On some Windows systems, antivirus, endpoint-security or DLP/encryption software intercepts short-lived toolchain processes and strips their stdout when the build captures it through a pipe, while the same command prints its output normally when run by hand. The tool exits successfully but returns nothing, and each build step that reads toolchain output then failed with a different, cryptic error far from the real cause: - CMake configuration aborted with "Unknown arguments specified" in components/xtensa/project_include.cmake, or "check_expected_tool_version invoked with incorrect arguments" in components/esp_common. - ldgen turned the empty objdump output into an opaque pyparsing "Expected 'In archive'" traceback. - idf_tools.py silently reported the compiler/debugger version as "unknown", sending users into a fruitless reinstall loop. Detect the empty result at each consumer and fail (or warn) with an actionable message that names the likely cause and the remedy: - tools/cmake/compiler_query.cmake: new __compiler_query() helper runs a compiler query and fails with a clear error on empty or failed output. It is a standalone module included by both the cmakev1 and cmakev2 utilities, since the esp_common and xtensa project_include.cmake that call it are shared by both build systems. The xtensa if() arguments are now quoted so an empty result no longer collapses into a parse error. - tools/ldgen/ldgen.py: _run_objdump() rejects empty objdump output, and non-empty-but-unparsable section info is caught and re-raised as a clear LdGenFailure instead of a raw pyparsing traceback. - tools/idf_tools.py: empty version output now warns with the cause and returns UNKNOWN_VERSION instead of silently reporting "unknown". Closes https://github.com/espressif/esp-idf/issues/18727 Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Linker Script Generator
Contains code that implements linker script generation, ldgen. For more information about the feature,
see docs/en/api-guides/linker-script-generation.rst.
Source Files
The following are the source files in the directory:
ldgen.py- Python executable that gets called during build.entity.py- contains classes related to entities (library, object, symbol or combination of the above) with mappable input sections.fragments.py- contains classes for parsing the different types of fragments in linker fragment files.generation.py- contains bulk of the logic used to process fragments into output commands.sdkconfig.py- used for evaluating conditionals in fragment files.linker_script.py- augments the input linker script template with output commands from generation process to produce the output linker script.output_commands.py- contains classes that represent the output commands in the output linker script.ldgen_common.py- contains miscellaneous utilities/definitions that can be used in the files mentioned above.
Tests
Unit tests are in the test directory. These tests are run as part of CI in the job test_ldgen_on_host.
There is also a test app for ldgen in tools/test_apps/build_system/ldgen_test.
Build System
Linker script generation is a part of the build process. The build scripts tools/cmake/ldgen.cmake
and make/ldgen.mk contain the build-system-side implementation for CMake and Make, respectively.
Basic Flow
The build system invokes ldgen.py, passing some information from the build.
The linker fragment files are parsed by fragments.py, evaluating conditional expressions
with sdkconfig.py.
From the parsed fragments, generation.py generates output commands defined in output_commands.py,
with some help from entity.py.
linker_script.py writes the output linker script, replacing markers with output commands generated.
More details about the implementation are in the respective source files.