2022-11-16 06:20:24 +00:00
|
|
|
# https://stackoverflow.com/a/62311397/328260
|
|
|
|
macro (get_all_targets_recursive targets dir)
|
|
|
|
get_property (subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
|
|
|
|
foreach (subdir ${subdirectories})
|
|
|
|
get_all_targets_recursive (${targets} ${subdir})
|
|
|
|
endforeach ()
|
|
|
|
get_property (current_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
|
|
|
|
list (APPEND ${targets} ${current_targets})
|
|
|
|
endmacro ()
|
|
|
|
|
2020-07-07 16:22:41 +00:00
|
|
|
# When you will try to link target with the directory (that exists), cmake will
|
|
|
|
# skip this without an error, only the following warning will be reported:
|
|
|
|
#
|
|
|
|
# target_link_libraries(main /tmp)
|
|
|
|
#
|
|
|
|
# WARNING: Target "main" requests linking to directory "/tmp". Targets may link only to libraries. CMake is dropping the item.
|
|
|
|
#
|
|
|
|
# And there is no cmake policy that controls this.
|
|
|
|
# (I guess the reason that it is allowed is because of FRAMEWORK for OSX).
|
|
|
|
#
|
|
|
|
# So to avoid error-prone cmake rules, this can be sanitized.
|
|
|
|
# There are the following ways:
|
|
|
|
# - overwrite target_link_libraries()/link_libraries() and check *before*
|
|
|
|
# calling real macro, but this requires duplicate all supported syntax
|
|
|
|
# -- too complex
|
|
|
|
# - overwrite target_link_libraries() and check LINK_LIBRARIES property, this
|
|
|
|
# works great
|
|
|
|
# -- but cannot be used with link_libraries()
|
|
|
|
# - use BUILDSYSTEM_TARGETS property to get list of all targets and sanitize
|
|
|
|
# -- this will work.
|
|
|
|
function (get_all_targets var)
|
|
|
|
set (targets)
|
|
|
|
get_all_targets_recursive (targets ${CMAKE_CURRENT_SOURCE_DIR})
|
|
|
|
set (${var} ${targets} PARENT_SCOPE)
|
|
|
|
endfunction()
|
2022-11-16 06:20:24 +00:00
|
|
|
function (sanitize_link_libraries target)
|
2020-07-07 16:22:41 +00:00
|
|
|
get_target_property(target_type ${target} TYPE)
|
|
|
|
if (${target_type} STREQUAL "INTERFACE_LIBRARY")
|
|
|
|
get_property(linked_libraries TARGET ${target} PROPERTY INTERFACE_LINK_LIBRARIES)
|
|
|
|
else()
|
|
|
|
get_property(linked_libraries TARGET ${target} PROPERTY LINK_LIBRARIES)
|
|
|
|
endif()
|
|
|
|
foreach (linked_library ${linked_libraries})
|
|
|
|
if (TARGET ${linked_library})
|
|
|
|
# just in case, skip if TARGET
|
|
|
|
elseif (IS_DIRECTORY ${linked_library})
|
|
|
|
message(FATAL_ERROR "${target} requested to link with directory: ${linked_library}")
|
|
|
|
endif()
|
|
|
|
endforeach()
|
2022-11-16 06:20:24 +00:00
|
|
|
endfunction()
|
2020-07-07 16:22:41 +00:00
|
|
|
get_all_targets (all_targets)
|
|
|
|
foreach (target ${all_targets})
|
|
|
|
sanitize_link_libraries(${target})
|
|
|
|
endforeach()
|
2022-11-16 06:20:24 +00:00
|
|
|
|
|
|
|
#
|
|
|
|
# Do not allow to define -W* from contrib publically (INTERFACE/PUBLIC).
|
|
|
|
#
|
|
|
|
function (get_contrib_targets var)
|
|
|
|
set (targets)
|
|
|
|
get_all_targets_recursive (targets ${CMAKE_CURRENT_SOURCE_DIR}/contrib)
|
|
|
|
set (${var} ${targets} PARENT_SCOPE)
|
|
|
|
endfunction()
|
|
|
|
function (sanitize_interface_flags target)
|
|
|
|
get_target_property(target_type ${target} TYPE)
|
|
|
|
get_property(compile_definitions TARGET ${target} PROPERTY INTERFACE_COMPILE_DEFINITIONS)
|
|
|
|
get_property(compile_options TARGET ${target} PROPERTY INTERFACE_COMPILE_OPTIONS)
|
|
|
|
if (NOT "${compile_options}" STREQUAL "")
|
|
|
|
message(FATAL_ERROR "${target} set INTERFACE_COMPILE_OPTIONS to ${compile_options}. This is forbidden.")
|
|
|
|
endif()
|
|
|
|
if ("${compile_definitions}" MATCHES "-Wl,")
|
|
|
|
# linker option - OK
|
|
|
|
elseif ("${compile_definitions}" MATCHES "-W")
|
|
|
|
message(FATAL_ERROR "${target} contains ${compile_definitions} flags in INTERFACE_COMPILE_DEFINITIONS. This is forbidden.")
|
|
|
|
endif()
|
|
|
|
endfunction()
|
|
|
|
get_contrib_targets (contrib_targets)
|
|
|
|
foreach (contrib_target ${contrib_targets})
|
|
|
|
sanitize_interface_flags(${contrib_target})
|
|
|
|
endforeach()
|
|
|
|
|