|
|
@@ -5,170 +5,174 @@
|
|
|
# component_paths contains only unique component names. Directories
|
|
|
# earlier in the component_dirs list take precedence.
|
|
|
function(components_find_all component_dirs filter_names component_paths component_names)
|
|
|
- # component_dirs entries can be files or lists of files
|
|
|
- set(paths "")
|
|
|
- set(names "")
|
|
|
-
|
|
|
- # start by expanding the component_dirs list with all subdirectories
|
|
|
- foreach(dir ${component_dirs})
|
|
|
- # Iterate any subdirectories for values
|
|
|
- file(GLOB subdirs LIST_DIRECTORIES true "${dir}/*")
|
|
|
- foreach(subdir ${subdirs})
|
|
|
- set(component_dirs "${component_dirs};${subdir}")
|
|
|
+ # component_dirs entries can be files or lists of files
|
|
|
+ set(paths "")
|
|
|
+ set(names "")
|
|
|
+
|
|
|
+ # start by expanding the component_dirs list with all subdirectories
|
|
|
+ foreach(dir ${component_dirs})
|
|
|
+ # Iterate any subdirectories for values
|
|
|
+ file(GLOB subdirs LIST_DIRECTORIES true "${dir}/*")
|
|
|
+ foreach(subdir ${subdirs})
|
|
|
+ set(component_dirs "${component_dirs};${subdir}")
|
|
|
+ endforeach()
|
|
|
endforeach()
|
|
|
- endforeach()
|
|
|
-
|
|
|
- # Look for a component in each component_dirs entry
|
|
|
- foreach(dir ${component_dirs})
|
|
|
- file(GLOB component "${dir}/CMakeLists.txt")
|
|
|
- if(component)
|
|
|
- get_filename_component(component "${component}" DIRECTORY)
|
|
|
- get_filename_component(name "${component}" NAME)
|
|
|
- if(NOT filter_names OR (name IN_LIST filter_names))
|
|
|
- if(NOT name IN_LIST names)
|
|
|
- set(names "${names};${name}")
|
|
|
- set(paths "${paths};${component}")
|
|
|
- endif()
|
|
|
- endif()
|
|
|
|
|
|
- else() # no CMakeLists.txt file
|
|
|
- # test for legacy component.mk and warn
|
|
|
- file(GLOB legacy_component "${dir}/component.mk")
|
|
|
- if(legacy_component)
|
|
|
- get_filename_component(legacy_component "${legacy_component}" DIRECTORY)
|
|
|
- message(WARNING "Component ${legacy_component} contains old-style component.mk but no CMakeLists.txt. Component will be skipped.")
|
|
|
- endif()
|
|
|
- endif(component)
|
|
|
+ # Look for a component in each component_dirs entry
|
|
|
+ foreach(dir ${component_dirs})
|
|
|
+ file(GLOB component "${dir}/CMakeLists.txt")
|
|
|
+ if(component)
|
|
|
+ get_filename_component(component "${component}" DIRECTORY)
|
|
|
+ get_filename_component(name "${component}" NAME)
|
|
|
+ if(NOT filter_names OR (name IN_LIST filter_names))
|
|
|
+ if(NOT name IN_LIST names)
|
|
|
+ set(names "${names};${name}")
|
|
|
+ set(paths "${paths};${component}")
|
|
|
+ endif()
|
|
|
+ endif()
|
|
|
+
|
|
|
+ else() # no CMakeLists.txt file
|
|
|
+ # test for legacy component.mk and warn
|
|
|
+ file(GLOB legacy_component "${dir}/component.mk")
|
|
|
+ if(legacy_component)
|
|
|
+ get_filename_component(legacy_component "${legacy_component}" DIRECTORY)
|
|
|
+ message(WARNING "Component ${legacy_component} contains old-style component.mk but no CMakeLists.txt. "
|
|
|
+ "Component will be skipped.")
|
|
|
+ endif()
|
|
|
+ endif()
|
|
|
|
|
|
- endforeach(dir ${component_dirs})
|
|
|
+ endforeach()
|
|
|
|
|
|
- set(${component_paths} ${paths} PARENT_SCOPE)
|
|
|
- set(${component_names} ${names} PARENT_SCOPE)
|
|
|
-endfunction(components_find_all)
|
|
|
+ set(${component_paths} ${paths} PARENT_SCOPE)
|
|
|
+ set(${component_names} ${names} PARENT_SCOPE)
|
|
|
+endfunction()
|
|
|
|
|
|
|
|
|
# Add a component to the build, using the COMPONENT variables defined
|
|
|
# in the parent
|
|
|
#
|
|
|
function(register_component)
|
|
|
- get_filename_component(component_dir ${CMAKE_CURRENT_LIST_FILE} DIRECTORY)
|
|
|
- get_filename_component(component ${component_dir} NAME)
|
|
|
-
|
|
|
- spaces2list(COMPONENT_SRCDIRS)
|
|
|
- spaces2list(COMPONENT_ADD_INCLUDEDIRS)
|
|
|
-
|
|
|
- # Add to COMPONENT_SRCS by globbing in COMPONENT_SRCDIRS
|
|
|
- if(NOT COMPONENT_SRCS)
|
|
|
- foreach(dir ${COMPONENT_SRCDIRS})
|
|
|
- get_filename_component(abs_dir ${dir} ABSOLUTE BASE_DIR ${component_dir})
|
|
|
- if(NOT IS_DIRECTORY ${abs_dir})
|
|
|
- message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_SRCDIRS entry '${dir}' does not exist")
|
|
|
- endif()
|
|
|
-
|
|
|
- file(GLOB matches "${abs_dir}/*.c" "${abs_dir}/*.cpp" "${abs_dir}/*.S")
|
|
|
- if(matches)
|
|
|
- list(SORT matches)
|
|
|
- set(COMPONENT_SRCS "${COMPONENT_SRCS};${matches}")
|
|
|
- else()
|
|
|
- message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_SRCDIRS entry '${dir}' contains no source files")
|
|
|
- endif(matches)
|
|
|
- endforeach()
|
|
|
- endif()
|
|
|
-
|
|
|
- # add public includes from other components when building this component
|
|
|
- if(COMPONENT_SRCS OR embed_binaries)
|
|
|
- add_library(${component} STATIC ${COMPONENT_SRCS})
|
|
|
- set(include_type PUBLIC)
|
|
|
- else()
|
|
|
- add_library(${component} INTERFACE) # header-only component
|
|
|
- set(include_type INTERFACE)
|
|
|
- endif()
|
|
|
-
|
|
|
- # binaries to embed directly in library
|
|
|
- spaces2list(COMPONENT_EMBED_FILES)
|
|
|
- spaces2list(COMPONENT_EMBED_TXTFILES)
|
|
|
- foreach(embed_data ${COMPONENT_EMBED_FILES} ${COMPONENT_EMBED_TXTFILES})
|
|
|
- if (embed_data IN_LIST COMPONENT_EMBED_TXTFILES)
|
|
|
- set(embed_type "TEXT")
|
|
|
- else()
|
|
|
- set(embed_type "BINARY")
|
|
|
- endif()
|
|
|
- target_add_binary_data("${component}" "${embed_data}" "${embed_type}")
|
|
|
- endforeach()
|
|
|
-
|
|
|
- # add public includes
|
|
|
- foreach(include_dir ${COMPONENT_ADD_INCLUDEDIRS})
|
|
|
- get_filename_component(abs_dir ${include_dir} ABSOLUTE BASE_DIR ${component_dir})
|
|
|
- if(NOT IS_DIRECTORY ${abs_dir})
|
|
|
- message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_ADD_INCLUDEDIRS entry '${include_dir}' does not exist")
|
|
|
- endif()
|
|
|
- target_include_directories(${component} ${include_type} ${abs_dir})
|
|
|
- endforeach()
|
|
|
+ get_filename_component(component_dir ${CMAKE_CURRENT_LIST_FILE} DIRECTORY)
|
|
|
+ get_filename_component(component ${component_dir} NAME)
|
|
|
+
|
|
|
+ spaces2list(COMPONENT_SRCDIRS)
|
|
|
+ spaces2list(COMPONENT_ADD_INCLUDEDIRS)
|
|
|
+
|
|
|
+ # Add to COMPONENT_SRCS by globbing in COMPONENT_SRCDIRS
|
|
|
+ if(NOT COMPONENT_SRCS)
|
|
|
+ foreach(dir ${COMPONENT_SRCDIRS})
|
|
|
+ get_filename_component(abs_dir ${dir} ABSOLUTE BASE_DIR ${component_dir})
|
|
|
+ if(NOT IS_DIRECTORY ${abs_dir})
|
|
|
+ message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_SRCDIRS entry '${dir}' does not exist")
|
|
|
+ endif()
|
|
|
|
|
|
- # add private includes
|
|
|
- foreach(include_dir ${COMPONENT_PRIV_INCLUDEDIRS})
|
|
|
- if (${include_type} STREQUAL INTERFACE)
|
|
|
- message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE} sets no component source files but sets COMPONENT_PRIV_INCLUDEDIRS")
|
|
|
+ file(GLOB matches "${abs_dir}/*.c" "${abs_dir}/*.cpp" "${abs_dir}/*.S")
|
|
|
+ if(matches)
|
|
|
+ list(SORT matches)
|
|
|
+ set(COMPONENT_SRCS "${COMPONENT_SRCS};${matches}")
|
|
|
+ else()
|
|
|
+ message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_SRCDIRS entry '${dir}' has no source files")
|
|
|
+ endif()
|
|
|
+ endforeach()
|
|
|
endif()
|
|
|
|
|
|
- get_filename_component(abs_dir ${include_dir} ABSOLUTE BASE_DIR ${component_dir})
|
|
|
- if(NOT IS_DIRECTORY ${abs_dir})
|
|
|
- message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: COMPONENT_PRIV_INCLUDEDIRS entry '${niclude_dir}' does not exist")
|
|
|
+ # add public includes from other components when building this component
|
|
|
+ if(COMPONENT_SRCS OR embed_binaries)
|
|
|
+ add_library(${component} STATIC ${COMPONENT_SRCS})
|
|
|
+ set(include_type PUBLIC)
|
|
|
+ else()
|
|
|
+ add_library(${component} INTERFACE) # header-only component
|
|
|
+ set(include_type INTERFACE)
|
|
|
endif()
|
|
|
- target_include_directories(${component} PRIVATE ${abs_dir})
|
|
|
- endforeach()
|
|
|
|
|
|
-endfunction(register_component)
|
|
|
+ # binaries to embed directly in library
|
|
|
+ spaces2list(COMPONENT_EMBED_FILES)
|
|
|
+ spaces2list(COMPONENT_EMBED_TXTFILES)
|
|
|
+ foreach(embed_data ${COMPONENT_EMBED_FILES} ${COMPONENT_EMBED_TXTFILES})
|
|
|
+ if(embed_data IN_LIST COMPONENT_EMBED_TXTFILES)
|
|
|
+ set(embed_type "TEXT")
|
|
|
+ else()
|
|
|
+ set(embed_type "BINARY")
|
|
|
+ endif()
|
|
|
+ target_add_binary_data("${component}" "${embed_data}" "${embed_type}")
|
|
|
+ endforeach()
|
|
|
+
|
|
|
+ # add public includes
|
|
|
+ foreach(include_dir ${COMPONENT_ADD_INCLUDEDIRS})
|
|
|
+ get_filename_component(abs_dir ${include_dir} ABSOLUTE BASE_DIR ${component_dir})
|
|
|
+ if(NOT IS_DIRECTORY ${abs_dir})
|
|
|
+ message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: "
|
|
|
+ "COMPONENT_ADD_INCLUDEDIRS entry '${include_dir}' not found")
|
|
|
+ endif()
|
|
|
+ target_include_directories(${component} ${include_type} ${abs_dir})
|
|
|
+ endforeach()
|
|
|
+
|
|
|
+ # add private includes
|
|
|
+ foreach(include_dir ${COMPONENT_PRIV_INCLUDEDIRS})
|
|
|
+ if(${include_type} STREQUAL INTERFACE)
|
|
|
+ message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE} "
|
|
|
+ "sets no component source files but sets COMPONENT_PRIV_INCLUDEDIRS")
|
|
|
+ endif()
|
|
|
+
|
|
|
+ get_filename_component(abs_dir ${include_dir} ABSOLUTE BASE_DIR ${component_dir})
|
|
|
+ if(NOT IS_DIRECTORY ${abs_dir})
|
|
|
+ message(FATAL_ERROR "${CMAKE_CURRENT_LIST_FILE}: "
|
|
|
+ "COMPONENT_PRIV_INCLUDEDIRS entry '${include_dir}' does not exist")
|
|
|
+ endif()
|
|
|
+ target_include_directories(${component} PRIVATE ${abs_dir})
|
|
|
+ endforeach()
|
|
|
+
|
|
|
+endfunction()
|
|
|
|
|
|
function(register_config_only_component)
|
|
|
- get_filename_component(component_dir ${CMAKE_CURRENT_LIST_FILE} DIRECTORY)
|
|
|
- get_filename_component(component ${component_dir} NAME)
|
|
|
+ get_filename_component(component_dir ${CMAKE_CURRENT_LIST_FILE} DIRECTORY)
|
|
|
+ get_filename_component(component ${component_dir} NAME)
|
|
|
|
|
|
- # No-op for now...
|
|
|
-endfunction(register_config_only_component)
|
|
|
+ # No-op for now...
|
|
|
+endfunction()
|
|
|
|
|
|
function(components_finish_registration)
|
|
|
- # each component should see the include directories of each other
|
|
|
- #
|
|
|
- # (we can't do this until all components are registered, because if(TARGET ...) won't work
|
|
|
- foreach(a ${COMPONENTS} ${CMAKE_PROJECT_NAME}.elf)
|
|
|
- if (TARGET ${a})
|
|
|
- get_target_property(a_imported ${a} IMPORTED)
|
|
|
- get_target_property(a_type ${a} TYPE)
|
|
|
- if (NOT a_imported)
|
|
|
- if (${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
|
|
|
- foreach(b ${COMPONENTS})
|
|
|
- if (TARGET ${b} AND NOT ${a} STREQUAL ${b})
|
|
|
- # Add all public compile options from b in a
|
|
|
- target_include_directories(${a} PRIVATE
|
|
|
- $<TARGET_PROPERTY:${b},INTERFACE_INCLUDE_DIRECTORIES>)
|
|
|
- target_compile_definitions(${a} PRIVATE
|
|
|
- $<TARGET_PROPERTY:${b},INTERFACE_COMPILE_DEFINITIONS>)
|
|
|
- target_compile_options(${a} PRIVATE
|
|
|
- $<TARGET_PROPERTY:${b},INTERFACE_COMPILE_OPTIONS>)
|
|
|
+ # each component should see the include directories of each other
|
|
|
+ #
|
|
|
+ # (we can't do this until all components are registered, because if(TARGET ...) won't work
|
|
|
+ foreach(a ${COMPONENTS} ${CMAKE_PROJECT_NAME}.elf)
|
|
|
+ if(TARGET ${a})
|
|
|
+ get_target_property(a_imported ${a} IMPORTED)
|
|
|
+ get_target_property(a_type ${a} TYPE)
|
|
|
+ if(NOT a_imported)
|
|
|
+ if(${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
|
|
|
+ foreach(b ${COMPONENTS})
|
|
|
+ if(TARGET ${b} AND NOT ${a} STREQUAL ${b})
|
|
|
+ # Add all public compile options from b in a
|
|
|
+ target_include_directories(${a} PRIVATE
|
|
|
+ $<TARGET_PROPERTY:${b},INTERFACE_INCLUDE_DIRECTORIES>)
|
|
|
+ target_compile_definitions(${a} PRIVATE
|
|
|
+ $<TARGET_PROPERTY:${b},INTERFACE_COMPILE_DEFINITIONS>)
|
|
|
+ target_compile_options(${a} PRIVATE
|
|
|
+ $<TARGET_PROPERTY:${b},INTERFACE_COMPILE_OPTIONS>)
|
|
|
+ endif()
|
|
|
+ endforeach(b)
|
|
|
+ endif()
|
|
|
endif()
|
|
|
- endforeach(b)
|
|
|
- endif(${a_type} STREQUAL STATIC_LIBRARY OR ${a_type} STREQUAL EXECUTABLE)
|
|
|
- endif(NOT a_imported)
|
|
|
|
|
|
- if (${a_type} MATCHES .+_LIBRARY)
|
|
|
- set(COMPONENT_LIBRARIES "${COMPONENT_LIBRARIES};${a}")
|
|
|
- endif()
|
|
|
- endif()
|
|
|
- endforeach()
|
|
|
+ if(${a_type} MATCHES .+_LIBRARY)
|
|
|
+ set(COMPONENT_LIBRARIES "${COMPONENT_LIBRARIES};${a}")
|
|
|
+ endif()
|
|
|
+ endif()
|
|
|
+ endforeach()
|
|
|
|
|
|
- # Embedded binary & text files
|
|
|
- spaces2list(COMPONENT_EMBED_FILES)
|
|
|
- foreach(embed_src ${COMPONENT_EMBED_FILES})
|
|
|
- target_add_binary_data(${component} "${embed_src}" BINARY)
|
|
|
- endforeach()
|
|
|
- spaces2list(COMPONENT_EMBED_TXTFILES)
|
|
|
- foreach(embed_src ${COMPONENT_EMBED_TXTFILES})
|
|
|
- target_add_binary_data(${component} "${embed_src}" TEXT)
|
|
|
- endforeach()
|
|
|
+ # Embedded binary & text files
|
|
|
+ spaces2list(COMPONENT_EMBED_FILES)
|
|
|
+ foreach(embed_src ${COMPONENT_EMBED_FILES})
|
|
|
+ target_add_binary_data(${component} "${embed_src}" BINARY)
|
|
|
+ endforeach()
|
|
|
+ spaces2list(COMPONENT_EMBED_TXTFILES)
|
|
|
+ foreach(embed_src ${COMPONENT_EMBED_TXTFILES})
|
|
|
+ target_add_binary_data(${component} "${embed_src}" TEXT)
|
|
|
+ endforeach()
|
|
|
|
|
|
- target_link_libraries(${CMAKE_PROJECT_NAME}.elf ${COMPONENT_LIBRARIES})
|
|
|
+ target_link_libraries(${CMAKE_PROJECT_NAME}.elf ${COMPONENT_LIBRARIES})
|
|
|
|
|
|
- message(STATUS "Component libraries: ${COMPONENT_LIBRARIES}")
|
|
|
+ message(STATUS "Component libraries: ${COMPONENT_LIBRARIES}")
|
|
|
|
|
|
-endfunction(components_finish_registration)
|
|
|
+endfunction()
|