diff --git a/AK/CMakeLists.txt b/AK/CMakeLists.txt index 479e06f377..5fc9dcd20e 100644 --- a/AK/CMakeLists.txt +++ b/AK/CMakeLists.txt @@ -1,4 +1,2 @@ -include(${CMAKE_SOURCE_DIR}/Meta/CMake/utils.cmake) - serenity_install_headers(AK) serenity_install_sources(AK) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6532785451..032e1e4b5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,11 +260,23 @@ if (ENABLE_UNDEFINED_SANITIZER) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-sanitize=vptr") endif() +add_custom_target(components ALL) +option(BUILD_EVERYTHING "Build all optional components" ON) + +include(${CMAKE_SOURCE_DIR}/Meta/CMake/utils.cmake) + +serenity_component( + Tests + RECOMMENDED +) + add_subdirectory(AK) add_subdirectory(Kernel) add_subdirectory(Userland) add_subdirectory(Tests) +export_components("${CMAKE_BINARY_DIR}/components.ini") + set(PCI_IDS_GZ_URL https://pci-ids.ucw.cz/v2.2/pci.ids.gz) set(PCI_IDS_GZ_PATH ${CMAKE_BINARY_DIR}/pci.ids.gz) set(PCI_IDS_PATH ${CMAKE_BINARY_DIR}/pci.ids) diff --git a/Documentation/BuildInstructions.md b/Documentation/BuildInstructions.md index b83e3f96ce..c14c298221 100644 --- a/Documentation/BuildInstructions.md +++ b/Documentation/BuildInstructions.md @@ -270,6 +270,8 @@ There are some optional features that can be enabled during compilation that are - `PRECOMPILE_COMMON_HEADERS`: precompiles some common headers to speedup compilation. - `ENABLE_KERNEL_LTO`: builds the kernel with link-time optimization. - `INCLUDE_WASM_SPEC_TESTS`: downloads and includes the WebAssembly spec testsuite tests +- `BUILD_`: builds the specified component, e.g. `BUILD_HEARTS` (note: must be all caps). Check the components.ini file in your build directory for a list of available components. Make sure to run `ninja clean` and `rm -rf Build/i686/Root` after disabling components. +- `BUILD_EVERYTHING`: builds all optional components, overrides other `BUILD_` flags when enabled Many parts of the SerenityOS codebase have debug functionality, mostly consisting of additional messages printed to the debug console. This is done via the `_DEBUG` macros, which can be enabled individually at build time. They are listed in [this file](../Meta/CMake/all_the_debug_macros.cmake). diff --git a/Meta/CMake/utils.cmake b/Meta/CMake/utils.cmake index e949a0adca..dd4e51869b 100644 --- a/Meta/CMake/utils.cmake +++ b/Meta/CMake/utils.cmake @@ -2,7 +2,7 @@ function(serenity_install_headers target_name) file(GLOB_RECURSE headers RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h") foreach(header ${headers}) get_filename_component(subdirectory ${header} DIRECTORY) - install(FILES ${header} DESTINATION usr/include/${target_name}/${subdirectory}) + install(FILES ${header} DESTINATION usr/include/${target_name}/${subdirectory} OPTIONAL) endforeach() endfunction() @@ -10,7 +10,7 @@ function(serenity_install_sources target_name) file(GLOB_RECURSE sources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.h" "*.cpp") foreach(source ${sources}) get_filename_component(subdirectory ${source} DIRECTORY) - install(FILES ${source} DESTINATION usr/src/serenity/${target_name}/${subdirectory}) + install(FILES ${source} DESTINATION usr/src/serenity/${target_name}/${subdirectory} OPTIONAL) endforeach() endfunction() @@ -28,7 +28,8 @@ function(serenity_lib target_name fs_name) serenity_install_headers(${target_name}) serenity_install_sources("Userland/Libraries/${target_name}") add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES}) - install(TARGETS ${target_name} DESTINATION usr/lib) + set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL TRUE) + install(TARGETS ${target_name} DESTINATION usr/lib OPTIONAL) set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name}) serenity_generated_sources(${target_name}) endfunction() @@ -37,7 +38,8 @@ function(serenity_shared_lib target_name fs_name) serenity_install_headers(${target_name}) serenity_install_sources("Userland/Libraries/${target_name}") add_library(${target_name} SHARED ${SOURCES} ${GENERATED_SOURCES}) - install(TARGETS ${target_name} DESTINATION usr/lib) + set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL TRUE) + install(TARGETS ${target_name} DESTINATION usr/lib OPTIONAL) set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name}) serenity_generated_sources(${target_name}) endfunction() @@ -57,7 +59,8 @@ function(serenity_libc_static target_name fs_name) serenity_install_headers("") serenity_install_sources("Userland/Libraries/LibC") add_library(${target_name} ${SOURCES}) - install(TARGETS ${target_name} ARCHIVE DESTINATION usr/lib) + set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL TRUE) + install(TARGETS ${target_name} ARCHIVE DESTINATION usr/lib OPTIONAL) set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name}) target_link_directories(${target_name} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) serenity_generated_sources(${target_name}) @@ -65,7 +68,8 @@ endfunction() function(serenity_bin target_name) add_executable(${target_name} ${SOURCES}) - install(TARGETS ${target_name} RUNTIME DESTINATION bin) + set_target_properties(${target_name} PROPERTIES EXCLUDE_FROM_ALL TRUE) + install(TARGETS ${target_name} RUNTIME DESTINATION bin OPTIONAL) serenity_generated_sources(${target_name}) endfunction() @@ -81,11 +85,13 @@ function(serenity_test test_src sub_dir) endif() get_filename_component(test_name ${test_src} NAME_WE) add_executable(${test_name} ${TEST_SOURCES}) + add_dependencies(ComponentTests ${test_name}) + set_target_properties(${test_name} PROPERTIES EXCLUDE_FROM_ALL TRUE) target_link_libraries(${test_name} LibTest LibCore) foreach(lib ${SERENITY_TEST_LIBS}) target_link_libraries(${test_name} ${lib}) endforeach() - install(TARGETS ${test_name} RUNTIME DESTINATION usr/Tests/${sub_dir}) + install(TARGETS ${test_name} RUNTIME DESTINATION usr/Tests/${sub_dir} OPTIONAL) endfunction() @@ -127,6 +133,84 @@ function(serenity_app target_name) endif() endfunction() +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(SERENITY_COMPONENT "RECOMMENDED;REQUIRED" "DESCRIPTION" "TARGETS;DEPENDS" ${ARGN}) + string(TOUPPER "${name}" NAME_UPPER) + option("BUILD_${NAME_UPPER}" "Build ${name}" ${SERENITY_COMPONENT_RECOMMENDED}) + add_custom_target("Component${name}") + set_property(TARGET "Component${name}" PROPERTY SERENITY_COMPONENT_NAME ${name}) + set_property(TARGET "Component${name}" PROPERTY SERENITY_COMPONENT_DESCRIPTION ${SERENITY_COMPONENT_DESCRIPTION}) + set_property(TARGET "Component${name}" PROPERTY SERENITY_COMPONENT_RECOMMENDED ${SERENITY_COMPONENT_RECOMMENDED}) + set_property(TARGET "Component${name}" PROPERTY SERENITY_COMPONENT_REQUIRED ${SERENITY_COMPONENT_REQUIRED}) + set_property(TARGET "Component${name}" PROPERTY SERENITY_COMPONENT_DEPENDS ${SERENITY_COMPONENT_DEPENDS}) + if(SERENITY_COMPONENT_TARGETS) + add_dependencies("Component${name}" ${SERENITY_COMPONENT_TARGETS}) + endif() + if(BUILD_EVERYTHING OR BUILD_${NAME_UPPER} OR SERENITY_COMPONENT_REQUIRED) + add_dependencies(components "Component${name}") + endif() + foreach(dependency ${SERENITY_COMPONENT_DEPENDS}) + add_dependencies("Component${name}" "Component${dependency}") + endforeach() +endfunction() + +macro(export_components_helper file_name current_dir) + get_property(sub_dirs DIRECTORY ${current_dir} PROPERTY SUBDIRECTORIES) + foreach(sub_dir ${sub_dirs}) + export_components_helper(${file_name} ${sub_dir}) + endforeach() + + get_property(targets DIRECTORY ${current_dir} PROPERTY BUILDSYSTEM_TARGETS) + foreach(target ${targets}) + get_property(component_name TARGET ${target} PROPERTY SERENITY_COMPONENT_NAME) + if(component_name) + get_property(component_name TARGET ${target} PROPERTY SERENITY_COMPONENT_NAME) + get_property(component_description TARGET ${target} PROPERTY SERENITY_COMPONENT_DESCRIPTION) + get_property(component_recommended TARGET ${target} PROPERTY SERENITY_COMPONENT_RECOMMENDED) + get_property(component_required TARGET ${target} PROPERTY SERENITY_COMPONENT_REQUIRED) + get_property(component_depends TARGET ${target} PROPERTY 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() +endmacro() + +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() + function(compile_gml source output string_name) set(source ${CMAKE_CURRENT_SOURCE_DIR}/${source}) add_custom_command(