cmake: Give zephyr_library_* flags precedence over zephyr_* flags

This fixes https://github.com/zephyrproject-rtos/zephyr/issues/5097.

The desired behaviour is that when a flag that is given through the
zephyr_* API conflicts with the zephyr_library_* API then precedence
will be given to the zephyr_library_* API. In other words, local
configuration overrides global configuration.

We choose to rely upon the compiler for sane behaviour when flags are
in conflict. Compilers generally give precedence to flags given late
on the command line. So to ensure that zephyr_library_* flags are
placed late on the command line we create a dummy interface library
and link with it to obtain the flags.

Other options were considered, source file properties would also have
higher priority. But that would have required some kind of
post-processing stage that applies all the source file properties.

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 are
taken from.

Signed-off-by: Sebastian Boe <sebastian.boe@nordicsemi.no>
This commit is contained in:
Sebastian Bøe 2017-11-22 15:37:04 +01:00 committed by Anas Nashif
commit 96e7df466a

View file

@ -239,7 +239,7 @@ function(generate_inc_file_for_target
add_dependencies(${target} ${generated_target_name})
endfunction()
# 2.1 zephyr_library_*
# 1.2 zephyr_library_*
#
# Zephyr libraries use CMake's library concept and a set of
# assumptions about how zephyr code is organized to cut down on
@ -260,6 +260,11 @@ endfunction()
# The methods modify the CMake target_* API to reduce boilerplate;
# PRIVATE is assumed
# The target is assumed to be ZEPHYR_CURRENT_LIBRARY
#
# When a flag that is given through the zephyr_* API conflicts with
# the zephyr_library_* API then precedence will be given to the
# zephyr_library_* API. In other words, local configuration overrides
# global configuration.
# Constructor with a directory-inferred name
macro(zephyr_library)
@ -319,12 +324,34 @@ function(zephyr_library_compile_definitions item)
endfunction()
function(zephyr_library_compile_options item)
target_compile_options(${ZEPHYR_CURRENT_LIBRARY} PRIVATE ${item} ${ARGN})
# The compiler is relied upon for sane behaviour when flags are in
# conflict. Compilers generally give precedence to flags given late
# on the command line. So to ensure that zephyr_library_* flags are
# placed late on the command line we create a dummy interface
# 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
# are taken from.
string(RANDOM random)
set(lib_name options_interface_lib_${random})
add_library( ${lib_name} INTERFACE)
target_compile_options(${lib_name} INTERFACE ${item} ${ARGN})
target_link_libraries(${ZEPHYR_CURRENT_LIBRARY} ${lib_name})
endfunction()
function(zephyr_library_cc_option)
foreach(arg ${ARGV})
target_cc_option(${ZEPHYR_CURRENT_LIBRARY} PRIVATE ${arg})
foreach(option ${ARGV})
string(MAKE_C_IDENTIFIER check${option} check)
check_c_compiler_flag(${option} ${check})
if(${check})
zephyr_library_compile_options(${option})
endif()
endforeach()
endfunction()