1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 13:07:46 +00:00

Meta: Switch to a SuperBuild that splits host and target builds

Replace the old logic where we would start with a host build, and swap
all the CMake compiler and target variables underneath it to trick
CMake into building for Serenity after we configured and built the Lagom
code generators.

The SuperBuild creates two ExternalProjects, one for Lagom and one for
Serenity. The Serenity project depends on the install stage for the
Lagom build. The SuperBuild also generates a CMakeToolchain file for the
Serenity build to use that replaces the old toolchain file that was only
used for Ports.

To ensure that code generators are rebuilt when core libraries such as
AK and LibCore are modified, developers will need to direct their manual
`ninja` invocations to the SuperBuild's binary directory instead of the
Serenity binary directory.

This commit includes warning coalescing and option style cleanup for the
affected CMakeLists in the Kernel, top level, and runtime support
libraries. A large part of the cleanup is replacing USE_CLANG_TOOLCHAIN
with the proper CMAKE_CXX_COMPILER_ID variable, which will no longer be
confused by a host clang compiler.
This commit is contained in:
Andrew Kaster 2021-09-07 02:21:36 -06:00 committed by Ali Mohammad Pur
parent 904a268872
commit b5c98ede08
15 changed files with 403 additions and 335 deletions

View file

@ -0,0 +1,137 @@
cmake_minimum_required(VERSION 3.16)
project(
SerenitySuperbuild
DESCRIPTION "Orchestrate host and target builds in a single build"
LANGUAGES NONE
)
# NOTE: Before CMake 3.19, if a custom command is attached to multiple step targets for Makefile and Visual Studio generators,
# it might be run multiple times during the build. Enable new behavior of policy CMP0114 to avoid this, or apply the
# workaround from https://gitlab.kitware.com/cmake/cmake/-/issues/18663#note_489967
if(NOT CMAKE_VERSION VERSION_LESS "3.19")
cmake_policy(SET CMP0114 NEW)
macro(ensure_dependencies)
endmacro()
else()
macro(ensure_dependencies proj)
foreach(step IN ITEMS configure build install)
if(NOT TARGET "${proj}-${step}")
ExternalProject_Add_StepTargets("${proj}" "${step}")
endif()
if(step STREQUAL "install")
ExternalProject_Add_StepDependencies("${proj}" install "${proj}-build")
elseif(step STREQUAL "build")
ExternalProject_Add_StepDependencies("${proj}" build "${proj}-configure")
endif()
endforeach()
endmacro()
endif()
get_filename_component(
SERENITY_SOURCE_DIR "${PROJECT_SOURCE_DIR}/../../.."
ABSOLUTE CACHE
)
set(SERENITY_ARCH "i686" CACHE STRING "Target architecture for SerenityOS.")
set(SERENITY_TOOLCHAIN "GNU" CACHE STRING "Compliler toolchain to use for Serenity (GNU or Clang)")
# FIXME: It is preferred to keep all the sub-build artifacts below the binary directory for the superbuild
# However, this has an impact on developer's IDE settings and more significantly, the Ports tree.
# See https://github.com/SerenityOS/serenity/pull/9297#discussion_r697877603
set(SERENITY_BUILD_DIR_SUFFIX "")
if(NOT SERENITY_TOOLCHAIN STREQUAL "GNU")
string(TOLOWER "${SERENITY_TOOLCHAIN}" SERENITY_BUILD_DIR_SUFFIX)
endif()
set(SERENITY_BUILD_DIR "${PROJECT_BINARY_DIR}/../${SERENITY_ARCH}${SERENITY_BUILD_DIR_SUFFIX}")
if (CMAKE_HOST_SYSTEM_NAME MATCHES "SerenityOS")
message(STATUS "Good job on building cmake!")
else()
configure_file("${SERENITY_SOURCE_DIR}/Toolchain/CMake/${SERENITY_TOOLCHAIN}Toolchain.txt.in" "${SERENITY_BUILD_DIR}/CMakeToolchain.txt" @ONLY)
set(SERENITY_TOOLCHAIN_FILE "${SERENITY_BUILD_DIR}/CMakeToolchain.txt" CACHE PATH "Toolchain file to use for cross-compilation")
# Support non-cross builds by stuffing this in a variable
set(SERENITY_TOOLCHAIN_FILE_ARG "-DCMAKE_TOOLCHAIN_FILE:STRING=${SERENITY_TOOLCHAIN_FILE}")
endif()
# Allow the Ninja generators to output messages as they happen by assigning
# these jobs to the 'console' job pool
set(console_access "")
if(CMAKE_GENERATOR MATCHES "^Ninja")
set(
console_access
USES_TERMINAL_CONFIGURE YES
USES_TERMINAL_BUILD YES
USES_TERMINAL_INSTALL YES
)
endif()
include(ExternalProject)
# Collect options for Lagom build
set(lagom_options "")
macro(serenity_option name)
set(${ARGV})
list(APPEND lagom_options "-D${name}:STRING=${${name}}")
endmacro()
include("${SERENITY_SOURCE_DIR}/Meta/CMake/lagom_options.cmake")
# Forward user defined host toolchain to lagom build
if (DEFINED CMAKE_C_COMPILER)
set(CMAKE_C_COMPILER "${CMAKE_C_COMPILER}" CACHE STRING "C Compiler to use for host builds")
list(APPEND lagom_options "-DCMAKE_C_COMPILER:STRING=${CMAKE_C_COMPILER}")
endif()
if (DEFINED CMAKE_CXX_COMPILER)
set(CMAKE_CXX_COMPILER "${CMAKE_CXX_COMPILER}" CACHE STRING "C++ Compiler to use for host builds")
list(APPEND lagom_options "-DCMAKE_CXX_COMPILER:STRING=${CMAKE_CXX_COMPILER}")
endif()
ExternalProject_Add(
lagom
SOURCE_DIR "${SERENITY_SOURCE_DIR}/Meta/Lagom"
BINARY_DIR "${PROJECT_BINARY_DIR}/../lagom"
INSTALL_DIR "${PROJECT_BINARY_DIR}/../lagom-install"
EXCLUDE_FROM_ALL YES
CMAKE_CACHE_ARGS
"-DCMAKE_INSTALL_PREFIX:STRING=<INSTALL_DIR>"
"-DUNICODE_CACHE_LOCATION:STRING=${SERENITY_BUILD_DIR}/UCD"
"-DLOCALE_DATA_CACHE_LOCATION:STRING=${SERENITY_BUILD_DIR}/CLDR"
${lagom_options}
# Always call the build step of tools, so keeping things up-to-date is easy
BUILD_ALWAYS YES
# Expose install step as a target, so it can be depended on
STEP_TARGETS install
${console_access}
)
ensure_dependencies(lagom)
# Collect options for serenity build
set(serenity_options "")
macro(serenity_option name)
set(${ARGV})
list(APPEND serenity_options "-D${name}:STRING=${${name}}")
endmacro()
include("${SERENITY_SOURCE_DIR}/Meta/CMake/serenity_options.cmake")
ExternalProject_Add(
serenity
SOURCE_DIR "${SERENITY_SOURCE_DIR}"
BINARY_DIR "${SERENITY_BUILD_DIR}"
CMAKE_CACHE_ARGS
# Tell the find_package(Lagom REQUIRED) command call where to find
# the CMake package
"-DCMAKE_PREFIX_PATH:STRING=${PROJECT_BINARY_DIR}/../lagom-install"
"-DUNICODE_CACHE_LOCATION:STRING=${SERENITY_BUILD_DIR}/UCD"
"-DLOCALE_DATA_CACHE_LOCATION:STRING=${SERENITY_BUILD_DIR}/CLDR"
"-DSERENITY_ARCH:STRING=${SERENITY_ARCH}"
"${SERENITY_TOOLCHAIN_FILE_ARG}"
${serenity_options}
# Always call the build step
BUILD_ALWAYS YES
# Host tools must be built and installed before the OS can be built
DEPENDS lagom-install
STEP_TARGETS install
${console_access}
)
ensure_dependencies(serenity)

View file

@ -56,8 +56,8 @@ function(serenity_libc target_name fs_name)
add_library(${target_name} SHARED ${SOURCES})
install(TARGETS ${target_name} DESTINATION usr/lib)
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${fs_name})
if (USE_CLANG_TOOLCHAIN)
target_link_libraries(${target_name} clang_rt.builtins-${SERENITY_CLANG_ARCH})
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang$")
target_link_libraries(${target_name} "clang_rt.builtins-${SERENITY_CLANG_ARCH}")
endif()
target_link_directories(LibC PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
serenity_generated_sources(${target_name})
@ -101,7 +101,6 @@ function(serenity_test test_src sub_dir)
install(TARGETS ${test_name} RUNTIME DESTINATION usr/Tests/${sub_dir} OPTIONAL)
endfunction()
function(serenity_testjs_test test_src sub_dir)
cmake_parse_arguments(PARSE_ARGV 2 SERENITY_TEST "" "CUSTOM_MAIN" "LIBS")
if ("${SERENITY_TEST_CUSTOM_MAIN}" STREQUAL "")