serenity/Meta/CMake/serenity_components.cmake
Gunnar Beutner f70ec7582f Meta: Properly ignore targets which don't have a component name
Previously we'd add [component_name-NOTFOUND] sections to the
components.ini file for targets which weren't part of a component.
2022-10-15 13:12:42 +02:00

91 lines
4.5 KiB
CMake

#
# Target properties and functions for optionally building libraries and applications
#
define_property(TARGET PROPERTY SERENITY_COMPONENT_NAME BRIEF_DOCS "SerenityOS component name" FULL_DOCS "-")
define_property(TARGET PROPERTY SERENITY_COMPONENT_DESCRIPTION BRIEF_DOCS "SerenityOS component description" FULL_DOCS "-")
define_property(TARGET PROPERTY SERENITY_COMPONENT_RECOMMENDED BRIEF_DOCS "SerenityOS component recommended (flag)" FULL_DOCS "-")
define_property(TARGET PROPERTY SERENITY_COMPONENT_REQUIRED BRIEF_DOCS "SerenityOS component required (flag)" FULL_DOCS "-")
define_property(TARGET PROPERTY SERENITY_COMPONENT_DEPENDS BRIEF_DOCS "SerenityOS component dependencies" FULL_DOCS "-")
function(serenity_component name)
cmake_parse_arguments(PARSE_ARGV 1 SERENITY_COMPONENT "RECOMMENDED;REQUIRED" "DESCRIPTION" "TARGETS;DEPENDS")
string(TOUPPER "${name}" NAME_UPPER)
option("BUILD_${NAME_UPPER}" "Build ${name}" "${SERENITY_COMPONENT_RECOMMENDED}")
add_custom_target("Component${name}")
set_target_properties(
"Component${name}" PROPERTIES
SERENITY_COMPONENT_NAME "${name}"
SERENITY_COMPONENT_DESCRIPTION "${SERENITY_COMPONENT_DESCRIPTION}"
SERENITY_COMPONENT_RECOMMENDED "${SERENITY_COMPONENT_RECOMMENDED}"
SERENITY_COMPONENT_REQUIRED "${SERENITY_COMPONENT_REQUIRED}"
SERENITY_COMPONENT_DEPENDS "${SERENITY_COMPONENT_DEPENDS}"
)
if(NOT "${SERENITY_COMPONENT_TARGETS}" STREQUAL "") # note: one component is /bin/false, which makes this tricky
foreach(target IN LISTS SERENITY_COMPONENT_TARGETS)
add_dependencies("Component${name}" "${target}")
endforeach()
endif()
if(BUILD_EVERYTHING OR "${BUILD_${NAME_UPPER}}" OR SERENITY_COMPONENT_REQUIRED)
add_dependencies(components "Component${name}")
endif()
foreach(dependency IN LISTS SERENITY_COMPONENT_DEPENDS)
add_dependencies("Component${name}" "Component${dependency}")
endforeach()
endfunction()
function(export_components_helper file_name current_dir)
get_property(sub_dirs DIRECTORY "${current_dir}" PROPERTY SUBDIRECTORIES)
foreach(sub_dir IN LISTS sub_dirs)
export_components_helper("${file_name}" "${sub_dir}")
endforeach()
get_property(targets DIRECTORY "${current_dir}" PROPERTY BUILDSYSTEM_TARGETS)
foreach(target IN LISTS targets)
get_target_property(type "${target}" TYPE)
if (type STREQUAL "INTERFACE_LIBRARY")
continue() # Custom properties are not allowed to be set on INTERFACE libraries
endif()
get_target_property(component_name "${target}" SERENITY_COMPONENT_NAME)
if(NOT "${component_name}" STREQUAL "" AND NOT "${component_name}" STREQUAL "component_name-NOTFOUND")
get_target_property(component_name "${target}" SERENITY_COMPONENT_NAME)
get_target_property(component_description "${target}" SERENITY_COMPONENT_DESCRIPTION)
get_target_property(component_recommended "${target}" SERENITY_COMPONENT_RECOMMENDED)
get_target_property(component_required "${target}" SERENITY_COMPONENT_REQUIRED)
get_target_property(component_depends "${target}" SERENITY_COMPONENT_DEPENDS)
file(APPEND "${file_name}" "[${component_name}]\n")
file(APPEND "${file_name}" "description=${component_description}\n")
if(component_recommended)
file(APPEND "${file_name}" "recommended=1\n")
else()
file(APPEND "${file_name}" "recommended=0\n")
endif()
if(component_required)
file(APPEND "${file_name}" "required=1\n")
else()
file(APPEND "${file_name}" "required=0\n")
endif()
string(TOUPPER "${component_name}" component_name_upper)
if("${BUILD_${component_name_upper}}")
file(APPEND "${file_name}" "user_selected=1\n")
else()
file(APPEND "${file_name}" "user_selected=0\n")
endif()
file(APPEND "${file_name}" "depends=${component_depends}\n")
file(APPEND "${file_name}" "\n")
endif()
endforeach()
endfunction()
function(export_components file_name)
file(WRITE "${file_name}" "[Global]\n")
if(BUILD_EVERYTHING)
file(APPEND "${file_name}" "build_everything=1\n")
else()
file(APPEND "${file_name}" "build_everything=0\n")
endif()
file(APPEND "${file_name}" "\n")
export_components_helper("${file_name}" "${CMAKE_CURRENT_SOURCE_DIR}")
endfunction()