From 33dd7011be064abf94e3c6e80887684796df4b40 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Fri, 24 May 2019 18:32:42 +0800 Subject: [PATCH 1/7] cmake: expand build components before generating config !4452 had config generation first before building the component list to be used in the build. This proved to be detrimental when a new target is added as config generation would consider configs from both targets. --- tools/cmake/build.cmake | 13 +++++++------ tools/cmake/kconfig.cmake | 17 ++++++++++------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/tools/cmake/build.cmake b/tools/cmake/build.cmake index 585d26e195..97c43e8a23 100644 --- a/tools/cmake/build.cmake +++ b/tools/cmake/build.cmake @@ -365,12 +365,6 @@ macro(idf_build_process target) # Check for required Python modules __build_check_python() - # Generate config values in different formats - idf_build_get_property(sdkconfig SDKCONFIG) - idf_build_get_property(sdkconfig_defaults SDKCONFIG_DEFAULTS) - __kconfig_generate_config("${sdkconfig}" "${sdkconfig_defaults}") - __build_import_configs() - # Write the partial build properties to a temporary file. # The path to this generated file is set to a short-lived build # property BUILD_PROPERTIES_FILE. @@ -416,6 +410,7 @@ macro(idf_build_process target) idf_build_unset_property(BUILD_PROPERTIES_FILE) file(REMOVE ${build_properties_file}) + # Finally, do component expansion. In this case it simply means getting a final list # of build component targets given the requirements set by each component. if(__COMPONENTS) @@ -442,6 +437,12 @@ macro(idf_build_process target) idf_build_set_property(___COMPONENT_REQUIRES_COMMON ${lib} APPEND) endforeach() + # Generate config values in different formats + idf_build_get_property(sdkconfig SDKCONFIG) + idf_build_get_property(sdkconfig_defaults SDKCONFIG_DEFAULTS) + __kconfig_generate_config("${sdkconfig}" "${sdkconfig_defaults}") + __build_import_configs() + # Temporary trick to support both gcc5 and gcc8 builds if(CMAKE_C_COMPILER_VERSION VERSION_EQUAL 5.2.0) set(GCC_NOT_5_2_0 0 CACHE STRING "GCC is 5.2.0 version") diff --git a/tools/cmake/kconfig.cmake b/tools/cmake/kconfig.cmake index 020e595509..28be99371e 100644 --- a/tools/cmake/kconfig.cmake +++ b/tools/cmake/kconfig.cmake @@ -88,14 +88,17 @@ endfunction() function(__kconfig_generate_config sdkconfig sdkconfig_defaults) # List all Kconfig and Kconfig.projbuild in known components idf_build_get_property(component_targets __COMPONENT_TARGETS) + idf_build_get_property(build_component_targets __BUILD_COMPONENT_TARGETS) foreach(component_target ${component_targets}) - __component_get_property(kconfig ${component_target} KCONFIG) - __component_get_property(kconfig_projbuild ${component_target} KCONFIG_PROJBUILD) - if(kconfig) - list(APPEND kconfigs ${kconfig}) - endif() - if(kconfig_projbuild) - list(APPEND kconfig_projbuilds ${kconfig_projbuild}) + if(component_target IN_LIST build_component_targets) + __component_get_property(kconfig ${component_target} KCONFIG) + __component_get_property(kconfig_projbuild ${component_target} KCONFIG_PROJBUILD) + if(kconfig) + list(APPEND kconfigs ${kconfig}) + endif() + if(kconfig_projbuild) + list(APPEND kconfig_projbuilds ${kconfig_projbuild}) + endif() endif() endforeach() From 297b2c5a3974b376bb17dc3785e8ffffb2701913 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Tue, 28 May 2019 21:43:03 +0800 Subject: [PATCH 2/7] cmake: evaluate component requirements in one go !4452 simplified early expansion by using an early expansion script that only does one thing: get the public and private requirements for each component, albeit one by one. This was also dependent on parsing the command output of the expansion script. This commit makes it so that a list of all components to be processed to passed to the expansion script, generating a cmake file that sets each component requirements in one go. This also makes sure that only components that registered themselves get included in the final build list. --- tools/cmake/build.cmake | 46 ++-------- tools/cmake/component.cmake | 58 ++++++------ .../scripts/component_get_requirements.cmake | 88 +++++++++++++++---- 3 files changed, 107 insertions(+), 85 deletions(-) diff --git a/tools/cmake/build.cmake b/tools/cmake/build.cmake index 97c43e8a23..6cf9a73b55 100644 --- a/tools/cmake/build.cmake +++ b/tools/cmake/build.cmake @@ -195,7 +195,8 @@ function(__build_expand_requirements component_target) # Since there are circular dependencies, make sure that we do not infinitely # expand requirements for each component. idf_build_get_property(component_targets_seen __COMPONENT_TARGETS_SEEN) - if(component_target IN_LIST component_targets_seen) + __component_get_property(component_registered ${component_target} __COMPONENT_REGISTERED) + if(component_target IN_LIST component_targets_seen OR NOT component_registered) return() endif() @@ -365,51 +366,13 @@ macro(idf_build_process target) # Check for required Python modules __build_check_python() - # Write the partial build properties to a temporary file. - # The path to this generated file is set to a short-lived build - # property BUILD_PROPERTIES_FILE. - idf_build_get_property(build_dir BUILD_DIR) - set(build_properties_file ${build_dir}/build_properties.temp.cmake) - idf_build_set_property(BUILD_PROPERTIES_FILE ${build_properties_file}) - __build_write_properties(${build_properties_file}) + idf_build_set_property(__COMPONENT_REQUIRES_COMMON ${target} APPEND) + __component_get_requirements() # Perform early expansion of component CMakeLists.txt in CMake scripting mode. # It is here we retrieve the public and private requirements of each component. # It is also here we add the common component requirements to each component's # own requirements. - idf_build_get_property(component_targets __COMPONENT_TARGETS) - idf_build_set_property(__COMPONENT_REQUIRES_COMMON ${target} APPEND) - idf_build_get_property(common_reqs __COMPONENT_REQUIRES_COMMON) - foreach(component_target ${component_targets}) - get_property(component_dir TARGET ${component_target} PROPERTY COMPONENT_DIR) - __component_get_requirements(error reqs priv_reqs ${component_dir}) - if(error) - message(FATAL_ERROR "${error}") - endif() - - list(APPEND reqs "${common_reqs}") - - # Remove duplicates and the component itself from its requirements - __component_get_property(alias ${component_target} COMPONENT_ALIAS) - __component_get_property(_name ${component_target} COMPONENT_NAME) - - # Prevent component from linking to itself. - if(reqs) - list(REMOVE_DUPLICATES reqs) - list(REMOVE_ITEM reqs ${alias} ${_name}) - endif() - - if(priv_reqs) - list(REMOVE_DUPLICATES priv_reqs) - list(REMOVE_ITEM priv_reqs ${alias} ${_name}) - endif() - - __component_set_property(${component_target} REQUIRES "${reqs}") - __component_set_property(${component_target} PRIV_REQUIRES "${priv_reqs}") - endforeach() - idf_build_unset_property(BUILD_PROPERTIES_FILE) - file(REMOVE ${build_properties_file}) - # Finally, do component expansion. In this case it simply means getting a final list # of build component targets given the requirements set by each component. @@ -431,6 +394,7 @@ macro(idf_build_process target) # Get a list of common component requirements in component targets form (previously # we just have a list of component names) + idf_build_get_property(common_reqs __COMPONENT_REQUIRES_COMMON) foreach(common_req ${common_reqs}) __component_get_target(component_target ${common_req}) __component_get_property(lib ${component_target} COMPONENT_LIB) diff --git a/tools/cmake/component.cmake b/tools/cmake/component.cmake index b3dd460c83..6caca93a74 100644 --- a/tools/cmake/component.cmake +++ b/tools/cmake/component.cmake @@ -125,6 +125,23 @@ function(__component_dir_quick_check var component_dir) set(${var} ${res} PARENT_SCOPE) endfunction() +# +# Write a CMake file containing all component and their properties. This is possible because each component +# keeps a list of all its properties. +# +function(__component_write_properties output_file) + idf_build_get_property(component_targets __COMPONENT_TARGETS) + foreach(component_target ${component_targets}) + __component_get_property(component_properties ${component_target} __COMPONENT_PROPERTIES) + foreach(property ${component_properties}) + __component_get_property(val ${component_target} ${property}) + set(component_properties_text + "${component_properties_text}\nset(__component_${component_target}_${property} ${val})") + endforeach() + file(WRITE ${output_file} "${component_properties_text}") + endforeach() +endfunction() + # # Add a component to process in the build. The components are keeped tracked of in property # __COMPONENT_TARGETS in component target form. @@ -184,44 +201,35 @@ endfunction() # Given a component directory, get the requirements by expanding it early. The expansion is performed # using a separate CMake script (the expansion is performed in a separate instance of CMake in scripting mode). # -function(__component_get_requirements error requires_var priv_requires_var component_dir) +function(__component_get_requirements) idf_build_get_property(idf_path IDF_PATH) - idf_build_get_property(build_properties_file BUILD_PROPERTIES_FILE) - idf_build_get_property(idf_target IDF_TARGET) - # This function assumes that the directory has been checked to contain a component, thus - # no check is performed here. + idf_build_get_property(build_dir BUILD_DIR) + set(build_properties_file ${build_dir}/build_properties.temp.cmake) + set(component_properties_file ${build_dir}/component_properties.temp.cmake) + set(component_requires_file ${build_dir}/component_requires.temp.cmake) + + __build_write_properties(${build_properties_file}) + __component_write_properties(${component_properties_file}) + execute_process(COMMAND "${CMAKE_COMMAND}" - -D "IDF_PATH=${idf_path}" - -D "IDF_TARGET=${idf_target}" - -D "COMPONENT_DIR=${component_dir}" -D "BUILD_PROPERTIES_FILE=${build_properties_file}" - -D "CMAKE_BUILD_EARLY_EXPANSION=1" + -D "COMPONENT_PROPERTIES_FILE=${component_properties_file}" + -D "COMPONENT_REQUIRES_FILE=${component_requires_file}" -P "${idf_path}/tools/cmake/scripts/component_get_requirements.cmake" RESULT_VARIABLE result ERROR_VARIABLE error ) if(NOT result EQUAL 0) - set(error "${error}" PARENT_SCOPE) - return() + message(FATAL_ERROR "${error}") endif() - string(REGEX REPLACE ";" "\\\\;" _output "${error}") - string(REGEX REPLACE "\n" ";" _output "${_output}") - list(REVERSE _output) + include(${component_requires_file}) - if(_output) - list(GET _output 1 _output) - - string(REGEX MATCH "\(.*\):::\(.*\)" _output "${_output}") - - string(REPLACE ":" ";" requires "${CMAKE_MATCH_1}") - string(REPLACE ":" ";" priv_requires "${CMAKE_MATCH_2}") - endif() - - set(${requires_var} ${requires} PARENT_SCOPE) - set(${priv_requires_var} ${priv_requires} PARENT_SCOPE) + file(REMOVE ${build_properties_file}) + file(REMOVE ${component_properties_file}) + file(REMOVE ${component_requires_file}) endfunction() # __component_add_sources, __component_check_target diff --git a/tools/cmake/scripts/component_get_requirements.cmake b/tools/cmake/scripts/component_get_requirements.cmake index 8223f709be..0b0d18727e 100644 --- a/tools/cmake/scripts/component_get_requirements.cmake +++ b/tools/cmake/scripts/component_get_requirements.cmake @@ -1,10 +1,5 @@ -include(${IDF_PATH}/tools/cmake/utilities.cmake) - include("${BUILD_PROPERTIES_FILE}") -include("${SDKCONFIG_CMAKE}") - -macro(require_idf_targets) -endmacro() +include("${COMPONENT_PROPERTIES_FILE}") function(idf_build_get_property var property) cmake_parse_arguments(_ "GENERATOR_EXPRESSION" "" "" ${ARGN}) @@ -12,17 +7,20 @@ function(idf_build_get_property var property) message(FATAL_ERROR "Getting build property generator expression not supported before idf_component_register().") endif() - set(${var} ${property} PARENT_SCOPE) + set(${var} ${${property}} PARENT_SCOPE) endfunction() -function(print_requires requires priv_requires) - spaces2list(requires) - spaces2list(priv_requires) - string(REPLACE ";" ":" requires "${requires}") - string(REPLACE ";" ":" priv_requires "${priv_requires}") - message("${requires}:::${priv_requires}") +idf_build_get_property(idf_path IDF_PATH) +include(${idf_path}/tools/cmake/utilities.cmake) + +function(__component_get_property var component_target property) + set(_property __component_${component_target}_${property}) + set(${var} ${${_property}} PARENT_SCOPE) endfunction() +macro(require_idf_targets) +endmacro() + macro(idf_component_register) set(options) set(single_value) @@ -30,14 +28,16 @@ macro(idf_component_register) INCLUDE_DIRS PRIV_INCLUDE_DIRS LDFRAGMENTS REQUIRES PRIV_REQUIRES REQUIRED_IDF_TARGETS EMBED_FILES EMBED_TXTFILES) cmake_parse_arguments(_ "${options}" "${single_value}" "${multi_value}" "${ARGN}") - print_requires("${__REQUIRES}" "${__PRIV_REQUIRES}") - set(__is_component 1) + set(__component_requires "${__REQUIRES}") + set(__component_priv_requires "${__PRIV_REQUIRES}") + set(__component_registered 1) return() endmacro() macro(register_component) - print_requires("${COMPONENT_REQUIRES}" "${COMPONENT_PRIV_REQUIRES}") - set(__is_component 1) + set(__component_requires "${COMPONENT_REQUIRES}") + set(__component_priv_requires "${COMPONENT_PRIV_REQUIRES}") + set(__component_registered 1) return() endmacro() @@ -45,5 +45,55 @@ macro(register_config_only_component) register_component() endmacro() -set(CMAKE_BUILD_EARLY_EXPANSION) -include(${COMPONENT_DIR}/CMakeLists.txt OPTIONAL) +idf_build_get_property(__common_reqs __COMPONENT_REQUIRES_COMMON) +idf_build_get_property(__component_targets __COMPONENT_TARGETS) + +function(__component_get_requirements) + # This is in a function (separate variable context) so that variables declared + # and set by the included CMakeLists.txt does not bleed into the next inclusion. + # We are only interested in the public and private requirements of components + __component_get_property(__component_dir ${__component_target} COMPONENT_DIR) + include(${__component_dir}/CMakeLists.txt OPTIONAL) + + spaces2list(__component_requires) + spaces2list(__component_priv_requires) + + set(__component_requires "${__component_requires}" PARENT_SCOPE) + set(__component_priv_requires "${__component_priv_requires}" PARENT_SCOPE) + set(__component_registered ${__component_registered} PARENT_SCOPE) +endfunction() + +set(CMAKE_BUILD_EARLY_EXPANSION 1) +foreach(__component_target ${__component_targets}) + set(__component_requires "") + set(__component_priv_requires "") + set(__component_registered 0) + + __component_get_requirements() + + list(APPEND __component_requires "${__common_reqs}") + + # Remove duplicates and the component itself from its requirements + __component_get_property(__component_alias ${__component_target} COMPONENT_ALIAS) + __component_get_property(__component_name ${__component_target} COMPONENT_NAME) + + # Prevent component from linking to itself. + if(__component_requires) + list(REMOVE_DUPLICATES __component_requires) + list(REMOVE_ITEM __component_requires ${__component_alias} ${__component_name}) + endif() + + if(__component_requires) + list(REMOVE_DUPLICATES __component_priv_requires) + list(REMOVE_ITEM __component_priv_requires ${__component_alias} ${__component_name}) + endif() + + set(__contents +"__component_set_property(${__component_target} REQUIRES \"${__component_requires}\") +__component_set_property(${__component_target} PRIV_REQUIRES \"${__component_priv_requires}\") +__component_set_property(${__component_target} __COMPONENT_REGISTERED ${__component_registered})" + ) + set(__component_requires_contents "${__component_requires_contents}\n${__contents}") +endforeach() + +file(WRITE ${COMPONENT_REQUIRES_FILE} "${__component_requires_contents}") \ No newline at end of file From 70dfcb35d44430256cb56c9c7ec21cfdcc8639c8 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Tue, 4 Jun 2019 20:19:25 +0800 Subject: [PATCH 3/7] mbedtls: component CMakeLists.txt corrections Since !4452 the common component requirements automatically get privately linked to libraries built under ESP-IDF build system (this includes targets from third-party libraries). This removes a variable that was used for that purpose before !4452. Since the internal target names were changed, the compile definition for warning on using deprecated functions is not being passed. Since using the internal name is unreliable, prefer passing this compile definition from the test itself. --- components/mbedtls/CMakeLists.txt | 9 +-------- components/mbedtls/test/CMakeLists.txt | 6 ++++++ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/components/mbedtls/CMakeLists.txt b/components/mbedtls/CMakeLists.txt index 3b1fd504e2..44af366f45 100644 --- a/components/mbedtls/CMakeLists.txt +++ b/components/mbedtls/CMakeLists.txt @@ -2,8 +2,6 @@ set(COMPONENT_ADD_INCLUDEDIRS "port/include" "mbedtls/include") set(COMPONENT_SRCS "mbedtls.c") set(COMPONENT_REQUIRES lwip) -set(MBEDTLS_PRIV_REQUIRES ${IDF_COMPONENT_REQUIRES_COMMON} soc) - register_component() # Only build mbedtls libraries @@ -96,9 +94,4 @@ foreach(target ${mbedtls_targets}) endforeach() # Link mbedtls libraries to component library -target_link_libraries(${COMPONENT_LIB} ${mbedtls_targets}) - -# Catch usage of deprecated mbedTLS functions when building tests -if(mbedtls_test IN_LIST BUILD_TEST_COMPONENTS) - add_definitions(-DMBEDTLS_DEPRECATED_WARNING) -endif() \ No newline at end of file +target_link_libraries(${COMPONENT_LIB} ${mbedtls_targets}) \ No newline at end of file diff --git a/components/mbedtls/test/CMakeLists.txt b/components/mbedtls/test/CMakeLists.txt index e1aad74fac..5a8cfd8d33 100644 --- a/components/mbedtls/test/CMakeLists.txt +++ b/components/mbedtls/test/CMakeLists.txt @@ -4,3 +4,9 @@ set(COMPONENT_ADD_INCLUDEDIRS ".") set(COMPONENT_REQUIRES unity test_utils mbedtls) register_component() + +idf_component_get_property(mbedtls mbedtls COMPONENT_LIB) +target_compile_definitions(${mbedtls} PUBLIC "-DMBEDTLS_DEPRECATED_WARNING") +target_compile_definitions(mbedtls PUBLIC "-DMBEDTLS_DEPRECATED_WARNING") +target_compile_definitions(mbedcrypto PUBLIC "-DMBEDTLS_DEPRECATED_WARNING") +target_compile_definitions(mbedx509 PUBLIC "-DMBEDTLS_DEPRECATED_WARNING") From f0f861ccd9912f93a43b51037655e4cb5bfb0127 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Fri, 31 May 2019 11:30:44 +0800 Subject: [PATCH 4/7] ldgen: use user input filename for processed template Previously ldgen determines the output file name on its own. This commit makes it so that user can dictate what the output file name will be for the processed template, if the user needs it for something else. --- components/esp32/CMakeLists.txt | 3 ++- tools/cmake/ldgen.cmake | 7 +------ tools/cmake/utilities.cmake | 5 +++-- tools/ldgen/ldgen.py | 10 ++++++++++ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 3710237896..0fca8aa0c0 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -58,7 +58,8 @@ else() # Process the template file through the linker script generation mechanism, and use the output for linking the # final binary - target_linker_script(${COMPONENT_LIB} "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in" PROCESS) + target_linker_script(${COMPONENT_LIB} "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in" + PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/esp32.project.ld") target_linker_script(${COMPONENT_LIB} "ld/esp32.peripherals.ld") target_link_libraries(${COMPONENT_LIB} gcc) diff --git a/tools/cmake/ldgen.cmake b/tools/cmake/ldgen.cmake index 9161ecd8f1..b8cfaad499 100644 --- a/tools/cmake/ldgen.cmake +++ b/tools/cmake/ldgen.cmake @@ -27,7 +27,7 @@ endfunction() # # Passes a linker script template to the linker script generation tool for # processing -function(__ldgen_process_template output_var template) +function(__ldgen_process_template template output) idf_build_get_property(idf_target IDF_TARGET) idf_build_get_property(idf_path IDF_PATH) @@ -36,11 +36,6 @@ function(__ldgen_process_template output_var template) file(GENERATE OUTPUT ${build_dir}/ldgen_libraries.in CONTENT $) file(GENERATE OUTPUT ${build_dir}/ldgen_libraries INPUT ${build_dir}/ldgen_libraries.in) - get_filename_component(filename "${template}" NAME) - - set(output ${CMAKE_CURRENT_BINARY_DIR}/${filename}.ld) - set(${output_var} ${output} PARENT_SCOPE) - set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${build_dir}/ldgen_libraries.in" diff --git a/tools/cmake/utilities.cmake b/tools/cmake/utilities.cmake index 4e64c16201..f5f7f9693c 100644 --- a/tools/cmake/utilities.cmake +++ b/tools/cmake/utilities.cmake @@ -131,13 +131,14 @@ endfunction() # and then adds -T with the filename only. This allows INCLUDE directives to be # used to include other linker scripts in the same directory. function(target_linker_script target scriptfiles) - cmake_parse_arguments(_ "PROCESS" "" "" ${ARGN}) + cmake_parse_arguments(_ "" "PROCESS" "" ${ARGN}) foreach(scriptfile ${scriptfiles}) get_filename_component(abs_script "${scriptfile}" ABSOLUTE) message(STATUS "Adding linker script ${abs_script}") if(__PROCESS) - __ldgen_process_template(output ${abs_script}) + get_filename_component(output "${__PROCESS}" ABSOLUTE) + __ldgen_process_template(${abs_script} ${output}) set(abs_script ${output}) endif() diff --git a/tools/ldgen/ldgen.py b/tools/ldgen/ldgen.py index 7829e4dfb8..dcc0db4e07 100755 --- a/tools/ldgen/ldgen.py +++ b/tools/ldgen/ldgen.py @@ -19,6 +19,8 @@ import argparse import sys import tempfile import subprocess +import os +import errno from fragments import FragmentFile from sdkconfig import SDKConfig @@ -111,6 +113,14 @@ def main(): with tempfile.TemporaryFile("w+") as output: script_model.write(output) output.seek(0) + + if not os.path.exists(os.path.dirname(output_path)): + try: + os.makedirs(os.path.dirname(output_path)) + except OSError as exc: + if exc.errno != errno.EEXIST: + raise + with open(output_path, "w") as f: # only create output file after generation has suceeded f.write(output.read()) except LdGenFailure as e: From 6365658d3fb481ed45bd143ce7c1cc54d4f7ec45 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Fri, 31 May 2019 15:27:11 +0800 Subject: [PATCH 5/7] cmake: revert using EXCLUDE_FROM_ALL when adding component subdirectories Reverting (for now) the change in !4452 to use EXCLUDE_FROM_ALL. Apparently this also affects custom targets with ALL option specified, not causing them to be built with the project. This is apparently a bug which has a merged fix: https://gitlab.kitware.com/cmake/cmake/merge_requests/2816 --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 141f903892..951c14ed36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,9 +74,9 @@ foreach(component_target ${build_component_targets}) idf_build_get_property(build_prefix __PREFIX) set(__idf_component_context 1) if(NOT prefix STREQUAL build_prefix) - add_subdirectory(${dir} ${prefix}_${_name} EXCLUDE_FROM_ALL) + add_subdirectory(${dir} ${prefix}_${_name}) else() - add_subdirectory(${dir} ${_name} EXCLUDE_FROM_ALL) + add_subdirectory(${dir} ${_name}) endif() set(__idf_component_context 0) endforeach() From 3882e48e8adf6cd1f5d9e42be732f2253ba99db0 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Tue, 4 Jun 2019 19:05:33 +0800 Subject: [PATCH 6/7] cmake: use new signature form of target_link_library to link components !4452 used setting LINK_LIBRARIES and INTERFACE_LINK_LIBRARIES to link components built under ESP-IDF build system. However, LINK_LIBRARIES does not produce behavior same as linking PRIVATE. This MR uses the new signature for target_link_libraries directly instead. This also moves setting dependencies during component registration rather than after all components have been processed. The consequence is that internally, components have to use the new signature form as well. This does not affect linking the components to external targets, such as with idf_as_lib example. This only affects linking additional libraries to ESP-IDF libraries outside component processing (after idf_build_process), which is not even possible for CMake") - target_link_libraries(${COMPONENT_LIB} extra) + target_link_libraries(${COMPONENT_LIB} PUBLIC extra) else() - target_link_libraries(${COMPONENT_LIB} ${LIBC} ${LIBM} gcc) + target_link_libraries(${COMPONENT_LIB} PUBLIC ${LIBC} ${LIBM} gcc) endif() set_source_files_properties(heap.c PROPERTIES COMPILE_FLAGS -fno-builtin) if(EXTRA_LINK_FLAGS) - target_link_libraries(${COMPONENT_LIB} "${EXTRA_LINK_FLAGS}") + target_link_libraries(${COMPONENT_LIB} INTERFACE "${EXTRA_LINK_FLAGS}") endif() diff --git a/components/ulp/project_include.cmake b/components/ulp/project_include.cmake index b5ac4c54e2..95996b32f0 100644 --- a/components/ulp/project_include.cmake +++ b/components/ulp/project_include.cmake @@ -61,7 +61,7 @@ function(ulp_embed_binary app_name s_sources exp_dep_srcs) add_dependencies(${COMPONENT_LIB} ${app_name}_artifacts) - target_linker_script(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}.ld) + target_linker_script(${COMPONENT_LIB} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}.ld) target_add_binary_data(${COMPONENT_LIB} ${CMAKE_CURRENT_BINARY_DIR}/${app_name}/${app_name}.bin BINARY) endif() endfunction() \ No newline at end of file diff --git a/components/vfs/CMakeLists.txt b/components/vfs/CMakeLists.txt index 1d8fb06ec0..0b2f640ca6 100644 --- a/components/vfs/CMakeLists.txt +++ b/components/vfs/CMakeLists.txt @@ -6,4 +6,4 @@ register_component() # Some newlib syscalls are implemented in vfs.c, make sure these are always # seen by the linker -target_link_libraries(${COMPONENT_LIB} "-u vfs_include_syscalls_impl") +target_link_libraries(${COMPONENT_LIB} INTERFACE "-u vfs_include_syscalls_impl") diff --git a/components/xtensa/CMakeLists.txt b/components/xtensa/CMakeLists.txt index 9044f14ae1..cb9c9ce49c 100644 --- a/components/xtensa/CMakeLists.txt +++ b/components/xtensa/CMakeLists.txt @@ -7,4 +7,4 @@ set(COMPONENT_PRIV_REQUIRES soc) register_component() -target_link_libraries(${COMPONENT_LIB} "${CMAKE_CURRENT_SOURCE_DIR}/${IDF_TARGET}/libhal.a") +target_link_libraries(${COMPONENT_LIB} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/${IDF_TARGET}/libhal.a") diff --git a/examples/build_system/cmake/import_lib/main/CMakeLists.txt b/examples/build_system/cmake/import_lib/main/CMakeLists.txt index 8111cbe6a3..fb136b8b97 100644 --- a/examples/build_system/cmake/import_lib/main/CMakeLists.txt +++ b/examples/build_system/cmake/import_lib/main/CMakeLists.txt @@ -23,4 +23,4 @@ endfunction() add_subdirectory(lib/tinyxml2) # Link tinyxml2 to main component -target_link_libraries(${COMPONENT_LIB} tinyxml2) +target_link_libraries(${COMPONENT_LIB} PUBLIC tinyxml2) diff --git a/tools/cmake/build.cmake b/tools/cmake/build.cmake index 6cf9a73b55..84f6f154fc 100644 --- a/tools/cmake/build.cmake +++ b/tools/cmake/build.cmake @@ -436,29 +436,8 @@ endmacro() # generating additional binary files, generating files related to flashing, etc.) function(idf_build_executable elf) # Propagate link dependencies from component library targets to the executable - idf_build_get_property(build_components BUILD_COMPONENTS) - foreach(build_component ${build_components}) - get_target_property(type ${build_component} TYPE) - if(type STREQUAL "INTERFACE_LIBRARY") - get_target_property(iface_link_depends ${build_component} INTERFACE_LINK_DEPENDS) - else() - get_target_property(link_depends ${build_component} LINK_DEPENDS) - get_target_property(iface_link_depends ${build_component} INTERFACE_LINK_DEPENDS) - endif() - if(iface_link_depends) - list(APPEND _link_depends ${iface_link_depends}) - endif() - if(link_depends) - list(APPEND _link_depends ${link_depends}) - endif() - endforeach() - - idf_build_get_property(link_depends LINK_DEPENDS) - if(link_depends) - list(APPEND _link_depends ${link_depends}) - endif() - - set_property(TARGET ${elf} APPEND PROPERTY LINK_DEPENDS "${_link_depends}") + idf_build_get_property(link_depends __LINK_DEPENDS) + set_property(TARGET ${elf} APPEND PROPERTY LINK_DEPENDS "${link_depends}") # Set the EXECUTABLE_NAME and EXECUTABLE properties since there are generator expression # from components that depend on it diff --git a/tools/cmake/component.cmake b/tools/cmake/component.cmake index 6caca93a74..22b3528ec6 100644 --- a/tools/cmake/component.cmake +++ b/tools/cmake/component.cmake @@ -288,6 +288,39 @@ macro(__component_check_target) endif() endmacro() +# __component_set_dependencies, __component_set_all_dependencies +# +# Links public and private requirements for the currently processed component +macro(__component_set_dependencies reqs type) + foreach(req ${reqs}) + if(req IN_LIST build_component_targets) + __component_get_property(req_lib ${req} COMPONENT_LIB) + target_link_libraries(${component_lib} ${type} ${req_lib}) + endif() + endforeach() +endmacro() + +macro(__component_set_all_dependencies) + __component_get_property(type ${component_target} COMPONENT_TYPE) + idf_build_get_property(build_component_targets __BUILD_COMPONENT_TARGETS) + + if(NOT type STREQUAL CONFIG_ONLY) + __component_get_property(reqs ${component_target} __REQUIRES) + __component_set_dependencies("${reqs}" PUBLIC) + + __component_get_property(priv_reqs ${component_target} __PRIV_REQUIRES) + __component_set_dependencies("${priv_reqs}" PRIVATE) + else() + __component_get_property(reqs ${component_target} __REQUIRES) + foreach(req ${reqs}) + if(req IN_LIST build_component_targets) + __component_get_property(req_lib ${req} COMPONENT_LIB) + target_link_libraries(${component_lib} INTERFACE ${req_lib}) + endif() + endforeach() + endif() +endmacro() + # idf_component_get_property # # @brief Retrieve the value of the specified component property @@ -331,6 +364,7 @@ function(idf_component_set_property component property val) endif() endfunction() + # idf_component_register # # @brief Register a component to the build, creating component library targets etc. @@ -431,6 +465,9 @@ function(idf_component_register) __ldgen_add_fragment_files("${__LDFRAGMENTS}") endif() + # Set dependencies + __component_set_all_dependencies() + # Add the component to built components idf_build_set_property(__BUILD_COMPONENTS ${component_lib} APPEND) idf_build_set_property(BUILD_COMPONENTS ${component_alias} APPEND) diff --git a/tools/cmake/ldgen.cmake b/tools/cmake/ldgen.cmake index b8cfaad499..27db72ae36 100644 --- a/tools/cmake/ldgen.cmake +++ b/tools/cmake/ldgen.cmake @@ -75,5 +75,5 @@ function(__ldgen_process_template template output) get_filename_component(_name ${output} NAME) add_custom_target(__ldgen_output_${_name} DEPENDS ${output}) add_dependencies(__idf_build_target __ldgen_output_${_name}) - idf_build_set_property(LINK_DEPENDS ${output} APPEND) + idf_build_set_property(__LINK_DEPENDS ${output} APPEND) endfunction() \ No newline at end of file diff --git a/tools/cmake/utilities.cmake b/tools/cmake/utilities.cmake index f5f7f9693c..83403d9ce9 100644 --- a/tools/cmake/utilities.cmake +++ b/tools/cmake/utilities.cmake @@ -130,7 +130,7 @@ endfunction() # Automatically adds a -L search path for the containing directory (if found), # and then adds -T with the filename only. This allows INCLUDE directives to be # used to include other linker scripts in the same directory. -function(target_linker_script target scriptfiles) +function(target_linker_script target deptype scriptfiles) cmake_parse_arguments(_ "" "PROCESS" "" ${ARGN}) foreach(scriptfile ${scriptfiles}) get_filename_component(abs_script "${scriptfile}" ABSOLUTE) @@ -145,12 +145,7 @@ function(target_linker_script target scriptfiles) get_filename_component(search_dir "${abs_script}" DIRECTORY) get_filename_component(scriptname "${abs_script}" NAME) - get_target_property(type ${target} TYPE) - if(type STREQUAL "INTERFACE_LIBRARY") - set(is_interface "INTERFACE") - endif() - - if(is_interface) + if(deptype STREQUAL INTERFACE OR deptype STREQUAL PUBLIC) get_target_property(link_libraries "${target}" INTERFACE_LINK_LIBRARIES) else() get_target_property(link_libraries "${target}" LINK_LIBRARIES) @@ -158,10 +153,10 @@ function(target_linker_script target scriptfiles) list(FIND "${link_libraries}" "-L ${search_dir}" found_search_dir) if(found_search_dir EQUAL "-1") # not already added as a search path - target_link_libraries("${target}" "${is_interface}" "-L ${search_dir}") + target_link_libraries("${target}" "${deptype}" "-L ${search_dir}") endif() - target_link_libraries("${target}" "${is_interface}" "-T ${scriptname}") + target_link_libraries("${target}" "${deptype}" "-T ${scriptname}") # Note: In ESP-IDF, most targets are libraries and libary LINK_DEPENDS don't propagate to # executable(s) the library is linked to. Attach manually to executable once it is known. @@ -169,11 +164,7 @@ function(target_linker_script target scriptfiles) # Property INTERFACE_LINK_DEPENDS is available in CMake 3.13 which should propagate link # dependencies. if(NOT __PROCESS) - if(is_interface) - set_property(TARGET ${target} APPEND PROPERTY INTERFACE_LINK_DEPENDS ${abs_script}) - else() - set_property(TARGET ${target} APPEND PROPERTY LINK_DEPENDS ${abs_script}) - endif() + idf_build_set_property(__LINK_DEPENDS ${abs_script} APPEND) endif() endforeach() endfunction() From 54ef60f26b15d92622c2e51bc4b5c9df96421e01 Mon Sep 17 00:00:00 2001 From: Renz Christian Bagaporo Date: Tue, 4 Jun 2019 20:32:43 +0800 Subject: [PATCH 7/7] component: revert some of the dependency corrections !4452 and !4897 made some ill-advised corrections to dependency info; revert those in this MR. Handling pre-built binaries as imported libraries is retained, however. --- components/bootloader_support/CMakeLists.txt | 8 ++++---- components/esp32/CMakeLists.txt | 4 ++-- components/esp_wifi/CMakeLists.txt | 3 +-- components/libsodium/CMakeLists.txt | 2 +- components/protocomm/CMakeLists.txt | 3 +-- components/spi_flash/CMakeLists.txt | 3 +-- 6 files changed, 10 insertions(+), 13 deletions(-) diff --git a/components/bootloader_support/CMakeLists.txt b/components/bootloader_support/CMakeLists.txt index d1373be307..2437829d54 100644 --- a/components/bootloader_support/CMakeLists.txt +++ b/components/bootloader_support/CMakeLists.txt @@ -9,8 +9,8 @@ set(COMPONENT_SRCS "src/bootloader_clock.c" if(BOOTLOADER_BUILD) set(COMPONENT_ADD_INCLUDEDIRS "include include_bootloader") - set(COMPONENT_REQUIRES spi_flash soc) #unfortunately the header directly uses SOC registers - set(COMPONENT_PRIV_REQUIRES micro-ecc efuse) + set(COMPONENT_REQUIRES soc) #unfortunately the header directly uses SOC registers + set(COMPONENT_PRIV_REQUIRES micro-ecc spi_flash efuse) list(APPEND COMPONENT_SRCS "src/bootloader_init.c" "src/${IDF_TARGET}/bootloader_sha.c" "src/${IDF_TARGET}/flash_encrypt.c" @@ -55,8 +55,8 @@ else() "src/idf/secure_boot_signatures.c") set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_PRIV_INCLUDEDIRS "include_bootloader") - set(COMPONENT_REQUIRES mbedtls soc) #unfortunately the header directly uses SOC registers - set(COMPONENT_PRIV_REQUIRES spi_flash efuse) + set(COMPONENT_REQUIRES soc) #unfortunately the header directly uses SOC registers + set(COMPONENT_PRIV_REQUIRES spi_flash mbedtls efuse) endif() register_component() \ No newline at end of file diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 89b344b25e..abcc0ada17 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -34,12 +34,12 @@ else() "task_wdt.c") set(COMPONENT_ADD_INCLUDEDIRS "include") - set(COMPONENT_REQUIRES app_update driver esp_event efuse pthread soc) #unfortunately rom/uart uses SOC registers directly + set(COMPONENT_REQUIRES driver esp_event efuse soc) #unfortunately rom/uart uses SOC registers directly # driver is a public requirement because esp_sleep.h uses gpio_num_t & touch_pad_t # app_update is added here because cpu_start.c uses esp_ota_get_app_description() function. set(COMPONENT_PRIV_REQUIRES - app_trace app_update bootloader_support log mbedtls nvs_flash + app_trace app_update bootloader_support log mbedtls nvs_flash pthread smartconfig_ack spi_flash vfs wpa_supplicant espcoredump esp_common esp_wifi) set(COMPONENT_ADD_LDFRAGMENTS linker.lf ld/esp32_fragments.lf) diff --git a/components/esp_wifi/CMakeLists.txt b/components/esp_wifi/CMakeLists.txt index 0041234312..c8f31cd53c 100644 --- a/components/esp_wifi/CMakeLists.txt +++ b/components/esp_wifi/CMakeLists.txt @@ -8,8 +8,7 @@ set(COMPONENT_SRCS "src/wifi_init.c") set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_PRIV_INCLUDEDIRS) -set(COMPONENT_REQUIRES wpa_supplicant smartconfig_ack) -set(COMPONENT_PRIV_REQUIRES "nvs_flash") +set(COMPONENT_PRIV_REQUIRES wpa_supplicant nvs_flash) if(NOT CONFIG_ESP32_NO_BLOBS) set(COMPONENT_ADD_LDFRAGMENTS "linker.lf") diff --git a/components/libsodium/CMakeLists.txt b/components/libsodium/CMakeLists.txt index f0d5afc9da..caef522233 100644 --- a/components/libsodium/CMakeLists.txt +++ b/components/libsodium/CMakeLists.txt @@ -126,7 +126,7 @@ endif() set(COMPONENT_ADD_INCLUDEDIRS ${SRC}/include port_include) set(COMPONENT_PRIV_INCLUDEDIRS ${SRC}/include/sodium port_include/sodium port) -set(COMPONENT_REQUIRES mbedtls vfs) +set(COMPONENT_REQUIRES mbedtls) register_component() target_compile_definitions(${COMPONENT_LIB} PRIVATE diff --git a/components/protocomm/CMakeLists.txt b/components/protocomm/CMakeLists.txt index 79e824ceb6..9f9343815f 100644 --- a/components/protocomm/CMakeLists.txt +++ b/components/protocomm/CMakeLists.txt @@ -12,8 +12,7 @@ set(COMPONENT_SRCS "src/common/protocomm.c" "src/transports/protocomm_console.c" "src/transports/protocomm_httpd.c") -set(COMPONENT_REQUIRES protobuf-c bt) -set(COMPONENT_PRIV_REQUIRES mbedtls console esp_http_server) +set(COMPONENT_PRIV_REQUIRES protobuf-c mbedtls console esp_http_server bt) if(CONFIG_BT_ENABLED) if(CONFIG_BT_BLUEDROID_ENABLED) diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index db8fceee0e..be290e7c32 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -9,8 +9,7 @@ else() "flash_ops.c" "partition.c" "spi_flash_rom_patch.c") - set(COMPONENT_REQUIRES app_update) - set(COMPONENT_PRIV_REQUIRES bootloader_support soc) + set(COMPONENT_PRIV_REQUIRES bootloader_support app_update soc) endif() set(COMPONENT_ADD_INCLUDEDIRS include)