BaseTools/Trim.py: Strip "#pragma once" from inlined ASL content#12667
Open
makubacki wants to merge 1 commit into
Open
BaseTools/Trim.py: Strip "#pragma once" from inlined ASL content#12667makubacki wants to merge 1 commit into
makubacki wants to merge 1 commit into
Conversation
When Trim processes an ASL file (`--asl-file`), it textually inlines
the body of every `Include()`'d file directly into the constructed
preprocessor input, once per include site.
Its has duplicate protection in the form of a circular-include stack
(`gIncludedAslFile`), that prevents A->B->A cycles. But, as far as
the script is concerned, each `Include()` is a unique include site.
Various combinations of includes and file types are possible and
handled slightly differently.
Starting with file types as defined in
BaseTools\Conf\build_rule.template:
- `.aslc`, `.act` files fall under `Acpi-Table-Code-File` and are
compiled, linked, and processed by genfw.
- `.asl`, `.Asl`, and `.ASL` files fall in `Acpi-Source-Language-File`
and are processed by Trim:
1. `Trim --asl-file` to produce a single combined .i file with
includes inlined.
2. `ASLPP` (ASL preprocessor, a C preprocessor) on the output of
Trim to produce a .iii file with all macros expanded and
conditional branches resolved. AutoGen.h is also included and
processed here to resolve fixed PCD values if needed.
3. `Trim --source-code` which takes the pre-processed .iii file and
produces a .iiii file with content like linemarkers cleaned up.
4. The ACPI compiler compiles the .iiii file to produce AML bytecode
in a .aml file.
Because the `.aslc`/`.act` files are directly passed to normal C
processing tools, they are not part of the Trim change made in this
commit and the remainder of this message focuses on the ACPI Source
Language File case.
ASL files can use either an ASL `Include()` directive or a C-style
`#include` directive. In addition, different file types may be
included such as a `.asl` file or a `.h` file.
`Trim` handles these cases differently:
- For ASL `Include()` directives, `Trim` inlines the content of the
included file directly into the output at the include site. This is
done for all included ASL files regardless of their extension. The
inlining is purely textual and does not attempt to resolve or
preserve any preprocessor directives such as `#pragma once` or
include guards.
- For C-style `#include` directives, `Trim` checks the file extension
of the included file. If the file is an ASL file (`.asl` or `.asi`),
`Trim` treats the file the same as the `Include()` case. Otherwise,
`Trim` passes the directive through verbatim to the output, allowing
the downstream C preprocessor (`ASLPP`) to handle it according to
normal C preprocessor rules.
This creates a situtation in which the resulting `.i` might include:
- Inlined file content (from a `.asl` or `.h` file) depending on the
include type and file extension.
- Verbatim `#include` directives for non-ASL files which will be
processed by the C preprocessor.
Focusing on the "inlined" case, historically `.h` files would have
traditional C include guards (`#ifndef`/`#define`, `#endif`). However,
files might also include `#pragma once` as a guard.
In that case, the inlined content of the `.i` file could contain
multiple `#pragma once` directives, one per include site. When the
C preprocessor (`ASLPP`) processes the `.i` file, it sees multiple
`#pragma once` directives in what it considers the main file, and
could emit a warning like the following from gcc:
warning: '#pragma once' in main file [-Wpragma-once-outside-header]
The remainder of this commit message describes the change made to
address this warning.
This change strips "#pragma once" lines on the ASL content path in
`DoInclude()` in `Trim.py` so the directive is removed before it
reaches the C preprocessor.
- "#include" directives for non-ASL files are still passed through
verbatim for the C preprocessor to resolve where the contents of
those .h files might contain "#pragma once" or traditional guards.
- Traditional include guards are untouched and continue to behave as
before where multiple include sites might inline the same content
in the .i file before reaching the C preprocessor.
The change:
In the case that a file is inlined with a `#pragma once` directive,
the directive is stripped from the inlined content which prevents the
warning.
This is considered acceptable because it only removes the
`#pragma once` directive from the inlined content for these specific
cases. So, the `.i` file might contain multiple inlined copies of the
same header content (like always in this inline case) but without the
`#pragma once` directives. Because actual C content was already not
processed or trimmed out (e.g. `typedef struct`) duplicate content is
not considered to be a problem (`#define` multiple times is not a
problem for the C preprocessor).
Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
AshrafAliS
approved these changes
Jun 12, 2026
apop5
approved these changes
Jun 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Note: I've made this description verbose because (1) I'm not sure everyone is familiar with the details and nuances of this flow and (2) I tried to balance a simple solution versus practical concerns and I want that to be obvious for feedback on the approach. TLDR is this addresses a potential warning in some C preprocessors if
#pragma onceis used in header files included in certain ways in ASL source files.When
Trimprocesses an ASL file (--asl-file), it textually inlines the body of everyInclude()'d file directly into the constructed preprocessor input, once per include site.Its has duplicate protection in the form of a circular-include stack (
gIncludedAslFile), that prevents A->B->A cycles. But, as far as the script is concerned, eachInclude()is a unique include site.Various combinations of includes and file types are possible and handled slightly differently.
Starting with file types as defined in BaseTools\Conf\build_rule.template:
.aslc,.actfiles fall underAcpi-Table-Code-Fileand are compiled, linked, and processed bygenfw..asl,.Asl, and.ASLfiles fall inAcpi-Source-Language-Fileand are processed byTrim:Trim --asl-fileto produce a single combined .i file with includes inlined.ASLPP(ASL preprocessor, a C preprocessor) on the output ofTrimto produce a .iii file with all macros expanded and conditional branches resolved. AutoGen.h is also included and processed here to resolve fixed PCD values if needed.Trim --source-codewhich takes the pre-processed .iii file and produces a .iiii file with content like linemarkers cleaned up.Because the
.aslc/.actfiles are directly passed to normal C processing tools, they are not part of theTrimchange made in this commit and the remainder of this message focuses on the ACPI Source Language File case.ASL files can use either an ASL
Include()directive or a C-style#includedirective. In addition, different file types may be included such as a.aslfile or a.hfile.Trimhandles these cases differently:Include()directives,Triminlines the content of the included file directly into the output at the include site. This is done for all included ASL files regardless of their extension. The inlining is purely textual and does not attempt to resolve or preserve any preprocessor directives such as#pragma onceor include guards.#includedirectives,Trimchecks the file extension of the included file. If the file is an ASL file (.aslor.asi),Trimtreats the file the same as theInclude()case. Otherwise,Trimpasses the directive through verbatim to the output, allowing the downstream C preprocessor (ASLPP) to handle it according to normal C preprocessor rules.This creates a situtation in which the resulting
.imight include:.aslor.hfile) depending on the include type and file extension.#includedirectives for non-ASL files which will be processed by the C preprocessor.Focusing on the "inlined" case, historically
.hfiles would have traditional C include guards (#ifndef/#define,#endif). However, files might also include#pragma onceas a guard.In that case, the inlined content of the
.ifile could contain multiple#pragma oncedirectives, one per include site. When the C preprocessor (ASLPP) processes the.ifile, it sees multiple#pragma oncedirectives in what it considers the main file, and could emit a warning like the following from gcc:The remainder of this commit message describes the change made to address this warning.
This change strips "#pragma once" lines on the ASL content path in
DoInclude()inTrim.pyso the directive is removed before it reaches the C preprocessor.The change:
In the case that a file is inlined with a
#pragma oncedirective, the directive is stripped from the inlined content which prevents the warning.This is considered acceptable because it only removes the
#pragma oncedirective from the inlined content for these specific cases. So, the.ifile might contain multiple inlined copies of the same header content (like always in this inline case) but without the#pragma oncedirectives. Because actual C content was already not processed or trimmed out (e.g.typedef struct) duplicate content that could cause multiple symbol definitions is not considered to be a problem (#definemultiple times is not a problem for the C preprocessor).How This Was Tested
.i,.iiifiles, etc.) of Trim.py and C preprocessor output with gcc and MSVC linkers.#pragma oncein .h files.Integration Instructions