cmake: Change the zephyr_get_* API to be LANG-aware
When exporting flags to an external build system we need to deal with the fact that we sometimes use generator expressions. Specifically, we use generator expressions that look like this: $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions> This patch replaces the old API with a new one where users can ask for compile options for specific languages, like this: zephyr_get_compile_options_for_lang_as_string(CXX x) The existing API would have either crashed or silently omitted flags when a COMPILE_LANG generator expression was present. Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
This commit is contained in:
parent
b277d3b081
commit
89516fbc25
|
@ -359,7 +359,7 @@ add_custom_target(offsets_h DEPENDS ${OFFSETS_H_PATH})
|
|||
|
||||
zephyr_include_directories(${TOOLCHAIN_INCLUDES})
|
||||
|
||||
zephyr_get_include_directories(ZEPHYR_INCLUDES)
|
||||
zephyr_get_include_directories_for_lang(C ZEPHYR_INCLUDES)
|
||||
|
||||
add_subdirectory(kernel)
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ endfunction()
|
|||
# includes, options).
|
||||
#
|
||||
# The naming convention follows:
|
||||
# zephyr_get_${build_information}${format}(x)
|
||||
# zephyr_get_${build_information}_for_lang${format}(lang x)
|
||||
# Where
|
||||
# the argument 'x' is written with the result
|
||||
# and
|
||||
|
@ -128,14 +128,133 @@ endfunction()
|
|||
# - compile_options # misc. compiler flags
|
||||
# and
|
||||
# ${format} can be
|
||||
# the empty string '', signifying that it should be returned as a list
|
||||
# _as_string signifying that it should be returned as a string
|
||||
# - the empty string '', signifying that it should be returned as a list
|
||||
# - _as_string signifying that it should be returned as a string
|
||||
# and
|
||||
# ${lang} can be one of
|
||||
# - C
|
||||
# - CXX
|
||||
# - ASM
|
||||
#
|
||||
# e.g.
|
||||
# zephyr_get_include_directories(x)
|
||||
# zephyr_get_include_directories_for_lang(ASM x)
|
||||
# writes "-Isome_dir;-Isome/other/dir" to x
|
||||
|
||||
# Utility macro used by the below macros.
|
||||
function(zephyr_get_include_directories_for_lang_as_string lang i)
|
||||
zephyr_get_include_directories_for_lang(${lang} list_of_flags)
|
||||
|
||||
convert_list_of_flags_to_string_of_flags(list_of_flags str_of_flags)
|
||||
|
||||
set(${i} ${str_of_flags} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(zephyr_get_system_include_directories_for_lang_as_string lang i)
|
||||
zephyr_get_system_include_directories_for_lang(${lang} list_of_flags)
|
||||
|
||||
convert_list_of_flags_to_string_of_flags(list_of_flags str_of_flags)
|
||||
|
||||
set(${i} ${str_of_flags} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(zephyr_get_compile_definitions_for_lang_as_string lang i)
|
||||
zephyr_get_compile_definitions_for_lang(${lang} list_of_flags)
|
||||
|
||||
convert_list_of_flags_to_string_of_flags(list_of_flags str_of_flags)
|
||||
|
||||
set(${i} ${str_of_flags} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(zephyr_get_compile_options_for_lang_as_string lang i)
|
||||
zephyr_get_compile_options_for_lang(${lang} list_of_flags)
|
||||
|
||||
convert_list_of_flags_to_string_of_flags(list_of_flags str_of_flags)
|
||||
|
||||
set(${i} ${str_of_flags} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(zephyr_get_include_directories_for_lang lang i)
|
||||
get_property_and_add_prefix(flags zephyr_interface INTERFACE_INCLUDE_DIRECTORIES -I)
|
||||
|
||||
process_flags(${lang} flags output_list)
|
||||
|
||||
set(${i} ${output_list} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(zephyr_get_system_include_directories_for_lang lang i)
|
||||
get_property_and_add_prefix(flags zephyr_interface INTERFACE_SYSTEM_INCLUDE_DIRECTORIES -isystem)
|
||||
|
||||
process_flags(${lang} flags output_list)
|
||||
|
||||
set(${i} ${output_list} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(zephyr_get_compile_definitions_for_lang lang i)
|
||||
get_property_and_add_prefix(flags zephyr_interface INTERFACE_COMPILE_DEFINITIONS -D)
|
||||
|
||||
process_flags(${lang} flags output_list)
|
||||
|
||||
set(${i} ${output_list} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(zephyr_get_compile_options_for_lang lang i)
|
||||
get_property(flags TARGET zephyr_interface PROPERTY INTERFACE_COMPILE_OPTIONS)
|
||||
|
||||
process_flags(${lang} flags output_list)
|
||||
|
||||
set(${i} ${output_list} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(process_flags lang input output)
|
||||
# The flags might contains compile language generator expressions that
|
||||
# look like this:
|
||||
# $<$<COMPILE_LANGUAGE:CXX>:-fno-exceptions>
|
||||
#
|
||||
# Flags that don't specify a language like this apply to all
|
||||
# languages.
|
||||
#
|
||||
# See COMPILE_LANGUAGE in
|
||||
# https://cmake.org/cmake/help/v3.3/manual/cmake-generator-expressions.7.html
|
||||
#
|
||||
# To deal with this, we apply a regex to extract the flag and also
|
||||
# to find out if the language matches.
|
||||
#
|
||||
# If this doesn't work out we might need to ban the use of
|
||||
# COMPILE_LANGUAGE and instead partition C, CXX, and ASM into
|
||||
# different libraries
|
||||
set(languages C CXX ASM)
|
||||
|
||||
set(tmp_list "")
|
||||
|
||||
foreach(flag ${${input}})
|
||||
set(is_compile_lang_generator_expression 0)
|
||||
foreach(l ${languages})
|
||||
if(flag MATCHES "<COMPILE_LANGUAGE:${l}>:([^>]+)>")
|
||||
set(is_compile_lang_generator_expression 1)
|
||||
if(${l} STREQUAL ${lang})
|
||||
list(APPEND tmp_list ${CMAKE_MATCH_1})
|
||||
break()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(NOT is_compile_lang_generator_expression)
|
||||
list(APPEND tmp_list ${flag})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(${output} ${tmp_list} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(convert_list_of_flags_to_string_of_flags ptr_list_of_flags string_of_flags)
|
||||
# Convert the list to a string so we can do string replace
|
||||
# operations on it and replace the ";" list separators with a
|
||||
# whitespace so the flags are spaced out
|
||||
string(REPLACE ";" " " locally_scoped_string_of_flags "${${ptr_list_of_flags}}")
|
||||
|
||||
# Set the output variable in the parent scope
|
||||
set(${string_of_flags} ${locally_scoped_string_of_flags} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
macro(get_property_and_add_prefix result target property prefix)
|
||||
get_property(target_property TARGET ${target} PROPERTY ${property})
|
||||
foreach(x ${target_property})
|
||||
|
@ -143,55 +262,6 @@ macro(get_property_and_add_prefix result target property prefix)
|
|||
endforeach()
|
||||
endmacro()
|
||||
|
||||
macro(zephyr_get_include_directories i)
|
||||
get_property_and_add_prefix(${i} zephyr_interface INTERFACE_INCLUDE_DIRECTORIES -I)
|
||||
endmacro()
|
||||
|
||||
macro(zephyr_get_system_include_directories i)
|
||||
get_property_and_add_prefix(${i} zephyr_interface INTERFACE_SYSTEM_INCLUDE_DIRECTORIES -isystem)
|
||||
endmacro()
|
||||
|
||||
macro(zephyr_get_compile_definitions i)
|
||||
get_property_and_add_prefix(${i} zephyr_interface INTERFACE_COMPILE_DEFINITIONS -D)
|
||||
endmacro()
|
||||
|
||||
macro(zephyr_get_compile_options i)
|
||||
get_property(${i} TARGET zephyr_interface PROPERTY INTERFACE_COMPILE_OPTIONS)
|
||||
endmacro()
|
||||
|
||||
macro(zephyr_get_include_directories_as_string i)
|
||||
zephyr_get_include_directories(${i})
|
||||
|
||||
string(REPLACE ";" " " ${i} ${${i}})
|
||||
string(REPLACE "-I" " -I" ${i} ${${i}})
|
||||
endmacro()
|
||||
|
||||
macro(zephyr_get_system_include_directories_as_string i)
|
||||
get_property_and_add_prefix(${i} zephyr_interface INTERFACE_SYSTEM_INCLUDE_DIRECTORIES -isystem)
|
||||
|
||||
string(REPLACE ";" " " ${i} ${${i}})
|
||||
string(REPLACE "-isystem" " -isystem" ${i} ${${i}})
|
||||
endmacro()
|
||||
|
||||
macro(zephyr_get_compile_definitions_as_string i)
|
||||
get_property_and_add_prefix(${i} zephyr_interface INTERFACE_COMPILE_DEFINITIONS -D)
|
||||
|
||||
string(REPLACE ";" " " ${i} ${${i}})
|
||||
string(REPLACE "-D" " -D" ${i} ${${i}})
|
||||
endmacro()
|
||||
|
||||
macro(zephyr_get_compile_options_as_string i)
|
||||
zephyr_get_compile_options(j)
|
||||
|
||||
foreach(__opt__ ${j})
|
||||
if(__opt__ MATCHES "<COMPILE_LANGUAGE:")
|
||||
# TODO: Support COMPILE_LANGUAGE generator expressions
|
||||
continue()
|
||||
endif()
|
||||
set(${i} "${${i}} ${__opt__}")
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
# 1.3 generate_inc_*
|
||||
|
||||
# These functions are useful if there is a need to generate a file
|
||||
|
|
|
@ -11,13 +11,13 @@ target_sources(app PRIVATE src/main.c)
|
|||
# do not need any build information from zephyr. Or they may be
|
||||
# incompatible with certain zephyr options and need them to be
|
||||
# filtered out.
|
||||
zephyr_get_include_directories_as_string(includes)
|
||||
zephyr_get_system_include_directories_as_string(system_includes)
|
||||
zephyr_get_compile_definitions_as_string(definitions)
|
||||
zephyr_get_compile_options_as_string(options)
|
||||
zephyr_get_include_directories_for_lang_as_string( C includes)
|
||||
zephyr_get_system_include_directories_for_lang_as_string(C system_includes)
|
||||
zephyr_get_compile_definitions_for_lang_as_string( C definitions)
|
||||
zephyr_get_compile_options_for_lang_as_string( C options)
|
||||
|
||||
set(external_project_cflags
|
||||
${includes}${definitions}${options}${system_includes}
|
||||
"${includes} ${definitions} ${options} ${system_includes}"
|
||||
)
|
||||
|
||||
include(ExternalProject)
|
||||
|
|
Loading…
Reference in a new issue