Skip to content

Instantly share code, notes, and snippets.

@valgur
Created May 5, 2023 17:13
Show Gist options
  • Save valgur/1b5b07dff33df96ddedeedff8d38e18f to your computer and use it in GitHub Desktop.
Save valgur/1b5b07dff33df96ddedeedff8d38e18f to your computer and use it in GitHub Desktop.
# Defines the following helper functions:
# - print_target_properties()
# - print_vars()
# - get_all_targets()
# Adapted from https://stackoverflow.com/a/68881024/2997179
# Print all properties of CMake target.
function(print_target_properties target)
if(NOT TARGET ${target})
message("There is no target named '${target}'")
return()
endif()
_get_cmake_property_list()
get_target_property(target_type ${target} TYPE)
if(target_type STREQUAL "INTERFACE_LIBRARY")
set(PROPERTIES ${CMAKE_WHITELISTED_PROPERTY_LIST})
else()
set(PROPERTIES ${CMAKE_PROPERTY_LIST})
endif()
foreach(prop ${PROPERTIES})
get_property(value TARGET ${target} PROPERTY ${prop} SET)
if(value)
get_target_property(value ${target} ${prop})
message("${target} ${prop} = ${value}")
endif()
endforeach()
endfunction()
function(print_vars)
get_cmake_property(variables VARIABLES)
list(SORT variables)
list(REMOVE_DUPLICATES variables)
# exclude arguments to this function
list(FILTER variables EXCLUDE REGEX "ARG(C|N|V|\\d+)")
foreach(variable ${variables})
if(ARGC EQUAL 0 OR variable MATCHES "${ARGV0}")
message("${variable} = ${${variable}}")
endif()
endforeach()
endfunction()
function(get_all_targets var)
set(targets)
_get_all_targets_in_directory(targets ${CMAKE_CURRENT_LIST_DIR})
set(${var} ${targets} PARENT_SCOPE)
endfunction()
function(_get_all_targets_in_directory result dir)
get_property(_subdirs DIRECTORY "${dir}" PROPERTY SUBDIRECTORIES)
foreach(_subdir IN LISTS _subdirs)
_get_all_targets_in_directory(${result} "${_subdir}")
endforeach()
get_directory_property(_sub_targets DIRECTORY "${dir}" BUILDSYSTEM_TARGETS)
set(${result} ${${result}} ${_sub_targets} PARENT_SCOPE)
endfunction()
# Sets the AVAILABLE_CONFIGURATION_TYPES variable to the default available configurations
# (For some reason, CMAKE_CONFIGURATION_TYPES tends to be empty)
function(_get_available_configuration_types)
# Get all variables that cmake cache defines by default
execute_process(COMMAND cmake "${CMAKE_CURRENT_SOURCE_DIR}" -LAH -N OUTPUT_VARIABLE CMAKE_CACHE_VARIABLE_LIST)
# Convert command output into a CMake list
string(REGEX REPLACE ";" "[:semicolon:]" CMAKE_CACHE_VARIABLE_LIST "${CMAKE_CACHE_VARIABLE_LIST}")
string(REGEX REPLACE "\n" ";" CMAKE_CACHE_VARIABLE_LIST "${CMAKE_CACHE_VARIABLE_LIST}")
# filter down to the variables
list(FILTER CMAKE_CACHE_VARIABLE_LIST EXCLUDE REGEX "^$|^//.*$|^\\-\\-$")
# Get the configuration types
set(AVAILABLE_CONFIGURATION_TYPES ${CMAKE_CACHE_VARIABLE_LIST})
list(FILTER AVAILABLE_CONFIGURATION_TYPES INCLUDE REGEX "^CMAKE_CONFIGURATION_TYPES")
if(AVAILABLE_CONFIGURATION_TYPES)
list(GET AVAILABLE_CONFIGURATION_TYPES 0 AVAILABLE_CONFIGURATION_TYPES)
endif()
string(REGEX REPLACE ".*=" "" AVAILABLE_CONFIGURATION_TYPES "${AVAILABLE_CONFIGURATION_TYPES}")
string(REPLACE "[:semicolon:]" ";" AVAILABLE_CONFIGURATION_TYPES "${AVAILABLE_CONFIGURATION_TYPES}")
string(TOUPPER "${AVAILABLE_CONFIGURATION_TYPES}" AVAILABLE_CONFIGURATION_TYPES)
# Add the current build type if it isn't already there
string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE)
list(FILTER AVAILABLE_CONFIGURATION_TYPES EXCLUDE REGEX ${BUILD_TYPE})
list(APPEND AVAILABLE_CONFIGURATION_TYPES ${BUILD_TYPE})
list(SORT AVAILABLE_CONFIGURATION_TYPES)
# make AVAILABLE_CONFIGURATION_TYPES available to parent
set(AVAILABLE_CONFIGURATION_TYPES ${AVAILABLE_CONFIGURATION_TYPES} PARENT_SCOPE)
endfunction()
# Sets the CMAKE_PROPERTY_LIST and CMAKE_WHITELISTED_PROPERTY_LIST variables to
# the list of properties
function(_get_cmake_property_list)
# See https://stackoverflow.com/a/44477728/240845
set(LANGS ASM-ATT ASM ASM_MASM ASM_NASM C CSHARP CUDA CXX FORTRAN HIP ISPC JAVA OBJC OBJCXX RC SWIFT)
_get_available_configuration_types()
# Get all properties that cmake supports
execute_process(COMMAND cmake --help-property-list OUTPUT_VARIABLE CMAKE_PROPERTY_LIST)
# Convert command output into a CMake list
string(REGEX REPLACE ";" "\\\\;" CMAKE_PROPERTY_LIST "${CMAKE_PROPERTY_LIST}")
string(REGEX REPLACE "\n" ";" CMAKE_PROPERTY_LIST "${CMAKE_PROPERTY_LIST}")
# Populate "<CONFIG>" with AVAILABLE_CONFIGURATION_TYPES
set(CONFIG_LINES ${CMAKE_PROPERTY_LIST})
list(FILTER CONFIG_LINES INCLUDE REGEX "<CONFIG>")
list(FILTER CMAKE_PROPERTY_LIST EXCLUDE REGEX "<CONFIG>")
foreach(CONFIG_LINE IN LISTS CONFIG_LINES)
foreach(CONFIG_VALUE IN LISTS AVAILABLE_CONFIGURATION_TYPES)
string(REPLACE "<CONFIG>" "${CONFIG_VALUE}" FIXED "${CONFIG_LINE}")
list(APPEND CMAKE_PROPERTY_LIST ${FIXED})
endforeach()
endforeach()
# Populate "<LANG>" with LANGS
set(LANG_LINES ${CMAKE_PROPERTY_LIST})
list(FILTER LANG_LINES INCLUDE REGEX "<LANG>")
list(FILTER CMAKE_PROPERTY_LIST EXCLUDE REGEX "<LANG>")
foreach(LANG_LINE IN LISTS LANG_LINES)
foreach(LANG IN LISTS LANGS)
string(REPLACE "<LANG>" "${LANG}" FIXED "${LANG_LINE}")
list(APPEND CMAKE_PROPERTY_LIST ${FIXED})
endforeach()
endforeach()
list(REMOVE_DUPLICATES CMAKE_PROPERTY_LIST)
# Fix https://stackoverflow.com/questions/32197663/how-can-i-remove-the-the-location-property-may-not-be-read-from-target-error-i
list(FILTER CMAKE_PROPERTY_LIST EXCLUDE REGEX "^LOCATION$|^LOCATION_|_LOCATION$")
list(SORT CMAKE_PROPERTY_LIST)
# Whitelisted property list for use with interface libraries to reduce warnings
# regex from https://stackoverflow.com/a/51987470/240845
set(CMAKE_WHITELISTED_PROPERTY_LIST ${CMAKE_PROPERTY_LIST})
list(FILTER CMAKE_WHITELISTED_PROPERTY_LIST INCLUDE REGEX
"^(INTERFACE|[_a-z]|IMPORTED_LIBNAME_|MAP_IMPORTED_CONFIG_)|^(COMPATIBLE_INTERFACE_(BOOL|NUMBER_MAX|NUMBER_MIN|STRING)|EXPORT_NAME|IMPORTED(_GLOBAL|_CONFIGURATIONS|_LIBNAME)?|NAME|TYPE|NO_SYSTEM_FROM_IMPORTED)$")
# make the lists available
set(CMAKE_PROPERTY_LIST ${CMAKE_PROPERTY_LIST} PARENT_SCOPE)
set(CMAKE_WHITELISTED_PROPERTY_LIST ${CMAKE_WHITELISTED_PROPERTY_LIST} PARENT_SCOPE)
endfunction()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment