diff --git a/CMakeLists.txt b/CMakeLists.txt index 90e0d4f40b1953..814b5784eda948 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,31 +45,37 @@ assert(toolchain_is_ok "The toolchain is unable to build a dummy C file. See CMa # is the last station. See "logical_target_for_zephyr_elf" below for # details. set(CMAKE_EXECUTABLE_SUFFIX .elf) -set(ZEPHYR_PREBUILT_EXECUTABLE zephyr_prebuilt) -set(ZEPHYR_FINAL_EXECUTABLE zephyr_final) +set(ZEPHYR_PREBUILT_EXECUTABLE ${IMAGE}zephyr_prebuilt) +set(ZEPHYR_FINAL_EXECUTABLE ${IMAGE}zephyr_final) # Set some phony targets to collect dependencies -set(OFFSETS_H_TARGET offsets_h) -set(SYSCALL_MACROS_H_TARGET syscall_macros_h_target) -set(SYSCALL_LIST_H_TARGET syscall_list_h_target) -set(DRIVER_VALIDATION_H_TARGET driver_validation_h_target) -set(KOBJ_TYPES_H_TARGET kobj_types_h_target) -set(LINKER_SCRIPT_TARGET linker_script_target) + +set(OFFSETS_H_TARGET ${IMAGE}offsets_h) +set(SYSCALL_MACROS_H_TARGET ${IMAGE}syscall_macros_h_target) +set(SYSCALL_LIST_H_TARGET ${IMAGE}syscall_list_h_target) +set(DRIVER_VALIDATION_H_TARGET ${IMAGE}driver_validation_h_target) +set(KOBJ_TYPES_H_TARGET ${IMAGE}kobj_types_h_target) +set(LINKER_SCRIPT_TARGET ${IMAGE}linker_script_target) + +set(OFFSETS_LIB ${IMAGE}offsets) +set(KERNEL_LIBRARY ${IMAGE}kernel) + +set(PRIV_STACKS_PREBUILT ${IMAGE}priv_stacks_prebuilt) define_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT BRIEF_DOCS " " FULL_DOCS " ") set_property( GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-little${ARCH}) # BFD format -# "zephyr_interface" is a source-less library that encapsulates all the global +# ${IMAGE}zephyr_interface is a source-less library that encapsulates all the global # compiler options needed by all source files. All zephyr libraries, # including the library named "zephyr" link with this library to # obtain these flags. # https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#interface-libraries -add_library(zephyr_interface INTERFACE) +add_library(${IMAGE}zephyr_interface INTERFACE) # "zephyr" is a catch-all CMake library for source files that can be # built purely with the include paths, defines, and other compiler -# flags that come with zephyr_interface. +# flags that come with ${IMAGE}zephyr_interface. zephyr_library_named(zephyr) zephyr_include_directories( @@ -343,11 +349,14 @@ endif() # Declare MPU userspace dependencies before the linker scripts to make # sure the order of dependencies are met +unset(APP_SMEM_ALIGNED_DEP) +unset(APP_SMEM_UNALIGNED_DEP) +unset(PRIV_STACK_DEP) if(CONFIG_USERSPACE) - set(APP_SMEM_ALIGNED_DEP app_smem_aligned_linker) - set(APP_SMEM_UNALIGNED_DEP app_smem_unaligned_linker) + set(APP_SMEM_ALIGNED_DEP ${IMAGE}app_smem_aligned_linker) + set(APP_SMEM_UNALIGNED_DEP ${IMAGE}app_smem_unaligned_linker) if(CONFIG_ARM) - set(PRIV_STACK_DEP priv_stacks_prebuilt) + set(PRIV_STACK_DEP ${PRIV_STACKS_PREBUILT}) endif() endif() @@ -399,15 +408,15 @@ foreach(path endif() endforeach() -set_ifndef( DTS_BOARD_FIXUP_FILE ${BOARD_DIR}/dts_fixup.h) -set_ifndef( DTS_SOC_FIXUP_FILE ${SOC_DIR}/${ARCH}/${SOC_PATH}/dts_fixup.h) -set( DTS_APP_FIXUP_FILE ${APPLICATION_SOURCE_DIR}/dts_fixup.h) +set_ifndef(${IMAGE}DTS_BOARD_FIXUP_FILE ${BOARD_DIR}/dts_fixup.h) +set_ifndef(${IMAGE}DTS_SOC_FIXUP_FILE ${SOC_DIR}/${ARCH}/${SOC_PATH}/dts_fixup.h) +set( DTS_APP_FIXUP_FILE ${APPLICATION_SOURCE_DIR}/dts_fixup.h) -set_ifndef(DTS_CAT_OF_FIXUP_FILES ${ZEPHYR_BINARY_DIR}/include/generated/generated_dts_board_fixups.h) +set_ifndef(${IMAGE}DTS_CAT_OF_FIXUP_FILES ${ZEPHYR_BINARY_DIR}/include/generated/generated_dts_board_fixups.h) # Concatenate the fixups into a single header file for easy # #include'ing -file(WRITE ${DTS_CAT_OF_FIXUP_FILES} "/* May only be included by generated_dts_board.h */\n\n") +file(WRITE ${${IMAGE}DTS_CAT_OF_FIXUP_FILES} "/* May only be included by generated_dts_board.h */\n\n") foreach(fixup_file ${DTS_BOARD_FIXUP_FILE} ${DTS_SOC_FIXUP_FILE} @@ -416,7 +425,7 @@ foreach(fixup_file ) if(EXISTS ${fixup_file}) file(READ ${fixup_file} contents) - file(APPEND ${DTS_CAT_OF_FIXUP_FILES} "${contents}") + file(APPEND ${${IMAGE}DTS_CAT_OF_FIXUP_FILES} "${contents}") endif() endforeach() @@ -426,12 +435,12 @@ endforeach() # build are not exported to external build systems #5605"; when we # integrate with an external build system we read out all compiler # flags when the external project is created. So an external project -# defined in subsys or ext will not get global flags added by drivers/ +# defined in subsys or ext will not get image-global flags added by drivers/ # or tests/ as the subdirectories are ordered now. # # Another example of when the order matters is the reading and writing -# of global properties such as ZEPHYR_LIBS or -# GENERATED_KERNEL_OBJECT_FILES. +# of global properties such as ${IMAGE}ZEPHYR_LIBS or +# ${IMAGE}GENERATED_KERNEL_OBJECT_FILES. # # Arch is placed early because it defines important compiler flags # that must be exported to external build systems defined in @@ -471,7 +480,7 @@ if(EXISTS ${CMAKE_BINARY_DIR}/zephyr_modules.txt) # the main binary dir instead. # https://cmake.org/pipermail/cmake/2019-June/069547.html set(ZEPHYR_CURRENT_MODULE_DIR ${module_path}) - add_subdirectory(${module_path} ${CMAKE_BINARY_DIR}/modules/${module_name}) + add_subdirectory(${module_path} ${CMAKE_CURRENT_BINARY_DIR}/modules/${module_name}) endforeach() # Done processing modules, clear ZEPHYR_CURRENT_MODULE_DIR. set(ZEPHYR_CURRENT_MODULE_DIR) @@ -624,17 +633,14 @@ gen_kobj(KOBJ_INCLUDE_PATH) # Generate offsets.c.obj from offsets.c # Generate offsets.h from offsets.c.obj -set(OFFSETS_LIB offsets) - set(OFFSETS_C_PATH ${ARCH_DIR}/${ARCH}/core/offsets/offsets.c) set(OFFSETS_H_PATH ${PROJECT_BINARY_DIR}/include/generated/offsets.h) - add_library( ${OFFSETS_LIB} OBJECT ${OFFSETS_C_PATH}) target_include_directories(${OFFSETS_LIB} PRIVATE kernel/include ${ARCH_DIR}/${ARCH}/include ) -target_link_libraries(${OFFSETS_LIB} zephyr_interface) +target_link_libraries(${OFFSETS_LIB} ${IMAGE}zephyr_interface) add_dependencies( ${OFFSETS_LIB} ${SYSCALL_LIST_H_TARGET} ${SYSCALL_MACROS_H_TARGET} @@ -660,17 +666,18 @@ zephyr_get_include_directories_for_lang(C ZEPHYR_INCLUDES) add_subdirectory(kernel) # Read list content -get_property(ZEPHYR_LIBS_PROPERTY GLOBAL PROPERTY ZEPHYR_LIBS) +get_property(ZEPHYR_LIBS_PROPERTY GLOBAL PROPERTY ${IMAGE}ZEPHYR_LIBS) foreach(zephyr_lib ${ZEPHYR_LIBS_PROPERTY}) - # TODO: Could this become an INTERFACE property of zephyr_interface? + # TODO: Could this become an INTERFACE property of ${IMAGE}zephyr_interface? add_dependencies(${zephyr_lib} ${OFFSETS_H_TARGET}) endforeach() get_property(OUTPUT_FORMAT GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT) +unset(CODE_RELOCATION_DEP) if (CONFIG_CODE_DATA_RELOCATION) - set(CODE_RELOCATION_DEP code_relocation_source_lib) + set(CODE_RELOCATION_DEP ${IMAGE}code_relocation_source_lib) endif() # CONFIG_CODE_DATA_RELOCATION configure_linker_script( @@ -734,7 +741,7 @@ if(CONFIG_GEN_ISR_TABLES) ${GEN_ISR_TABLE_EXTRA_ARG} DEPENDS ${ZEPHYR_PREBUILT_EXECUTABLE} ) - set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_SOURCE_FILES isr_tables.c) + set_property(GLOBAL APPEND PROPERTY ${IMAGE}GENERATED_KERNEL_SOURCE_FILES isr_tables.c) endif() if(CONFIG_CODE_DATA_RELOCATION) @@ -771,6 +778,14 @@ if(CONFIG_ARM AND CONFIG_USERSPACE) set(PRIV_STACKS_OUTPUT_OBJ priv_stacks_hash.c.obj) set(PRIV_STACKS_OUTPUT_OBJ_RENAMED priv_stacks_hash_renamed.o) + set(PRIV_STACKS_T ${IMAGE}priv_stacks) + set(PRIV_STACKS_OUTPUT_SRC_PRE_T ${IMAGE}priv_stacks_output_src_pre) + set(PRIV_STACKS_OUTPUT_SRC_T ${IMAGE}priv_stacks_output_src) + set(PRIV_STACKS_OUTPUT_LIB ${IMAGE}priv_stacks_output_lib) + set(PRIV_STACKS_OUTPUT_LIB_INTERFACE ${IMAGE}priv_stacks_output_lib_interface) + set(PRIV_STACKS_OUTPUT_OBJ_RENAMED_T ${IMAGE}priv_stacks_output_obj_renamed) + set(PRIV_STACKS_OUTPUT_OBJ_RENAMED_LIB ${IMAGE}priv_stacks_output_obj_renamed_lib) + # Essentially what we are doing here is extracting some information # out of the nearly finished elf file, generating the source code # for a hash table based on that information, and then compiling and @@ -785,13 +800,13 @@ if(CONFIG_ARM AND CONFIG_USERSPACE) COMMAND ${PYTHON_EXECUTABLE} ${GEN_PRIV_STACKS} - --kernel $ + --kernel $ --output ${PRIV_STACKS} $<$:--verbose> - DEPENDS priv_stacks_prebuilt + DEPENDS ${PRIV_STACKS_PREBUILT} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - add_custom_target(priv_stacks DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS}) + add_custom_target(${PRIV_STACKS_T} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS}) # Use gperf to generate C code (PRIV_STACKS_OUTPUT_SRC_PRE) which implements a # perfect hashtable based on PRIV_STACKS @@ -801,10 +816,11 @@ if(CONFIG_ARM AND CONFIG_USERSPACE) ${GPERF} -C --output-file ${PRIV_STACKS_OUTPUT_SRC_PRE} ${PRIV_STACKS} - DEPENDS priv_stacks ${PRIV_STACKS} + DEPENDS ${PRIV_STACKS_T} ${PRIV_STACKS} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - add_custom_target(priv_stacks_output_src_pre DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_SRC_PRE}) + add_custom_target(${PRIV_STACKS_OUTPUT_SRC_PRE_T} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_SRC_PRE}) # For our purposes the code/data generated by gperf is not optimal. # @@ -820,10 +836,11 @@ if(CONFIG_ARM AND CONFIG_USERSPACE) -o ${PRIV_STACKS_OUTPUT_SRC} -p "struct _k_priv_stack_map" $<$:--verbose> - DEPENDS priv_stacks_output_src_pre ${PRIV_STACKS_OUTPUT_SRC_PRE} + DEPENDS ${PRIV_STACKS_OUTPUT_SRC_PRE_T} ${PRIV_STACKS_OUTPUT_SRC_PRE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - add_custom_target(priv_stacks_output_src DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_SRC}) + add_custom_target(${PRIV_STACKS_OUTPUT_SRC_T} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_SRC}) set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_SRC} PROPERTIES COMPILE_DEFINITIONS "${compile_definitions_interface}") @@ -835,25 +852,29 @@ if(CONFIG_ARM AND CONFIG_USERSPACE) # We need precise control of where generated text/data ends up in the final # kernel image. Disable function/data sections and use objcopy to move # generated data into special section names - add_library(priv_stacks_output_lib STATIC + add_library(${PRIV_STACKS_OUTPUT_LIB} STATIC ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_SRC} ) # Turn off -ffunction-sections, etc. - # NB: Using a library instead of target_compile_options(priv_stacks_output_lib + # NB: Using a library instead of + # target_compile_options(${PRIV_STACKS_OUTPUT_LIB} # [...]) because a library's options have precedence - add_library(priv_stacks_output_lib_interface INTERFACE) + add_library(${PRIV_STACKS_OUTPUT_LIB_INTERFACE} INTERFACE) foreach(incl ${include_dir_in_interface}) - target_include_directories(priv_stacks_output_lib_interface INTERFACE ${incl}) + target_include_directories(${PRIV_STACKS_OUTPUT_LIB_INTERFACE} INTERFACE ${incl}) endforeach() foreach(incl ${sys_include_dir_in_interface}) target_include_directories(priv_stacks_output_lib_interface SYSTEM INTERFACE ${incl}) endforeach() - target_link_libraries(priv_stacks_output_lib priv_stacks_output_lib_interface) + target_link_libraries(${PRIV_STACKS_OUTPUT_LIB} + ${PRIV_STACKS_OUTPUT_LIB_INTERFACE}) - set(PRIV_STACKS_OUTPUT_OBJ_PATH ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/priv_stacks_output_lib.dir/${PRIV_STACKS_OUTPUT_OBJ}) + + set(PRIV_STACKS_OUTPUT_OBJ_PATH + ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${PRIV_STACKS_OUTPUT_LIB}.dir/${PRIV_STACKS_OUTPUT_OBJ}) set(obj_copy_cmd "") set(obj_copy_sections_rename @@ -871,23 +892,25 @@ if(CONFIG_ARM AND CONFIG_USERSPACE) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_OBJ_RENAMED} ${obj_copy_cmd} - DEPENDS priv_stacks_output_lib + DEPENDS ${PRIV_STACKS_OUTPUT_LIB} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - add_custom_target(priv_stacks_output_obj_renamed DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_OBJ_RENAMED}) + add_custom_target(${PRIV_STACKS_OUTPUT_OBJ_RENAMED_T} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_OBJ_RENAMED}) - add_library(priv_stacks_output_obj_renamed_lib STATIC IMPORTED GLOBAL) + add_library(${PRIV_STACKS_OUTPUT_OBJ_RENAMED_LIB} STATIC IMPORTED GLOBAL) set_property( - TARGET priv_stacks_output_obj_renamed_lib + TARGET ${PRIV_STACKS_OUTPUT_OBJ_RENAMED_LIB} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${PRIV_STACKS_OUTPUT_OBJ_RENAMED} ) add_dependencies( - priv_stacks_output_obj_renamed_lib - priv_stacks_output_obj_renamed + ${PRIV_STACKS_OUTPUT_OBJ_RENAMED_LIB} + ${PRIV_STACKS_OUTPUT_OBJ_RENAMED_T} ) - set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_OBJECT_FILES priv_stacks_output_obj_renamed_lib) + set_property(GLOBAL APPEND PROPERTY ${IMAGE}GENERATED_KERNEL_OBJECT_FILES + ${PRIV_STACKS_OUTPUT_OBJ_RENAMED_LIB}) endif() # Warning: most of this gperf code is duplicated above for @@ -902,6 +925,13 @@ if(CONFIG_USERSPACE) set(OUTPUT_OBJ kobject_hash.c.obj) set(OUTPUT_OBJ_RENAMED kobject_hash_renamed.o) + set(OUTPUT_SRC_PRE_T ${IMAGE}output_src_pre) + set(OBJ_LIST_T ${IMAGE}obj_list) + set(OUTPUT_SRC_T ${IMAGE}output_src) + set(OUTPUT_LIB ${IMAGE}output_lib) + set(OUTPUT_LIB_INTERFACE ${IMAGE}output_lib_interface) + set(OUTPUT_OBJ_RENAMED_T ${IMAGE}output_obj_renamed) + set(OUTPUT_OBJ_RENAMED_LIB ${IMAGE}output_obj_renamed_lib) # Essentially what we are doing here is extracting some information # out of the nearly finished elf file, generating the source code # for a hash table based on that information, and then compiling and @@ -922,7 +952,7 @@ if(CONFIG_USERSPACE) DEPENDS ${ZEPHYR_PREBUILT_EXECUTABLE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - add_custom_target(obj_list DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${OBJ_LIST}) + add_custom_target(${OBJ_LIST_T} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${OBJ_LIST}) # Use gperf to generate C code (OUTPUT_SRC_PRE) which implements a # perfect hashtable based on OBJ_LIST @@ -932,10 +962,10 @@ if(CONFIG_USERSPACE) ${GPERF} --output-file ${OUTPUT_SRC_PRE} ${OBJ_LIST} - DEPENDS obj_list ${OBJ_LIST} + DEPENDS ${OBJ_LIST_T} ${OBJ_LIST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - add_custom_target(output_src_pre DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SRC_PRE}) + add_custom_target(${OUTPUT_SRC_PRE_T} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SRC_PRE}) # For our purposes the code/data generated by gperf is not optimal. # @@ -951,15 +981,15 @@ if(CONFIG_USERSPACE) -o ${OUTPUT_SRC} -p "struct _k_object" $<$:--verbose> - DEPENDS output_src_pre ${OUTPUT_SRC_PRE} + DEPENDS ${OUTPUT_SRC_PRE_T} ${OUTPUT_SRC_PRE} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - add_custom_target(output_src DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SRC}) + add_custom_target(${OUTPUT_SRC_T} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SRC}) # We need precise control of where generated text/data ends up in the final # kernel image. Disable function/data sections and use objcopy to move # generated data into special section names - add_library(output_lib STATIC + add_library(${OUTPUT_LIB} STATIC ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_SRC} ) @@ -970,21 +1000,21 @@ if(CONFIG_USERSPACE) PROPERTIES COMPILE_DEFINITIONS "${compile_definitions_interface}") # Turn off -ffunction-sections, etc. - # NB: Using a library instead of target_compile_options(output_lib + # NB: Using a library instead of target_compile_options(${OUTPUT_LIB} # [...]) because a library's options have precedence - add_library(output_lib_interface INTERFACE) + add_library(${OUTPUT_LIB}_interface INTERFACE) - target_link_libraries(output_lib output_lib_interface) + target_link_libraries(${OUTPUT_LIB} ${OUTPUT_LIB_INTERFACE}) foreach(incl ${include_dir_in_interface}) - target_include_directories(output_lib_interface INTERFACE ${incl}) + target_include_directories(${OUTPUT_LIB_INTERFACE} INTERFACE ${incl}) endforeach() foreach(incl ${sys_include_dir_in_interface}) target_include_directories(output_lib_interface SYSTEM INTERFACE ${incl}) endforeach() - set(OUTPUT_OBJ_PATH ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/output_lib.dir/${OUTPUT_OBJ}) + set(OUTPUT_OBJ_PATH ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${OUTPUT_LIB}.dir/${OUTPUT_OBJ}) set(obj_copy_cmd "") set(obj_copy_sections_rename @@ -1001,28 +1031,29 @@ if(CONFIG_USERSPACE) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_OBJ_RENAMED} ${obj_copy_cmd} - DEPENDS output_lib + DEPENDS ${OUTPUT_LIB} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - add_custom_target(output_obj_renamed DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_OBJ_RENAMED}) + add_custom_target(${OUTPUT_OBJ_RENAMED_T} DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_OBJ_RENAMED}) - add_library(output_obj_renamed_lib STATIC IMPORTED GLOBAL) + add_library(${OUTPUT_OBJ_RENAMED_LIB} STATIC IMPORTED GLOBAL) set_property( - TARGET output_obj_renamed_lib + TARGET ${OUTPUT_OBJ_RENAMED_LIB} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_OBJ_RENAMED} ) add_dependencies( - output_obj_renamed_lib - output_obj_renamed + ${OUTPUT_OBJ_RENAMED_LIB} + ${OUTPUT_OBJ_RENAMED_T} ) - set_property(GLOBAL APPEND PROPERTY GENERATED_KERNEL_OBJECT_FILES output_obj_renamed_lib) + set_property(GLOBAL APPEND PROPERTY ${IMAGE}GENERATED_KERNEL_OBJECT_FILES + ${OUTPUT_OBJ_RENAMED_LIB}) endif() # Read global variables into local variables -get_property(GKOF GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES) -get_property(GKSF GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES) +get_property(GKOF GLOBAL PROPERTY ${IMAGE}GENERATED_KERNEL_OBJECT_FILES) +get_property(GKSF GLOBAL PROPERTY ${IMAGE}GENERATED_KERNEL_SOURCE_FILES) get_property(CSTD GLOBAL PROPERTY CSTD) @@ -1122,7 +1153,7 @@ if(CONFIG_USERSPACE) $ $<$:--verbose> DEPENDS - kernel + ${KERNEL_LIBRARY} ${ZEPHYR_LIBS_PROPERTY} app_smem_unaligned_prebuilt WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/ @@ -1142,29 +1173,29 @@ if(CONFIG_USERSPACE AND CONFIG_ARM) ) add_custom_target( - linker_priv_stacks_script + ${IMAGE}linker_priv_stacks_script DEPENDS linker_priv_stacks.cmd ) set_property(TARGET - linker_priv_stacks_script + ${IMAGE}linker_priv_stacks_script PROPERTY INCLUDE_DIRECTORIES ${ZEPHYR_INCLUDE_DIRS} ) - set(PRIV_STACK_LIB priv_stacks_output_obj_renamed_lib) - add_executable( priv_stacks_prebuilt misc/empty_file.c) + set(PRIV_STACK_LIB ${IMAGE}priv_stacks_output_obj_renamed_lib) + add_executable( ${PRIV_STACKS_PREBUILT} misc/empty_file.c) toolchain_ld_link_elf( - TARGET_ELF priv_stacks_prebuilt - OUTPUT_MAP ${PROJECT_BINARY_DIR}/priv_stacks_prebuilt.map + TARGET_ELF ${PRIV_STACKS_PREBUILT} + OUTPUT_MAP ${PROJECT_BINARY_DIR}/${PRIV_STACKS_PREBUILT}.map LIBRARIES_PRE_SCRIPT "" LINKER_SCRIPT ${PROJECT_BINARY_DIR}/linker_priv_stacks.cmd LIBRARIES_POST_SCRIPT "" DEPENDENCIES ${CODE_RELOCATION_DEP} ) - set_property(TARGET priv_stacks_prebuilt PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_priv_stacks.cmd) - add_dependencies( priv_stacks_prebuilt linker_priv_stacks_script ${OFFSETS_LIB}) + set_property(TARGET ${PRIV_STACKS_PREBUILT} PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/linker_priv_stacks.cmd) + add_dependencies( ${PRIV_STACKS_PREBUILT} ${IMAGE}linker_priv_stacks_script ${OFFSETS_LIB}) endif() # FIXME: Is there any way to get rid of empty_file.c? @@ -1199,7 +1230,7 @@ else() ${OFFSETS_H_TARGET} ) - set(LINKER_PASS_FINAL_SCRIPT_TARGET linker_pass_final_script_target) + set(LINKER_PASS_FINAL_SCRIPT_TARGET ${IMAGE}linker_pass_final_script_target) add_custom_target( ${LINKER_PASS_FINAL_SCRIPT_TARGET} DEPENDS @@ -1435,14 +1466,14 @@ list(APPEND ${extra_post_build_commands} ) -get_property(extra_post_build_byproducts +get_property(${IMAGE}extra_post_build_byproducts GLOBAL PROPERTY - extra_post_build_byproducts + ${IMAGE}extra_post_build_byproducts ) list(APPEND post_build_byproducts - ${extra_post_build_byproducts} + ${${IMAGE}extra_post_build_byproducts} ) # Add post_build_commands to post-process the final .elf file produced by @@ -1456,34 +1487,14 @@ add_custom_command( ${post_build_byproducts} COMMENT "Generating files from ${KERNEL_ELF_NAME} for board: ${BOARD}" # NB: COMMENT only works for some CMake-Generators + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) -# To populate with hex files to merge, do the following: -# set_property(GLOBAL APPEND PROPERTY HEX_FILES_TO_MERGE ${my_local_list}) -# Note that the zephyr.hex file will not be included automatically. -get_property(HEX_FILES_TO_MERGE GLOBAL PROPERTY HEX_FILES_TO_MERGE) -if(HEX_FILES_TO_MERGE) - # Merge in out-of-tree hex files. - set(MERGED_HEX_NAME merged.hex) - - add_custom_command( - OUTPUT ${MERGED_HEX_NAME} - COMMAND - ${PYTHON_EXECUTABLE} - ${ZEPHYR_BASE}/scripts/mergehex.py - -o ${MERGED_HEX_NAME} - ${HEX_FILES_TO_MERGE} - DEPENDS ${HEX_FILES_TO_MERGE} ${logical_target_for_zephyr_elf} - ) - - add_custom_target(mergehex ALL DEPENDS ${MERGED_HEX_NAME}) - list(APPEND FLASH_DEPS mergehex) -endif() if(EMU_PLATFORM) include(${ZEPHYR_BASE}/cmake/emu/${EMU_PLATFORM}.cmake) else() - add_custom_target(run + add_custom_target(${IMAGE}run COMMAND ${CMAKE_COMMAND} -E echo "===================================================" @@ -1493,7 +1504,6 @@ else() endif() add_subdirectory(cmake/flash) -add_subdirectory(cmake/usage) add_subdirectory(cmake/reports) if(NOT CONFIG_TEST) diff --git a/arch/arm/core/cortex_m/tz/CMakeLists.txt b/arch/arm/core/cortex_m/tz/CMakeLists.txt index a525844c8b902e..c4e4902fb7c3eb 100644 --- a/arch/arm/core/cortex_m/tz/CMakeLists.txt +++ b/arch/arm/core/cortex_m/tz/CMakeLists.txt @@ -22,7 +22,7 @@ if(CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS) # Indicate that the entry veneers library file is created during linking of this firmware. set_property( GLOBAL APPEND PROPERTY - extra_post_build_byproducts + ${IMAGE}extra_post_build_byproducts ${CMAKE_BINARY_DIR}/${CONFIG_ARM_ENTRY_VENEERS_LIB_NAME} ) endif() diff --git a/cmake/app/boilerplate.cmake b/cmake/app/boilerplate.cmake index fe7d4d95c4a19a..0f37d49419735a 100644 --- a/cmake/app/boilerplate.cmake +++ b/cmake/app/boilerplate.cmake @@ -28,42 +28,72 @@ cmake_policy(SET CMP0002 NEW) # CMP0079: "target_link_libraries() allows use with targets in other directories" cmake_policy(SET CMP0079 OLD) -define_property(GLOBAL PROPERTY ZEPHYR_LIBS - BRIEF_DOCS "Global list of all Zephyr CMake libs that should be linked in" - FULL_DOCS "Global list of all Zephyr CMake libs that should be linked in. +get_property(IMAGE GLOBAL PROPERTY IMAGE) + +if(IMAGE) + set(FIRST_BOILERPLATE_EXECUTION 0) +else() + set(FIRST_BOILERPLATE_EXECUTION 1) +endif() + +if (NOT FIRST_BOILERPLATE_EXECUTION) + # Clear the Kconfig namespace of the other image. + # Since the CMake context of each subsequent image is loaded by "add_subdirectory" + # the Kconfig namespace is automatically restored by CMake. + get_cmake_property(names VARIABLES) + foreach (name ${names}) + if("${name}" MATCHES "^CONFIG_") + # When a variable starts with 'CONFIG_' it is assumed to be a + # Kconfig symbol. + unset(${name}) + endif() + endforeach() +endif() + +define_property(GLOBAL PROPERTY ${IMAGE}ZEPHYR_LIBS + BRIEF_DOCS "Image-global list of all Zephyr CMake libs that should be linked in" + FULL_DOCS "Image-global list of all Zephyr CMake libs that should be linked in zephyr_library() appends libs to this list.") -set_property(GLOBAL PROPERTY ZEPHYR_LIBS "") +set_property(GLOBAL PROPERTY ${IMAGE}ZEPHYR_LIBS "") -define_property(GLOBAL PROPERTY ZEPHYR_INTERFACE_LIBS - BRIEF_DOCS "Global list of all Zephyr interface libs that should be linked in." - FULL_DOCS "Global list of all Zephyr interface libs that should be linked in. +define_property(GLOBAL PROPERTY ${IMAGE}ZEPHYR_INTERFACE_LIBS + BRIEF_DOCS "Image-global list of all Zephyr interface libs that should be linked in." + FULL_DOCS "Image-global list of all Zephyr interface libs that should be linked in. zephyr_interface_library_named() appends libs to this list.") -set_property(GLOBAL PROPERTY ZEPHYR_INTERFACE_LIBS "") +set_property(GLOBAL PROPERTY ${IMAGE}ZEPHYR_INTERFACE_LIBS "") -define_property(GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES +define_property(GLOBAL PROPERTY ${IMAGE}GENERATED_KERNEL_OBJECT_FILES BRIEF_DOCS "Object files that are generated after Zephyr has been linked once." FULL_DOCS "\ Object files that are generated after Zephyr has been linked once.\ May include mmu tables, etc." ) -set_property(GLOBAL PROPERTY GENERATED_KERNEL_OBJECT_FILES "") +set_property(GLOBAL PROPERTY ${IMAGE}GENERATED_KERNEL_OBJECT_FILES "") -define_property(GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES +define_property(GLOBAL PROPERTY ${IMAGE}GENERATED_KERNEL_SOURCE_FILES BRIEF_DOCS "Source files that are generated after Zephyr has been linked once." FULL_DOCS "\ Source files that are generated after Zephyr has been linked once.\ May include isr_tables.c etc." ) -set_property(GLOBAL PROPERTY GENERATED_KERNEL_SOURCE_FILES "") +set_property(GLOBAL PROPERTY ${IMAGE}GENERATED_KERNEL_SOURCE_FILES "") + +set(APPLICATION_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(APPLICATION_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) -set(APPLICATION_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH "Application Source Directory") -set(APPLICATION_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} CACHE PATH "Application Binary Directory") +message(STATUS "Using application from '${APPLICATION_SOURCE_DIR}'") set(__build_dir ${CMAKE_CURRENT_BINARY_DIR}/zephyr) set(PROJECT_BINARY_DIR ${__build_dir}) -add_custom_target(code_data_relocation_target) +define_property(GLOBAL PROPERTY ${IMAGE}PROJECT_BINARY_DIR + BRIEF_DOCS "Build directory (PROJECT_BINARY_DIR) for the ${IMAGE} image." + FULL_DOCS "To be used to access e.g. this image's hex file." + ) +set_property(GLOBAL PROPERTY ${IMAGE}PROJECT_BINARY_DIR ${PROJECT_BINARY_DIR}) + +add_custom_target(${IMAGE}code_data_relocation_target) # CMake's 'project' concept has proven to not be very useful for Zephyr # due in part to how Zephyr is organized and in part to it not fitting well @@ -94,93 +124,147 @@ include(CheckCXXCompilerFlag) include(${ZEPHYR_BASE}/cmake/extensions.cmake) include(${ZEPHYR_BASE}/cmake/version.cmake) # depends on hex.cmake -# -# Find tools -# - -include(${ZEPHYR_BASE}/cmake/python.cmake) -include(${ZEPHYR_BASE}/cmake/git.cmake) # depends on version.cmake -include(${ZEPHYR_BASE}/cmake/ccache.cmake) - if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) message(FATAL_ERROR "Source directory equals build directory.\ In-source builds are not supported.\ Please specify a build directory, e.g. cmake -Bbuild -H.") endif() -add_custom_target( - pristine - COMMAND ${CMAKE_COMMAND} -P ${ZEPHYR_BASE}/cmake/pristine.cmake - # Equivalent to rm -rf build/* - ) - # Dummy add to generate files. zephyr_linker_sources(SECTIONS) -# The BOARD can be set by 3 sources. Through environment variables, -# through the cmake CLI, and through CMakeLists.txt. -# -# CLI has the highest precedence, then comes environment variables, -# and then finally CMakeLists.txt. -# -# A user can ignore all the precedence rules if he simply always uses -# the same source. E.g. always specifies -DBOARD= on the command line, -# always has an environment variable set, or always has a set(BOARD -# foo) line in his CMakeLists.txt and avoids mixing sources. -# -# The selected BOARD can be accessed through the variable 'BOARD'. +if(FIRST_BOILERPLATE_EXECUTION) + # + # Find tools + # -# Read out the cached board value if present -get_property(cached_board_value CACHE BOARD PROPERTY VALUE) + include(${ZEPHYR_BASE}/cmake/python.cmake) + include(${ZEPHYR_BASE}/cmake/git.cmake) # depends on version.cmake + include(${ZEPHYR_BASE}/cmake/ccache.cmake) -# There are actually 4 sources, the three user input sources, and the -# previously used value (CACHED_BOARD). The previously used value has -# precedence, and if we detect that the user is trying to change the -# value we give him a warning about needing to clean the build -# directory to be able to change boards. + add_custom_target( + pristine + COMMAND ${CMAKE_COMMAND} -P ${ZEPHYR_BASE}/cmake/pristine.cmake + # Equivalent to rm -rf build/* + ) -set(board_cli_argument ${cached_board_value}) # Either new or old -if(board_cli_argument STREQUAL CACHED_BOARD) - # We already have a CACHED_BOARD so there is no new input on the CLI - unset(board_cli_argument) -endif() + # 'BOARD_ROOT' is a prioritized list of directories where boards may + # be found. It always includes ${ZEPHYR_BASE} at the lowest priority. + list(APPEND BOARD_ROOT ${ZEPHYR_BASE}) -set(board_app_cmake_lists ${BOARD}) -if(cached_board_value STREQUAL BOARD) - # The app build scripts did not set a default, The BOARD we are - # reading is the cached value from the CLI - unset(board_app_cmake_lists) -endif() + # The BOARD can be set by 3 sources. Through environment variables, + # through the cmake CLI, and through CMakeLists.txt. + # + # CLI has the highest precedence, then comes environment variables, + # and then finally CMakeLists.txt. + # + # A user can ignore all the precedence rules if he simply always uses + # the same source. E.g. always specifies -DBOARD= on the command line, + # always has an environment variable set, or always has a set(BOARD + # foo) line in his CMakeLists.txt and avoids mixing sources. + # + # The selected BOARD can be accessed through the variable 'BOARD'. -if(CACHED_BOARD) - # Warn the user if it looks like he is trying to change the board - # without cleaning first - if(board_cli_argument) - if(NOT (CACHED_BOARD STREQUAL board_cli_argument)) - message(WARNING "The build directory must be cleaned pristinely when changing boards") - # TODO: Support changing boards without requiring a clean build + # Read out the cached board value if present + get_property(cached_board_value CACHE BOARD PROPERTY VALUE) + + # There are actually 4 sources, the three user input sources, and the + # previously used value (CACHED_BOARD). The previously used value has + # precedence, and if we detect that the user is trying to change the + # value we give him a warning about needing to clean the build + # directory to be able to change boards. + + set(board_cli_argument ${cached_board_value}) # Either new or old + if(board_cli_argument STREQUAL CACHED_BOARD) + # We already have a CACHED_BOARD so there is no new input on the CLI + unset(board_cli_argument) + endif() + + set(board_app_cmake_lists ${BOARD}) + if(cached_board_value STREQUAL BOARD) + # The app build scripts did not set a default, The BOARD we are + # reading is the cached value from the CLI + unset(board_app_cmake_lists) + endif() + + if(CACHED_BOARD) + # Warn the user if it looks like he is trying to change the board + # without cleaning first + if(board_cli_argument) + if(NOT (CACHED_BOARD STREQUAL board_cli_argument)) + message(WARNING "The build directory must be cleaned pristinely when changing boards") + # TODO: Support changing boards without requiring a clean build + endif() endif() + + set(BOARD ${CACHED_BOARD}) + elseif(board_cli_argument) + set(BOARD ${board_cli_argument}) + + elseif(DEFINED ENV{BOARD}) + set(BOARD $ENV{BOARD}) + + elseif(board_app_cmake_lists) + set(BOARD ${board_app_cmake_lists}) + + else() + message(FATAL_ERROR "BOARD is not being defined on the CMake command-line in the environment or by the app.") endif() - set(BOARD ${CACHED_BOARD}) -elseif(board_cli_argument) - set(BOARD ${board_cli_argument}) + assert(BOARD "BOARD not set") + message(STATUS "Selected BOARD ${BOARD}") -elseif(DEFINED ENV{BOARD}) - set(BOARD $ENV{BOARD}) + # Store the selected board in the cache + set(CACHED_BOARD ${BOARD} CACHE STRING "Selected board") -elseif(board_app_cmake_lists) - set(BOARD ${board_app_cmake_lists}) + if(NOT ARCH_ROOT) + set(ARCH_DIR ${ZEPHYR_BASE}/arch) + else() + set(ARCH_DIR ${ARCH_ROOT}/arch) + endif() -else() - message(FATAL_ERROR "BOARD is not being defined on the CMake command-line in the environment or by the app.") -endif() + if(NOT SOC_ROOT) + set(SOC_DIR ${ZEPHYR_BASE}/soc) + else() + set(SOC_DIR ${SOC_ROOT}/soc) + endif() + + # Prevent CMake from testing the toolchain + set(CMAKE_C_COMPILER_FORCED 1) + set(CMAKE_CXX_COMPILER_FORCED 1) + + include(${ZEPHYR_BASE}/cmake/host-tools.cmake) -assert(BOARD "BOARD not set") -message(STATUS "Selected BOARD ${BOARD}") + string(REPLACE ";" " " BOARD_ROOT_SPACE_SEPARATED "${BOARD_ROOT}") + string(REPLACE ";" " " SHIELD_LIST_SPACE_SEPARATED "${SHIELD_LIST}") -# Store the selected board in the cache -set(CACHED_BOARD ${BOARD} CACHE STRING "Selected board") + # NB: The reason it is 'usage' and not help is that CMake already + # defines a target 'help' + add_custom_target( + usage + ${CMAKE_COMMAND} + -DBOARD_ROOT_SPACE_SEPARATED=${BOARD_ROOT_SPACE_SEPARATED} + -DSHIELD_LIST_SPACE_SEPARATED=${SHIELD_LIST_SPACE_SEPARATED} + -P ${ZEPHYR_BASE}/cmake/usage/usage.cmake + ) + + include(${ZEPHYR_BASE}/cmake/zephyr_module.cmake) + + if(NOT DEFINED USER_CACHE_DIR) + find_appropriate_cache_directory(USER_CACHE_DIR) + endif() + message(STATUS "Cache files will be written to: ${USER_CACHE_DIR}") +else() # NOT FIRST_BOILERPLATE_EXECUTION + + # Have the child image select the same BOARD that was selected by + # the parent. + set(BOARD ${CACHED_BOARD}) + + unset(${IMAGE}DTC_OVERLAY_FILE) + if(EXISTS ${APPLICATION_SOURCE_DIR}/${BOARD}.overlay) + set(${IMAGE}DTC_OVERLAY_FILE ${APPLICATION_SOURCE_DIR}/${BOARD}.overlay) + endif() +endif(FIRST_BOILERPLATE_EXECUTION) # The SHIELD can be set by 3 sources. Through environment variables, # through the cmake CLI, and through CMakeLists.txt. @@ -188,15 +272,18 @@ set(CACHED_BOARD ${BOARD} CACHE STRING "Selected board") # CLI has the highest precedence, then comes environment variables, # and then finally CMakeLists.txt. # -# A user can ignore all the precedence rules if he simply always uses +# A user can ignore all the precedence rules if she simply always uses # the same source. E.g. always specifies -DSHIELD= on the command line, # always has an environment variable set, or always has a set(SHIELD -# foo) line in his CMakeLists.txt and avoids mixing sources. +# foo) line in her CMakeLists.txt and avoids mixing sources. # # The selected SHIELD can be accessed through the variable 'SHIELD'. +# +# To specify a SHIELD specifically for an image, prefix with the image +# name. E.g. -Dmcuboot_SHIELD= on the command line. # Read out the cached shield value if present -get_property(cached_shield_value CACHE SHIELD PROPERTY VALUE) +get_property(cached_shield_value CACHE ${IMAGE}SHIELD PROPERTY VALUE) # There are actually 4 sources, the three user input sources, and the # previously used value (CACHED_SHIELD). The previously used value has @@ -205,70 +292,64 @@ get_property(cached_shield_value CACHE SHIELD PROPERTY VALUE) # directory to be able to change shields. set(shield_cli_argument ${cached_shield_value}) # Either new or old -if(shield_cli_argument STREQUAL CACHED_SHIELD) +if(shield_cli_argument STREQUAL ${IMAGE}CACHED_SHIELD) # We already have a CACHED_SHIELD so there is no new input on the CLI unset(shield_cli_argument) endif() -set(shield_app_cmake_lists ${SHIELD}) -if(cached_shield_value STREQUAL SHIELD) +set(shield_app_cmake_lists ${${IMAGE}SHIELD}) +if(cached_shield_value STREQUAL ${IMAGE}SHIELD) # The app build scripts did not set a default, The SHIELD we are # reading is the cached value from the CLI unset(shield_app_cmake_lists) endif() -if(CACHED_SHIELD) - # Warn the user if it looks like he is trying to change the shield +if(${IMAGE}CACHED_SHIELD) + # Warn the user if it looks like she is trying to change the shield # without cleaning first if(shield_cli_argument) - if(NOT (CACHED_SHIELD STREQUAL shield_cli_argument)) + if(NOT (${IMAGE}CACHED_SHIELD STREQUAL shield_cli_argument)) message(WARNING "The build directory must be cleaned pristinely when changing shields") # TODO: Support changing shields without requiring a clean build endif() endif() - set(SHIELD ${CACHED_SHIELD}) + set(${IMAGE}SHIELD ${${IMAGE}CACHED_SHIELD}) elseif(shield_cli_argument) - set(SHIELD ${shield_cli_argument}) + set(${IMAGE}SHIELD ${shield_cli_argument}) -elseif(DEFINED ENV{SHIELD}) - set(SHIELD $ENV{SHIELD}) +elseif(DEFINED ENV{${IMAGE}SHIELD}) + set(${IMAGE}SHIELD $ENV{${IMAGE}SHIELD}) elseif(shield_app_cmake_lists) - set(SHIELD ${shield_app_cmake_lists}) + set(${IMAGE}SHIELD ${shield_app_cmake_lists}) endif() # Store the selected shield in the cache -set(CACHED_SHIELD ${SHIELD} CACHE STRING "Selected shield") - -# 'BOARD_ROOT' is a prioritized list of directories where boards may -# be found. It always includes ${ZEPHYR_BASE} at the lowest priority. -list(APPEND BOARD_ROOT ${ZEPHYR_BASE}) - -if(NOT SOC_ROOT) - set(SOC_DIR ${ZEPHYR_BASE}/soc) -else() - set(SOC_DIR ${SOC_ROOT}/soc) -endif() - -if(NOT ARCH_ROOT) - set(ARCH_DIR ${ZEPHYR_BASE}/arch) -else() - set(ARCH_DIR ${ARCH_ROOT}/arch) -endif() +set(${IMAGE}CACHED_SHIELD ${${IMAGE}SHIELD} CACHE STRING "Selected shield") # Use BOARD to search for a '_defconfig' file. # e.g. zephyr/boards/arm/96b_carbon_nrf51/96b_carbon_nrf51_defconfig. # When found, use that path to infer the ARCH we are building for. foreach(root ${BOARD_ROOT}) - # NB: find_path will return immediately if the output variable is - # already set - find_path(BOARD_DIR - NAMES ${BOARD}_defconfig - PATHS ${root}/boards/*/* - NO_DEFAULT_PATH - ) + if (NOT BOARD_DIR) + # NB: find_path will return immediately if the output variable is + # already set this because it will set the output variable in the + # CACHE as well. + find_path(TMP_BOARD_DIR + NAMES ${BOARD}_defconfig + PATHS ${root}/boards/*/* + NO_DEFAULT_PATH + ) + set(BOARD_DIR ${TMP_BOARD_DIR}) + unset(TMP_BOARD_DIR CACHE) + endif() + + # Ensure that BOARD_DIR is not in CACHE so that different images can use + # different BOARD_DIR. + if(BOARD_DIR AND NOT (${root} STREQUAL ${ZEPHYR_BASE})) + message("USING OUT OF TREE BOARD") set(USING_OUT_OF_TREE_BOARD 1) endif() @@ -360,6 +441,15 @@ foreach(root ${BOARD_ROOT}) endif() endforeach() endif() + + if(DEFINED SHIELD AND DEFINED NOT_FOUND_SHIELD_LIST) + foreach (s ${NOT_FOUND_SHIELD_LIST}) + message("No shield named '${s}' found") + endforeach() + print_usage() + unset(CACHED_SHIELD CACHE) + message(FATAL_ERROR "Invalid usage") + endif() endforeach() if(NOT BOARD_DIR) @@ -369,45 +459,52 @@ if(NOT BOARD_DIR) message(FATAL_ERROR "Invalid usage") endif() -if(DEFINED SHIELD AND DEFINED NOT_FOUND_SHIELD_LIST) - foreach (s ${NOT_FOUND_SHIELD_LIST}) - message("No shield named '${s}' found") - endforeach() - print_usage() - unset(CACHED_SHIELD CACHE) - message(FATAL_ERROR "Invalid usage") -endif() +unset(BOARD_ARCH_DIR CACHE) +unset(BOARD_FAMILY CACHE) +unset(ARCH CACHE) -get_filename_component(BOARD_ARCH_DIR ${BOARD_DIR} DIRECTORY) +get_filename_component(BOARD_ARCH_DIR ${BOARD_DIR} DIRECTORY) get_filename_component(BOARD_FAMILY ${BOARD_DIR} NAME) get_filename_component(ARCH ${BOARD_ARCH_DIR} NAME) -if(CONF_FILE) - # CONF_FILE has either been specified on the cmake CLI or is already - # in the CMakeCache.txt. This has precedence over the environment - # variable CONF_FILE and the default prj.conf -elseif(DEFINED ENV{CONF_FILE}) - set(CONF_FILE $ENV{CONF_FILE}) +# DTS should be close to kconfig because CONFIG_ variables from +# kconfig and dts should be available at the same time. +# +# The DT system uses a C preprocessor for it's code generation needs. +# This creates an awkward chicken-and-egg problem, because we don't +# always know exactly which toolchain the user needs until we know +# more about the target, e.g. after DT and Kconfig. +# +# To resolve this we find "some" C toolchain, configure it generically +# with the minimal amount of configuration needed to have it +# preprocess DT sources, and then, after we have finished processing +# both DT and Kconfig we complete the target-specific configuration, +# and possibly change the toolchain. + +# Populate USER_CACHE_DIR with a directory that user applications may +# write cache files to. +include(${ZEPHYR_BASE}/cmake/generic_toolchain.cmake) + +if(${IMAGE}CONF_FILE) + # ${IMAGE}CONF_FILE has either been specified on the cmake CLI or is already + # in the CMakeCache.txt. This has precedence over the environment + # variable ${IMAGE}CONF_FILE and the default prj.conf +elseif(DEFINED ENV{${IMAGE}CONF_FILE}) + set(${IMAGE}CONF_FILE $ENV{${IMAGE}CONF_FILE}) elseif(COMMAND set_conf_file) message(WARNING "'set_conf_file' is deprecated, it will be removed in a future release.") set_conf_file() - elseif(EXISTS ${APPLICATION_SOURCE_DIR}/prj_${BOARD}.conf) - set(CONF_FILE ${APPLICATION_SOURCE_DIR}/prj_${BOARD}.conf) + set(${IMAGE}CONF_FILE ${APPLICATION_SOURCE_DIR}/prj_${BOARD}.conf) elseif(EXISTS ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf) - set(CONF_FILE ${APPLICATION_SOURCE_DIR}/prj.conf ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf) + set(${IMAGE}CONF_FILE ${APPLICATION_SOURCE_DIR}/prj.conf ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.conf) elseif(EXISTS ${APPLICATION_SOURCE_DIR}/prj.conf) - set(CONF_FILE ${APPLICATION_SOURCE_DIR}/prj.conf) + set(${IMAGE}CONF_FILE ${APPLICATION_SOURCE_DIR}/prj.conf) endif() -set(CONF_FILE ${CONF_FILE} CACHE STRING "If desired, you can build the application using\ -the configuration settings specified in an alternate .conf file using this parameter. \ -These settings will override the settings in the application’s .config file or its default .conf file.\ -Multiple files may be listed, e.g. CONF_FILE=\"prj1.conf prj2.conf\"") - if(ZEPHYR_EXTRA_MODULES) # ZEPHYR_EXTRA_MODULES has either been specified on the cmake CLI or is # already in the CMakeCache.txt. This has precedence over the environment @@ -416,47 +513,35 @@ elseif(DEFINED ENV{ZEPHYR_EXTRA_MODULES}) set(ZEPHYR_EXTRA_MODULES $ENV{ZEPHYR_EXTRA_MODULES}) endif() -if(DTC_OVERLAY_FILE) - # DTC_OVERLAY_FILE has either been specified on the cmake CLI or is already - # in the CMakeCache.txt. This has precedence over the environment - # variable DTC_OVERLAY_FILE -elseif(DEFINED ENV{DTC_OVERLAY_FILE}) - set(DTC_OVERLAY_FILE $ENV{DTC_OVERLAY_FILE}) +if(${IMAGE}DTC_OVERLAY_FILE) + # DTC_OVERLAY_FILE has either been specified on the cmake CLI or is + # already in the CMakeCache.txt. This has precedence over the + # environment variable DTC_OVERLAY_FILE +elseif(DEFINED ENV{${IMAGE}DTC_OVERLAY_FILE}) + set(${IMAGE}DTC_OVERLAY_FILE $ENV{${IMAGE}DTC_OVERLAY_FILE}) elseif(EXISTS ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.overlay) set(DTC_OVERLAY_FILE ${APPLICATION_SOURCE_DIR}/boards/${BOARD}.overlay) elseif(EXISTS ${APPLICATION_SOURCE_DIR}/${BOARD}.overlay) - set(DTC_OVERLAY_FILE ${APPLICATION_SOURCE_DIR}/${BOARD}.overlay) + set(${IMAGE}DTC_OVERLAY_FILE ${APPLICATION_SOURCE_DIR}/${BOARD}.overlay) elseif(EXISTS ${APPLICATION_SOURCE_DIR}/app.overlay) - set(DTC_OVERLAY_FILE ${APPLICATION_SOURCE_DIR}/app.overlay) + set(${IMAGE}DTC_OVERLAY_FILE ${APPLICATION_SOURCE_DIR}/app.overlay) endif() -set(DTC_OVERLAY_FILE ${DTC_OVERLAY_FILE} CACHE STRING "If desired, you can \ +set(${IMAGE}CONF_FILE ${${IMAGE}CONF_FILE} CACHE STRING "If desired, you can build the application using\ +the configuration settings specified in an alternate .conf file using this parameter. \ +These settings will override the settings in the application’s .config file or its default .conf file.\ +Multiple files may be listed, e.g. CONF_FILE=\"prj1.conf prj2.conf\". \ +To specify an alternate .conf file for a specific image, prefix \"CONF_FILE\" \ +with the image name. For instance \"mcuboot_CONF_FILE\".") + +set(${IMAGE}DTC_OVERLAY_FILE ${${IMAGE}DTC_OVERLAY_FILE} CACHE STRING "If desired, you can \ build the application using the DT configuration settings specified in an \ alternate .overlay file using this parameter. These settings will override the \ settings in the board's .dts file. Multiple files may be listed, e.g. \ -DTC_OVERLAY_FILE=\"dts1.overlay dts2.overlay\"") +DTC_OVERLAY_FILE=\"dts1.overlay dts2.overlay\". To specify an alternate +.overlay file for a specific image, prefix \"DTC_OVERLAY_FILE\" with the image name. \ +For instance \"mcuboot_DTC_OVERLAY_FILE\".") -# Prevent CMake from testing the toolchain -set(CMAKE_C_COMPILER_FORCED 1) -set(CMAKE_CXX_COMPILER_FORCED 1) - -include(${ZEPHYR_BASE}/cmake/host-tools.cmake) - -# DTS should be close to kconfig because CONFIG_ variables from -# kconfig and dts should be available at the same time. -# -# The DT system uses a C preprocessor for it's code generation needs. -# This creates an awkward chicken-and-egg problem, because we don't -# always know exactly which toolchain the user needs until we know -# more about the target, e.g. after DT and Kconfig. -# -# To resolve this we find "some" C toolchain, configure it generically -# with the minimal amount of configuration needed to have it -# preprocess DT sources, and then, after we have finished processing -# both DT and Kconfig we complete the target-specific configuration, -# and possibly change the toolchain. -include(${ZEPHYR_BASE}/cmake/zephyr_module.cmake) -include(${ZEPHYR_BASE}/cmake/generic_toolchain.cmake) include(${ZEPHYR_BASE}/cmake/dts.cmake) include(${ZEPHYR_BASE}/cmake/kconfig.cmake) @@ -493,12 +578,11 @@ set(KERNEL_EXE_NAME ${KERNEL_NAME}.exe) set(KERNEL_STAT_NAME ${KERNEL_NAME}.stat) set(KERNEL_STRIP_NAME ${KERNEL_NAME}.strip) -# Populate USER_CACHE_DIR with a directory that user applications may -# write cache files to. -if(NOT DEFINED USER_CACHE_DIR) - find_appropriate_cache_directory(USER_CACHE_DIR) -endif() -message(STATUS "Cache files will be written to: ${USER_CACHE_DIR}") +define_property(GLOBAL PROPERTY ${IMAGE}KERNEL_NAME + BRIEF_DOCS "Name (KERNEL_NAME) for the ${IMAGE} image." + FULL_DOCS "To be used to access e.g. this image's hex file." + ) +set_property(GLOBAL PROPERTY ${IMAGE}KERNEL_NAME ${KERNEL_NAME}) include(${BOARD_DIR}/board.cmake OPTIONAL) @@ -536,7 +620,7 @@ add_custom_target(zephyr_property_target) # modified by the entry point ${APPLICATION_SOURCE_DIR}/CMakeLists.txt # that was specified when cmake was called. zephyr_library_named(app) -set_property(TARGET app PROPERTY ARCHIVE_OUTPUT_DIRECTORY app) +set_property(TARGET ${IMAGE}app PROPERTY ARCHIVE_OUTPUT_DIRECTORY ${IMAGE}app) add_subdirectory(${ZEPHYR_BASE} ${__build_dir}) @@ -547,17 +631,35 @@ add_subdirectory(${ZEPHYR_BASE} ${__build_dir}) # done after 'add_subdirectory(${ZEPHYR_BASE} ${__build_dir})' # because interface libraries are defined while processing that # subdirectory. -get_property(ZEPHYR_INTERFACE_LIBS_PROPERTY GLOBAL PROPERTY ZEPHYR_INTERFACE_LIBS) +get_property(ZEPHYR_INTERFACE_LIBS_PROPERTY GLOBAL PROPERTY ${IMAGE}ZEPHYR_INTERFACE_LIBS) foreach(boilerplate_lib ${ZEPHYR_INTERFACE_LIBS_PROPERTY}) # Linking 'app' with 'boilerplate_lib' causes 'app' to inherit the INTERFACE # properties of 'boilerplate_lib'. The most common property is 'include # directories', but it is also possible to have defines and compiler # flags in the interface of a library. - # - string(TOUPPER ${boilerplate_lib} boilerplate_lib_upper_case) # Support lowercase lib names + + # 'boilerplate_lib' is formatted as '0_mbedtls' (for instance). But + # the Kconfig options are formatted as + # 'CONFIG_APP_LINK_WITH_MBEDTLS'. So we need to strip the '0_' and + # convert to upper case. + + # Match the non-image'ified library name. E.g. '1_mylib' -> 'mylib'. + set(image_regex "^${IMAGE}(.*)") + string(REGEX MATCH + ${image_regex} + unused_out_var + ${boilerplate_lib} + ) + if(CMAKE_MATCH_1) + set(boilerplate_lib_without_image ${CMAKE_MATCH_1}) + else() + message(FATAL_ERROR "Internal error. Expected '${boilerplate_lib}' to match '${image_regex}'") + endif() + + string(TOUPPER ${boilerplate_lib_without_image} boilerplate_lib_upper_case) # Support lowercase lib names target_link_libraries_ifdef( CONFIG_APP_LINK_WITH_${boilerplate_lib_upper_case} - app + ${IMAGE}app PUBLIC ${boilerplate_lib} ) diff --git a/cmake/compiler/gcc/target.cmake b/cmake/compiler/gcc/target.cmake index 401cc28db8a0d4..6f247b65fd86ab 100644 --- a/cmake/compiler/gcc/target.cmake +++ b/cmake/compiler/gcc/target.cmake @@ -72,8 +72,9 @@ if(NOT no_libgcc) assert_exists(LIBGCC_DIR) - LIST(APPEND LIB_INCLUDE_DIR "-L\"${LIBGCC_DIR}\"") - LIST(APPEND TOOLCHAIN_LIBS gcc) + #TODO multi_image add ${IMAGE} prefix to other toolchains. + LIST(APPEND ${IMAGE}LIB_INCLUDE_DIR "-L\"${LIBGCC_DIR}\"") + LIST(APPEND ${IMAGE}TOOLCHAIN_LIBS gcc) endif() if(SYSROOT_DIR) diff --git a/cmake/dts.cmake b/cmake/dts.cmake index 669b581a3db428..b70db223ad7063 100644 --- a/cmake/dts.cmake +++ b/cmake/dts.cmake @@ -16,13 +16,13 @@ set(GENERATED_DTS_BOARD_UNFIXED_H ${PROJECT_BINARY_DIR}/include/generated/genera set(GENERATED_DTS_BOARD_CONF ${PROJECT_BINARY_DIR}/include/generated/generated_dts_board.conf) set(DTS_POST_CPP ${PROJECT_BINARY_DIR}/${BOARD}.dts.pre.tmp) -set_ifndef(DTS_SOURCE ${BOARD_DIR}/${BOARD}.dts) - if(DEFINED DTS_COMMON_OVERLAYS) # TODO: remove this warning in version 1.16 message(FATAL_ERROR "DTS_COMMON_OVERLAYS is no longer supported. Use DTC_OVERLAY_FILE instead.") endif() +set_ifndef(${IMAGE}DTS_SOURCE ${BOARD_DIR}/${BOARD}.dts) + # 'DTS_ROOT' is a list of directories where a directory tree with DT # files may be found. It always includes the application directory, # the board directory, and ${ZEPHYR_BASE}. @@ -39,22 +39,23 @@ list(REMOVE_DUPLICATES list(REMOVE_DUPLICATES DTS_ROOT) set(dts_files - ${DTS_SOURCE} + ${${IMAGE}DTS_SOURCE} + ${DTS_COMMON_OVERLAYS} ${shield_dts_files} ) # TODO: What to do about non-posix platforms where NOT CONFIG_HAS_DTS (xtensa)? # Drop support for NOT CONFIG_HAS_DTS perhaps? -if(EXISTS ${DTS_SOURCE}) +if(EXISTS ${${IMAGE}DTS_SOURCE}) set(SUPPORTS_DTS 1) else() set(SUPPORTS_DTS 0) endif() if(SUPPORTS_DTS) - if(DTC_OVERLAY_FILE) + if(${IMAGE}DTC_OVERLAY_FILE) # Convert from space-separated files into file list - string(REPLACE " " ";" DTC_OVERLAY_FILE_AS_LIST ${DTC_OVERLAY_FILE}) + string(REPLACE " " ";" DTC_OVERLAY_FILE_AS_LIST ${${IMAGE}DTC_OVERLAY_FILE}) list(APPEND dts_files ${DTC_OVERLAY_FILE_AS_LIST} diff --git a/cmake/extensions.cmake b/cmake/extensions.cmake index be5e5235f50e71..00eea8ba8d616f 100644 --- a/cmake/extensions.cmake +++ b/cmake/extensions.cmake @@ -69,7 +69,7 @@ function(zephyr_sources) if(IS_DIRECTORY ${arg}) message(FATAL_ERROR "zephyr_sources() was called on a directory") endif() - target_sources(zephyr PRIVATE ${arg}) + target_sources(${IMAGE}zephyr PRIVATE ${arg}) endforeach() endfunction() @@ -81,7 +81,7 @@ function(zephyr_include_directories) else() set(path ${CMAKE_CURRENT_SOURCE_DIR}/${arg}) endif() - target_include_directories(zephyr_interface INTERFACE ${path}) + target_include_directories(${IMAGE}zephyr_interface INTERFACE ${path}) endforeach() endfunction() @@ -93,42 +93,87 @@ function(zephyr_system_include_directories) else() set(path ${CMAKE_CURRENT_SOURCE_DIR}/${arg}) endif() - target_include_directories(zephyr_interface SYSTEM INTERFACE ${path}) + target_include_directories(${IMAGE}zephyr_interface SYSTEM INTERFACE ${path}) endforeach() endfunction() # https://cmake.org/cmake/help/latest/command/target_compile_definitions.html function(zephyr_compile_definitions) - target_compile_definitions(zephyr_interface INTERFACE ${ARGV}) + target_compile_definitions(${IMAGE}zephyr_interface INTERFACE ${ARGV}) endfunction() # https://cmake.org/cmake/help/latest/command/target_compile_options.html function(zephyr_compile_options) - target_compile_options(zephyr_interface INTERFACE ${ARGV}) + target_compile_options(${IMAGE}zephyr_interface INTERFACE ${ARGV}) endfunction() # https://cmake.org/cmake/help/latest/command/target_link_libraries.html function(zephyr_link_libraries) - target_link_libraries(zephyr_interface INTERFACE ${ARGV}) + target_link_libraries(${IMAGE}zephyr_interface INTERFACE ${ARGV}) endfunction() # See this file section 3.1. target_cc_option function(zephyr_cc_option) foreach(arg ${ARGV}) - target_cc_option(zephyr_interface INTERFACE ${arg}) + target_cc_option(${IMAGE}zephyr_interface INTERFACE ${arg}) endforeach() endfunction() +# Add new executable which is built using a separate configuration. This is +# needed when a component needs to be built as an independent hex file, or with +# different configuration. Examples of use include bootloaders, and +# secure/non-secure partitions in a TrustZone environment. +# +# This function creates a new 'app' context, equivalent to the one defined by +# the 'origin' context. The CMakeLists.txt file pointed to by the users +# 'cmake' command defines the 'origin' context. All targets defined by the new +# context is prefixed with the name provided in the 'name' argument. As +# a result of this, in order to execute the 'menuconfig' target to perform +# configuration 'name_menuconfig' must be used instead. Note the targets +# defined by the 'origin' context is not prefixed in any way. +# +# Only a small set of configurations is shared between the 'origin' context and +# the new context, notably CMake properties. The new context defines its own +# set of: - CMake variables (note: not properties) - DTS configuration - +# KConfig configuration +# +# When multiple contexts are defined, a new merge target is defined which +# merges the resulting hex files. The 'flash' target is updated to use this +# merged hex file instead of the 'zephyr.hex' file from the origin context. +# +function(zephyr_add_executable name output_variable) + set(${output_variable} 0 PARENT_SCOPE) + string(TOUPPER ${name} UPNAME) + + if (CONFIG_${UPNAME}_BUILD_STRATEGY_USE_HEX_FILE) + assert_exists(CONFIG_${UPNAME}_HEX_FILE) + message("Using ${CONFIG_${UPNAME}_HEX_FILE} instead of building ${name}") + set_property(GLOBAL APPEND PROPERTY + HEX_FILES_TO_MERGE + ${CONFIG_${UPNAME}_HEX_FILE} + ${APPLICATION_BINARY_DIR}/zephyr/${KERNEL_HEX_NAME} + ) + elseif (CONFIG_${UPNAME}_BUILD_STRATEGY_SKIP_BUILD) + message("Skipping building of ${name}") + else() + # Build normally + set_property(GLOBAL PROPERTY IMAGE ${name}_) + set(${output_variable} 1 PARENT_SCOPE) + endif() + +endfunction() + + function(zephyr_cc_option_fallback option1 option2) - target_cc_option_fallback(zephyr_interface INTERFACE ${option1} ${option2}) + target_cc_option_fallback(${IMAGE}zephyr_interface INTERFACE ${option1} ${option2}) endfunction() function(zephyr_ld_options) - target_ld_options(zephyr_interface INTERFACE ${ARGV}) + target_ld_options(${IMAGE}zephyr_interface INTERFACE ${ARGV}) endfunction() # Getter functions for extracting build information from -# zephyr_interface. Returning lists, and strings is supported, as is +# ${IMAGE}zephyr_interface. Returning lists, and strings is supported, as is # requesting specific categories of build information (defines, # includes, options). # @@ -196,7 +241,7 @@ function(zephyr_get_compile_options_for_lang_as_string lang i) endfunction() function(zephyr_get_include_directories_for_lang lang i) - get_property_and_add_prefix(flags zephyr_interface INTERFACE_INCLUDE_DIRECTORIES + get_property_and_add_prefix(flags ${IMAGE}zephyr_interface INTERFACE_INCLUDE_DIRECTORIES "-I" ${ARGN} ) @@ -207,7 +252,7 @@ function(zephyr_get_include_directories_for_lang lang i) endfunction() function(zephyr_get_system_include_directories_for_lang lang i) - get_property_and_add_prefix(flags zephyr_interface INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + get_property_and_add_prefix(flags ${IMAGE}zephyr_interface INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "-isystem" ${ARGN} ) @@ -218,7 +263,7 @@ function(zephyr_get_system_include_directories_for_lang lang i) endfunction() function(zephyr_get_compile_definitions_for_lang lang i) - get_property_and_add_prefix(flags zephyr_interface INTERFACE_COMPILE_DEFINITIONS + get_property_and_add_prefix(flags ${IMAGE}zephyr_interface INTERFACE_COMPILE_DEFINITIONS "-D" ${ARGN} ) @@ -229,7 +274,7 @@ function(zephyr_get_compile_definitions_for_lang lang i) endfunction() function(zephyr_get_compile_options_for_lang lang i) - get_property(flags TARGET zephyr_interface PROPERTY INTERFACE_COMPILE_OPTIONS) + get_property(flags TARGET ${IMAGE}zephyr_interface PROPERTY INTERFACE_COMPILE_OPTIONS) process_flags(${lang} flags output_list) @@ -368,12 +413,12 @@ endmacro() macro(zephyr_library_named name) # This is a macro because we need add_library() to be executed # within the scope of the caller. - set(ZEPHYR_CURRENT_LIBRARY ${name}) - add_library(${name} STATIC "") + set(ZEPHYR_CURRENT_LIBRARY ${IMAGE}${name}) + add_library(${ZEPHYR_CURRENT_LIBRARY} STATIC "") - zephyr_append_cmake_library(${name}) + zephyr_append_cmake_library(${ZEPHYR_CURRENT_LIBRARY}) - target_link_libraries(${name} PUBLIC zephyr_interface) + target_link_libraries(${ZEPHYR_CURRENT_LIBRARY} PUBLIC ${IMAGE}zephyr_interface) endmacro() # Provides amend functionality to a Zephyr library for out-of-tree usage. @@ -406,7 +451,7 @@ macro(zephyr_library_amend) endmacro() function(zephyr_link_interface interface) - target_link_libraries(${interface} INTERFACE zephyr_interface) + target_link_libraries(${interface} INTERFACE ${IMAGE}zephyr_interface) endfunction() # @@ -436,8 +481,8 @@ function(zephyr_library_compile_options item) # library and link with it to obtain the flags. # # Linking with a dummy interface library will place flags later on - # the command line than the the flags from zephyr_interface because - # zephyr_interface will be the first interface library that flags + # the command line than the the flags from ${IMAGE}zephyr_interface because + # ${IMAGE}zephyr_interface will be the first interface library that flags # are taken from. string(MD5 uniqueness ${item}) @@ -470,7 +515,7 @@ endfunction() # constructor but must called explicitly on CMake libraries that do # not use a zephyr library constructor. function(zephyr_append_cmake_library library) - set_property(GLOBAL APPEND PROPERTY ZEPHYR_LIBS ${library}) + set_property(GLOBAL APPEND PROPERTY ${IMAGE}ZEPHYR_LIBS ${library}) endfunction() # Add the imported library 'library_name', located at 'library_path' to the @@ -523,8 +568,10 @@ endfunction() # This API has a constructor like the zephyr_library API has, but it # does not have wrappers over the other cmake target functions. macro(zephyr_interface_library_named name) - add_library(${name} INTERFACE) - set_property(GLOBAL APPEND PROPERTY ZEPHYR_INTERFACE_LIBS ${name}) + add_library(${IMAGE}${name} INTERFACE) + set_property(GLOBAL APPEND PROPERTY + ${IMAGE}ZEPHYR_INTERFACE_LIBS + ${IMAGE}${name}) endmacro() # 1.3 generate_inc_* @@ -893,14 +940,14 @@ function(zephyr_linker_sources location) set(rodata_path "${snippet_base}/snippets-rodata.ld") # Clear destination files if this is the first time the function is called. - get_property(cleared GLOBAL PROPERTY snippet_files_cleared) + get_property(cleared GLOBAL PROPERTY ${IMAGE}snippet_files_cleared) if (NOT DEFINED cleared) file(WRITE ${sections_path} "") file(WRITE ${ram_sections_path} "") file(WRITE ${noinit_path} "") file(WRITE ${rwdata_path} "") file(WRITE ${rodata_path} "") - set_property(GLOBAL PROPERTY snippet_files_cleared true) + set_property(GLOBAL PROPERTY ${IMAGE}snippet_files_cleared true) endif() # Choose destination file, based on the argument. @@ -942,7 +989,7 @@ endfunction(zephyr_linker_sources) # Helper function for CONFIG_CODE_DATA_RELOCATION # Call this function with 2 arguments file and then memory location function(zephyr_code_relocate file location) - set_property(TARGET code_data_relocation_target + set_property(TARGET ${IMAGE}code_data_relocation_target APPEND PROPERTY COMPILE_DEFINITIONS "${location}:${CMAKE_CURRENT_SOURCE_DIR}/${file}") endfunction() @@ -1054,6 +1101,13 @@ function(import_kconfig prefix kconfig_fragment) endforeach() endfunction() +function(get_image_name image out_var) + string(LENGTH ${image} len) + MATH(EXPR len "${len}-1") + string(SUBSTRING ${image} 0 ${len} ${out_var}) + set(${out_var} ${${out_var}} PARENT_SCOPE) +endfunction() + ######################################################## # 3. CMake-generic extensions ######################################################## @@ -1216,7 +1270,7 @@ endfunction() function(zephyr_link_interface_ifdef feature_toggle interface) if(${${feature_toggle}}) - target_link_libraries(${interface} INTERFACE zephyr_interface) + target_link_libraries(${interface} INTERFACE ${IMAGE}zephyr_interface) endif() endfunction() diff --git a/cmake/flash/CMakeLists.txt b/cmake/flash/CMakeLists.txt index 467b2d1284cec6..637236685978fd 100644 --- a/cmake/flash/CMakeLists.txt +++ b/cmake/flash/CMakeLists.txt @@ -113,15 +113,22 @@ foreach(target flash debug debugserver attach) WORKING_DIRECTORY ${APPLICATION_BINARY_DIR} ) - add_custom_target(${target} + add_custom_target(${IMAGE}${target} COMMAND ${cmd} COMMENT ${comment} USES_TERMINAL ) + elseif(WEST) + add_custom_target(${IMAGE}${target} + COMMAND ${CMAKE_COMMAND} -E echo \"West version found in path does not support + '${CMAKE_MAKE_PROGRAM} ${target}', ensure west is installed and not only + the bootstrapper. run 'west init' to fetch west.\" + USES_TERMINAL + ) else() - add_custom_target(${target} + add_custom_target(${IMAGE}${target} COMMAND ${CMAKE_COMMAND} -E echo \"West was not found in path. To support '${CMAKE_MAKE_PROGRAM} ${target}', please install west bootstrapper with: 'pip install west --user', and thereafter 'west init'.\" diff --git a/cmake/ide/eclipse_cdt4_generator_amendment.cmake b/cmake/ide/eclipse_cdt4_generator_amendment.cmake index 1bad729118e377..9179e4e4b77ab8 100644 --- a/cmake/ide/eclipse_cdt4_generator_amendment.cmake +++ b/cmake/ide/eclipse_cdt4_generator_amendment.cmake @@ -92,8 +92,8 @@ set(OUTPUT_FILE ${CMAKE_BINARY_DIR}/zephyr/include/generated/cmake_intdef.h) file(WRITE ${OUTPUT_FILE} "/* Generated by eclipse_cd4_generator_amendment.cmake */\n") file(APPEND ${OUTPUT_FILE} "/* The header contains the defines collected from the */\n") file(APPEND ${OUTPUT_FILE} "/* INTERFACE_COMPILE_DEFINITIONS target property */\n") -file(APPEND ${OUTPUT_FILE} "/* corresponding to zephyr_interface */\n") -get_target_property(_int_comp_def zephyr_interface INTERFACE_COMPILE_DEFINITIONS) +file(APPEND ${OUTPUT_FILE} "/* corresponding to ${IMAGE}zephyr_interface */\n") +get_target_property(_int_comp_def ${IMAGE}zephyr_interface INTERFACE_COMPILE_DEFINITIONS) foreach( d ${_int_comp_def} ) string(REGEX MATCH "([A-Za-z_][A-Za-z0-9_]*) *=* *(.*) *$" _dummy "${d}") file(APPEND ${OUTPUT_FILE} "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}\n") diff --git a/cmake/kconfig.cmake b/cmake/kconfig.cmake index 22a09a73590c81..e1788466a0ee0a 100644 --- a/cmake/kconfig.cmake +++ b/cmake/kconfig.cmake @@ -5,7 +5,7 @@ file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/generated) file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/kconfig/include/config) -if(KCONFIG_ROOT) +if(${IMAGE}KCONFIG_ROOT) # KCONFIG_ROOT has either been specified as a CMake variable or is # already in the CMakeCache.txt. This has precedence. elseif(EXISTS ${APPLICATION_SOURCE_DIR}/Kconfig) @@ -18,12 +18,12 @@ set(BOARD_DEFCONFIG ${BOARD_DIR}/${BOARD}_defconfig) set(DOTCONFIG ${PROJECT_BINARY_DIR}/.config) set(PARSED_KCONFIG_SOURCES_TXT ${PROJECT_BINARY_DIR}/kconfig/sources.txt) -if(CONF_FILE) -string(REPLACE " " ";" CONF_FILE_AS_LIST "${CONF_FILE}") +if(${IMAGE}CONF_FILE) +string(REPLACE " " ";" ${IMAGE}CONF_FILE_AS_LIST "${${IMAGE}CONF_FILE}") endif() -if(OVERLAY_CONFIG) - string(REPLACE " " ";" OVERLAY_CONFIG_AS_LIST "${OVERLAY_CONFIG}") +if(${IMAGE}OVERLAY_CONFIG) + string(REPLACE " " ";" ${IMAGE}OVERLAY_CONFIG_AS_LIST "${${IMAGE}OVERLAY_CONFIG}") endif() # DTS_ROOT_BINDINGS is a semicolon separated list, this causes @@ -71,7 +71,7 @@ foreach(kconfig_target ${EXTRA_KCONFIG_TARGETS} ) add_custom_target( - ${kconfig_target} + ${IMAGE}${kconfig_target} ${CMAKE_COMMAND} -E env PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} srctree=${ZEPHYR_BASE} @@ -101,16 +101,33 @@ endforeach() # user-testing. unset(EXTRA_KCONFIG_OPTIONS) get_cmake_property(cache_variable_names CACHE_VARIABLES) + +if ("${IMAGE}" STREQUAL "") + foreach (name ${cache_variable_names}) + if("${name}" MATCHES "^CONFIG_") + set(app_${name} ${${name}} CACHE STRING "") + unset(${name} CACHE) + endif() + endforeach() + set(KCONFIG_CACHE_IMAGE_PREFIX app_) +else() + set(KCONFIG_CACHE_IMAGE_PREFIX ${IMAGE}) +endif() + +get_cmake_property(cache_variable_names CACHE_VARIABLES) + foreach (name ${cache_variable_names}) - if("${name}" MATCHES "^CONFIG_") - # When a cache variable starts with 'CONFIG_', it is assumed to be + if("${name}" MATCHES "^${KCONFIG_CACHE_IMAGE_PREFIX}CONFIG_") + # When a cache variable starts with 'CONFIG_', it is assumed to be # a Kconfig symbol assignment from the CMake command line. + string(REPLACE "${KCONFIG_CACHE_IMAGE_PREFIX}" "" config_name ${name}) set(EXTRA_KCONFIG_OPTIONS - "${EXTRA_KCONFIG_OPTIONS}\n${name}=${${name}}" + "${EXTRA_KCONFIG_OPTIONS}\n${config_name}=${${name}}" ) endif() endforeach() +unset(EXTRA_KCONFIG_OPTIONS_FILE) if(EXTRA_KCONFIG_OPTIONS) set(EXTRA_KCONFIG_OPTIONS_FILE ${PROJECT_BINARY_DIR}/misc/generated/extra_kconfig_options.conf) file(WRITE @@ -126,9 +143,9 @@ list(SORT config_files) set( merge_config_files ${BOARD_DEFCONFIG} - ${CONF_FILE_AS_LIST} + ${${IMAGE}CONF_FILE_AS_LIST} ${shield_conf_files} - ${OVERLAY_CONFIG_AS_LIST} + ${${IMAGE}OVERLAY_CONFIG_AS_LIST} ${EXTRA_KCONFIG_OPTIONS_FILE} ${config_files} ) @@ -203,7 +220,7 @@ execute_process( ${merge_fragments} WORKING_DIRECTORY ${APPLICATION_SOURCE_DIR} # The working directory is set to the app dir such that the user - # can use relative paths in CONF_FILE, e.g. CONF_FILE=nrf5.conf + # can use relative paths in ${IMAGE}CONF_FILE, e.g. CONF_FILE=nrf5.conf RESULT_VARIABLE ret ) if(NOT "${ret}" STREQUAL "0") @@ -222,26 +239,17 @@ foreach(kconfig_input set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${kconfig_input}) endforeach() -add_custom_target(config-sanitycheck DEPENDS ${DOTCONFIG}) - -# Remove the CLI Kconfig symbols from the namespace and -# CMakeCache.txt. If the symbols end up in DOTCONFIG they will be -# re-introduced to the namespace through 'import_kconfig'. -foreach (name ${cache_variable_names}) - if("${name}" MATCHES "^CONFIG_") - unset(${name}) - unset(${name} CACHE) - endif() -endforeach() +add_custom_target(${IMAGE}config-sanitycheck DEPENDS ${DOTCONFIG}) # Parse the lines prefixed with CONFIG_ in the .config file from Kconfig import_kconfig(CONFIG_ ${DOTCONFIG}) -# Re-introduce the CLI Kconfig symbols that survived +# Clear CLI Kconfig symbols that were not set. foreach (name ${cache_variable_names}) - if("${name}" MATCHES "^CONFIG_") - if(DEFINED ${name}) - set(${name} ${${name}} CACHE STRING "") + if("${name}" MATCHES "^${KCONFIG_CACHE_IMAGE_PREFIX}CONFIG_") + string(REPLACE "${KCONFIG_CACHE_IMAGE_PREFIX}" "" config_name ${name}) + if(NOT DEFINED ${config_name}) + unset(${name} CACHE) endif() endif() endforeach() diff --git a/cmake/linker/ld/target.cmake b/cmake/linker/ld/target.cmake index 9523f4298545e1..6abdda9c63f325 100644 --- a/cmake/linker/ld/target.cmake +++ b/cmake/linker/ld/target.cmake @@ -27,8 +27,8 @@ macro(configure_linker_script linker_script_gen linker_pass_define) endif() zephyr_get_include_directories_for_lang(C current_includes) - get_filename_component(base_name ${CMAKE_CURRENT_BINARY_DIR} NAME) - get_property(current_defines GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES) + file(RELATIVE_PATH base_name "${CMAKE_BINARY_DIR}" "${PROJECT_BINARY_DIR}") + get_property(current_defines GLOBAL PROPERTY ${IMAGE}PROPERTY_LINKER_SCRIPT_DEFINES) add_custom_command( OUTPUT ${linker_script_gen} @@ -92,11 +92,11 @@ function(toolchain_ld_link_elf) ${LINKERFLAGPREFIX},--whole-archive ${ZEPHYR_LIBS_PROPERTY} ${LINKERFLAGPREFIX},--no-whole-archive - kernel + ${KERNEL_LIBRARY} $ - ${LIB_INCLUDE_DIR} + ${${IMAGE}LIB_INCLUDE_DIR} -L${PROJECT_BINARY_DIR} - ${TOOLCHAIN_LIBS} + ${${IMAGE}TOOLCHAIN_LIBS} ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} ) diff --git a/cmake/linker/ld/target_base.cmake b/cmake/linker/ld/target_base.cmake index a96c6d637c989f..8ca2adad677869 100644 --- a/cmake/linker/ld/target_base.cmake +++ b/cmake/linker/ld/target_base.cmake @@ -5,7 +5,7 @@ macro(toolchain_ld_base) if(NOT PROPERTY_LINKER_SCRIPT_DEFINES) - set_property(GLOBAL PROPERTY PROPERTY_LINKER_SCRIPT_DEFINES -D__GCC_LINKER_CMD__) + set_property(GLOBAL PROPERTY ${IMAGE}PROPERTY_LINKER_SCRIPT_DEFINES -D__GCC_LINKER_CMD__) endif() # TOOLCHAIN_LD_FLAGS comes from compiler/gcc/target.cmake diff --git a/cmake/linker/ld/target_relocation.cmake b/cmake/linker/ld/target_relocation.cmake index 076209a3ab26fb..0fcb0a8d9db804 100644 --- a/cmake/linker/ld/target_relocation.cmake +++ b/cmake/linker/ld/target_relocation.cmake @@ -17,14 +17,14 @@ macro(toolchain_ld_relocation) ${ZEPHYR_BASE}/scripts/gen_relocate_app.py $<$:--verbose> -d ${APPLICATION_BINARY_DIR} - -i '$' + -i '$' -o ${MEM_RELOCATION_LD} -s ${MEM_RELOCATION_SRAM_DATA_LD} -b ${MEM_RELOCATION_SRAM_BSS_LD} -c ${MEM_RELOCATION_CODE} - DEPENDS app kernel ${ZEPHYR_LIBS_PROPERTY} + DEPENDS ${IMAGE}app ${KERNEL_LIBRARY} ${ZEPHYR_LIBS_PROPERTY} ) - add_library(code_relocation_source_lib STATIC ${MEM_RELOCATION_CODE}) - target_link_libraries(code_relocation_source_lib zephyr_interface) + add_library(${IMAGE}code_relocation_source_lib STATIC ${MEM_RELOCATION_CODE}) + target_link_libraries(${IMAGE}code_relocation_source_lib ${IMAGE}zephyr_interface) endmacro() diff --git a/cmake/reports/CMakeLists.txt b/cmake/reports/CMakeLists.txt index 7c2140dc828fa5..8adedcd401de89 100644 --- a/cmake/reports/CMakeLists.txt +++ b/cmake/reports/CMakeLists.txt @@ -5,7 +5,7 @@ set(flag_for_rom_report -F) foreach(report ram_report rom_report) add_custom_target( - ${report} + ${IMAGE}${report} ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/footprint/size_report ${flag_for_${report}} diff --git a/cmake/usage/CMakeLists.txt b/cmake/usage/CMakeLists.txt deleted file mode 100644 index 5b042a47fe4f2b..00000000000000 --- a/cmake/usage/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -string(REPLACE ";" " " BOARD_ROOT_SPACE_SEPARATED "${BOARD_ROOT}") -string(REPLACE ";" " " SHIELD_LIST_SPACE_SEPARATED "${SHIELD_LIST}") - -add_custom_target( - usage - ${CMAKE_COMMAND} - -DBOARD_ROOT_SPACE_SEPARATED=${BOARD_ROOT_SPACE_SEPARATED} - -DSHIELD_LIST_SPACE_SEPARATED=${SHIELD_LIST_SPACE_SEPARATED} - -P ${CMAKE_CURRENT_SOURCE_DIR}/usage.cmake - ) - -# NB: The reason it is 'usage' and not help is that CMake already -# defines a target 'help' diff --git a/doc/application/index.rst b/doc/application/index.rst index db745696e3d008..fdd054d3f00fc6 100644 --- a/doc/application/index.rst +++ b/doc/application/index.rst @@ -1538,6 +1538,174 @@ After running the preprocessor, the final devicetree used in the build is created by running the devicetree compiler, ``dtc``, on the preprocessor output. +.. _application_multiple_images: + +Building and configuring multiple images +**************************************** + +When an embedded application includes functionality for firmware +updates or bootloaders, the final firmware that is programmed to +the device must usually consist of not one but multiple +executables that chain-load, or boot, each other. This section +describes how to build and configure such a Zephyr application. + +When and why to use multiple images +=================================== + +First off, you need a basic understanding of what exactly an +executable is and why we would want to have more than one. An +executable can be referred to by other names depending on context, +like program, image, or elf file. We will use the name *image*. You +probably have an idea of what an image is by reading the names, but if +not: An image consists of pieces of code and data that is identified +by image-unique names recorded in a single symbol table. The symbol +table exists as metadata in a ``.elf`` or ``.exe`` file and is not +included when the image is converted to a HEX file for +programming. Object files also consist of symbols, code, and data, but +object files are not images because unlike object files, images have +their code and data placed at addresses by a linker. In the end, it is +the linker that creates images. Therefore, if you want to determine if +you have zero, one, or more images, count the number of times the linker +has been run. + +From this definition, using two images gives you two opportunities: +Firstly, it allows you to run the linker multiple times and in this +process partition the final firmware into several regions, something +that is often desired by bootloaders. And secondly, since there are +multiple symbol tables, it allows the same symbol name to exist +multiple times in the final firmware. This again is useful for +bootloader images, as they often need to have their own fixed copies +of the same libraries that the application image is using. + +Enabling and configuring multiple images +======================================== + +Images are organized in a tree of parent-child relationships, which +means that a parent image requires one or more child images and +enables them through Kconfig. Usually, the tree is branchless: a +linked list of images where each image enables the child image that +boots it. The simplest and most common organization is a single +application image that enables a single bootloader image. + +When a parent image enables a child image through Kconfig, both images are +configured when CMake is run. +When configuring the parent image, you can decide how the child image +should be handled: + +* Build the child image from source while building the parent image. +* Use a prebuilt HEX file of the child image. +* Ignore the child image. + +When building the child image from source or using a prebuilt HEX +file, the build system will merge the HEX files of the parent and +child image together so that they can easily be programmed using +the ``ninja flash`` target. This means that in the simplest scenario, +it is possible to enable and integrate an additional image without +even realizing it, using the same workflow as for additional +libraries, namely enabling through Kconfig. + +Child images are configured with the same mechanisms as parent +images: through CMake variables, Kconfig input fragments, and by +modifying the ``.config`` file in the build directory. For example, to +change the CONF_FILE for the MCUBoot image and the parent image, you +could run the following command:: + + cmake -Dmcuboot_CONF_FILE=prj_a.conf -DCONF_FILE=app_prj.conf + +If you check the CONF_FILE, you can see that all CMake Cache +variables that are image-specific are given a prefix to disambiguate +them. To simplify configuation of single-image builds, the top-level +image has the empty string as its prefix. + +The same prefix convention is used to disambiguate targets. This means +that to run menuconfig, for example, you can simply invoke the +``menuconfig`` target to configure the top-level image and +``mcuboot_menuconfig`` to configure the MCUBoot child image. + +.. _application_defining_child_images: + +Defining new child images +========================= + +This section describes how to take an existing parent image and turn +it into a child image that can be enabled. A parent image typically +consists of source code, Kconfig fragments, and build script code. The +source code and Kconfig fragments can be reused as-is, but several +changes to the build scripts are necessary. + +As mentioned earlier, each target needs a prefix for disambiguation. This +includes the library target ``app``, so any references to ``app`` must +be changed to ``${IMAGE}app``. Or, even better, you could use +the ``zephyr_library_*`` API instead of the ``target_*`` API to indirectly +modify ``${IMAGE}app``. + +After the application build scripts have been ported, we need some +build scripts as shown below to connect the build scripts of the +parent and child. This code should be placed somewhere in-tree that is +conditional on a Kconfig option for having the parent image use the +child image. + +.. code-block:: cmake + + set(child_image_name mcuboot) + zephyr_add_executable(${child_image_name} require_build) + + set(build_directory ${CMAKE_CURRENT_BINARY_DIR}/mcuboot + set(child_image_application_directory ${MCUBOOT_BASE}/boot/zephyr) + + if(${require_build}) + add_subdirectory(${child_image_application_directory} ${build_directory}) + endif() + +In the above code, ``zephyr_add_executable`` registers the child image as +present in the build, and ``add_subdirectory`` actually executes the +child's build scripts. Note that in addition to the child image's +application build scripts being executed, most of the core build +scripts are executed for a second time as well, but now with a +different Kconfig configuration and possibly DeviceTree settings. + +Some Kconfig options must be added to allow the parent image to choose how to +include the child image. The three options are: + +1. Build from source. +#. Include as HEX file. +#. Skip building entirely. + +The first option will result in the child image being built from +source alongside the parent image. Option 2 requires a prebuilt HEX +file to be specified in Kconfig, which will be merged with the parent +image HEX file. Option 3 will cause the child image to not be built. These options are shown below for MCUBoot. + +.. code-block:: Kconfig + + choice + prompt "MCUBoot build strategy" + default MCUBOOT_BUILD_STRATEGY_FROM_SOURCE + + config MCUBOOT_BUILD_STRATEGY_USE_HEX_FILE + # Mandatory option when being built through 'zephyr_add_executable' + bool "Use hex file instead of building MCUBoot" + + if MCUBOOT_BUILD_STRATEGY_USE_HEX_FILE + + config MCUBOOT_HEX_FILE + # Mandatory option when being built through 'zephyr_add_executable' + string "MCUBoot hex file" + + endif # MCUBOOT_USE_HEX_FILE + + config MCUBOOT_BUILD_STRATEGY_SKIP_BUILD + # Mandatory option when being built through 'zephyr_add_executable' + bool "Skip building MCUBoot" + + config MCUBOOT_BUILD_STRATEGY_FROM_SOURCE + # Mandatory option when being built through 'zephyr_add_executable' + bool "Build from source" + + endchoice + + + Application-Specific Code ************************* diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 988df63371adfd..7c70a210e645fd 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -2,7 +2,7 @@ # kernel is a normal CMake library and not a zephyr_library because it # should not be --whole-archive'd -add_library(kernel +add_library(${KERNEL_LIBRARY} device.c errno.c fatal.c @@ -29,16 +29,16 @@ add_library(kernel # Kernel files has the macro __ZEPHYR_SUPERVISOR__ set so that it # optimizes the code when userspace is enabled. set_target_properties( - kernel + ${KERNEL_LIBRARY} PROPERTIES COMPILE_DEFINITIONS __ZEPHYR_SUPERVISOR__ ) -target_sources_ifdef(CONFIG_STACK_CANARIES kernel PRIVATE compiler_stack_protect.c) -target_sources_ifdef(CONFIG_SYS_CLOCK_EXISTS kernel PRIVATE timeout.c timer.c) -target_sources_ifdef(CONFIG_ATOMIC_OPERATIONS_C kernel PRIVATE atomic_c.c) -target_sources_if_kconfig( kernel PRIVATE poll.c) +target_sources_ifdef(CONFIG_STACK_CANARIES ${KERNEL_LIBRARY} PRIVATE compiler_stack_protect.c) +target_sources_ifdef(CONFIG_SYS_CLOCK_EXISTS ${KERNEL_LIBRARY} PRIVATE timeout.c timer.c) +target_sources_ifdef(CONFIG_ATOMIC_OPERATIONS_C ${KERNEL_LIBRARY} PRIVATE atomic_c.c) +target_sources_if_kconfig( ${KERNEL_LIBRARY} PRIVATE poll.c) # The last 2 files inside the target_sources_ifdef should be # userspace_handler.c and userspace.c. If not the linker would complain. @@ -46,7 +46,7 @@ target_sources_if_kconfig( kernel PRIVATE poll.c) # above these 2 files. target_sources_ifdef( CONFIG_USERSPACE - kernel PRIVATE + ${KERNEL_LIBRARY} PRIVATE futex.c mem_domain.c userspace_handler.c @@ -58,6 +58,6 @@ target_include_directories(kernel PRIVATE ${ZEPHYR_BASE}/arch/${ARCH}/include ) -add_dependencies(kernel ${OFFSETS_H_TARGET}) +add_dependencies(${KERNEL_LIBRARY} ${OFFSETS_H_TARGET}) -target_link_libraries(kernel zephyr_interface) +target_link_libraries(${KERNEL_LIBRARY} ${IMAGE}zephyr_interface) diff --git a/samples/subsys/ipc/ipm_mcux/CMakeLists.txt b/samples/subsys/ipc/ipm_mcux/CMakeLists.txt index 4b7fb8118848f0..e69eec0277e42c 100644 --- a/samples/subsys/ipc/ipm_mcux/CMakeLists.txt +++ b/samples/subsys/ipc/ipm_mcux/CMakeLists.txt @@ -24,4 +24,4 @@ ExternalProject_Add( project(ipm_mcux) target_sources(app PRIVATE src/main_master.c) -add_dependencies(core_m0_inc_target ipm_mcux_remote) +add_dependencies(${IMAGE}core_m0_inc_target ipm_mcux_remote) diff --git a/samples/subsys/ipc/openamp/CMakeLists.txt b/samples/subsys/ipc/openamp/CMakeLists.txt index fe0456425bc519..399f7dc5c77d5a 100644 --- a/samples/subsys/ipc/openamp/CMakeLists.txt +++ b/samples/subsys/ipc/openamp/CMakeLists.txt @@ -25,6 +25,6 @@ ExternalProject_Add( BUILD_BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/openamp_remote-prefix/src/openamp_remote-build/zephyr/zephyr.bin" # NB: Do we need to pass on more CMake variables? ) -add_dependencies(core_m0_inc_target openamp_remote) +add_dependencies(${IMAGE}core_m0_inc_target openamp_remote) target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/soc/arm/nxp_lpc/lpc54xxx/CMakeLists.txt b/soc/arm/nxp_lpc/lpc54xxx/CMakeLists.txt index 6f78f98e39e80e..e003f421433ccc 100644 --- a/soc/arm/nxp_lpc/lpc54xxx/CMakeLists.txt +++ b/soc/arm/nxp_lpc/lpc54xxx/CMakeLists.txt @@ -18,10 +18,10 @@ if (CONFIG_SLAVE_CORE_MCUX) set(gen_dir ${ZEPHYR_BINARY_DIR}/include/generated/) string(CONFIGURE ${CONFIG_SLAVE_IMAGE_MCUX} core_m0_image) - add_custom_target(core_m0_inc_target DEPENDS ${gen_dir}/core-m0.inc) + add_custom_target(${IMAGE}core_m0_inc_target DEPENDS ${gen_dir}/core-m0.inc) generate_inc_file_for_gen_target(${ZEPHYR_CURRENT_LIBRARY} ${core_m0_image} ${gen_dir}/core-m0.inc - core_m0_inc_target) + ${IMAGE}core_m0_inc_target) endif() diff --git a/subsys/bluetooth/CMakeLists.txt b/subsys/bluetooth/CMakeLists.txt index 4cac45c2e0c019..6a8a34705dc9b7 100644 --- a/subsys/bluetooth/CMakeLists.txt +++ b/subsys/bluetooth/CMakeLists.txt @@ -1,8 +1,8 @@ # SPDX-License-Identifier: Apache-2.0 -add_library(subsys__bluetooth INTERFACE) +add_library(${IMAGE}subsys__bluetooth INTERFACE) -target_include_directories(subsys__bluetooth INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(${IMAGE}subsys__bluetooth INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) add_subdirectory(common) add_subdirectory_ifdef(CONFIG_BT_HCI host) diff --git a/subsys/bluetooth/common/CMakeLists.txt b/subsys/bluetooth/common/CMakeLists.txt index 059a0d6ab1255e..a0d6656219e8d9 100644 --- a/subsys/bluetooth/common/CMakeLists.txt +++ b/subsys/bluetooth/common/CMakeLists.txt @@ -7,4 +7,4 @@ zephyr_library_sources(log.c) zephyr_library_sources_ifdef(CONFIG_BT_RPA rpa.c) -zephyr_library_link_libraries(subsys__bluetooth) +zephyr_library_link_libraries(${IMAGE}subsys__bluetooth) diff --git a/subsys/bluetooth/controller/CMakeLists.txt b/subsys/bluetooth/controller/CMakeLists.txt index b10998087f3bd7..daad6c0bf6e1f2 100644 --- a/subsys/bluetooth/controller/CMakeLists.txt +++ b/subsys/bluetooth/controller/CMakeLists.txt @@ -226,4 +226,4 @@ zephyr_library_compile_options_ifdef( ${OPTIMIZE_FOR_SPEED_FLAG} ) -zephyr_library_link_libraries(subsys__bluetooth) +zephyr_library_link_libraries(${IMAGE}subsys__bluetooth) diff --git a/subsys/bluetooth/host/CMakeLists.txt b/subsys/bluetooth/host/CMakeLists.txt index 5edfb9491b8726..ce915889da9b76 100644 --- a/subsys/bluetooth/host/CMakeLists.txt +++ b/subsys/bluetooth/host/CMakeLists.txt @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library() -zephyr_library_link_libraries(subsys__bluetooth) +zephyr_library_link_libraries(${IMAGE}subsys__bluetooth) zephyr_library_sources_ifdef(CONFIG_BT_HCI_RAW hci_raw.c) zephyr_library_sources_ifdef(CONFIG_BT_DEBUG_MONITOR monitor.c) diff --git a/subsys/bluetooth/mesh/CMakeLists.txt b/subsys/bluetooth/mesh/CMakeLists.txt index 3a286f7854bbca..7262eda8b2fb04 100644 --- a/subsys/bluetooth/mesh/CMakeLists.txt +++ b/subsys/bluetooth/mesh/CMakeLists.txt @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library() -zephyr_library_link_libraries(subsys__bluetooth) +zephyr_library_link_libraries(${IMAGE}subsys__bluetooth) zephyr_library_sources_ifdef(CONFIG_BT_MESH main.c