From b5c98ede084e5d29b8586f3bb2bf134184d372be Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Tue, 7 Sep 2021 02:21:36 -0600 Subject: [PATCH] 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. --- .github/workflows/cmake.yml | 41 ++++-- CMakeLists.txt | 166 ++++++---------------- Kernel/CMakeLists.txt | 90 ++++-------- Kernel/Prekernel/CMakeLists.txt | 8 +- Meta/Azure/Serenity.yml | 23 ++- Meta/CMake/Superbuild/CMakeLists.txt | 137 ++++++++++++++++++ Meta/CMake/utils.cmake | 5 +- Meta/Lagom/CMakeLists.txt | 140 +++++++++--------- Meta/build-root-filesystem.sh | 2 +- Toolchain/CMake/CMakeToolchain.txt | 33 ----- Toolchain/CMake/ClangToolchain.txt.in | 41 ++++++ Toolchain/CMake/GNUToolchain.txt.in | 37 +++++ Toolchain/CMake/Platform/SerenityOS.cmake | 2 + Userland/DynamicLoader/CMakeLists.txt | 11 +- Userland/Libraries/LibC/CMakeLists.txt | 2 +- 15 files changed, 403 insertions(+), 335 deletions(-) create mode 100644 Meta/CMake/Superbuild/CMakeLists.txt delete mode 100644 Toolchain/CMake/CMakeToolchain.txt create mode 100644 Toolchain/CMake/ClangToolchain.txt.in create mode 100644 Toolchain/CMake/GNUToolchain.txt.in diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index bf656add08..83bcb2d2bf 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -118,14 +118,13 @@ jobs: ccache -s - name: Create build directory run: | - mkdir -p ${{ github.workspace }}/Build - mkdir -p ${{ github.workspace }}/Build/UCD - mkdir -p ${{ github.workspace }}/Build/CLDR + mkdir -p ${{ github.workspace }}/Build/${{ matrix.arch }}/UCD + mkdir -p ${{ github.workspace }}/Build/${{ matrix.arch }}/CLDR - name: UnicodeData cache # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. uses: actions/cache@03e00da99d75a2204924908e1cca7902cafce66b with: - path: ${{ github.workspace }}/Build/UCD + path: ${{ github.workspace }}/Build/${{ matrix.arch }}/UCD key: UnicodeData-${{ hashFiles('Meta/CMake/unicode_data.cmake') }} - name: UnicodeLocale Cache # TODO: Change the version to the released version when https://github.com/actions/cache/pull/489 (or 571) is merged. @@ -134,22 +133,38 @@ jobs: path: ${{ github.workspace }}/Build/CLDR key: UnicodeLocale-${{ hashFiles('Meta/CMake/unicode_data.cmake') }} - name: Create build environment with extra debug options - working-directory: ${{ github.workspace }}/Build # Build the entire project with all available debug options turned on, to prevent code rot. - # However, it is unweildy and slow to run tests with them enabled, so we will build twice. - run: cmake .. -GNinja -DSERENITY_ARCH=${{ matrix.arch }} -DBUILD_LAGOM=ON -DENABLE_ALL_DEBUG_FACILITIES=ON -DENABLE_PCI_IDS_DOWNLOAD=OFF -DENABLE_USB_IDS_DOWNLOAD=OFF -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 + # However, it is unwieldy and slow to run tests with them enabled, so we will build twice. + run: | + cmake -S Meta/CMake/Superbuild -B Build/superbuild -GNinja \ + -DSERENITY_ARCH=${{ matrix.arch }} \ + -DSERENITY_TOOLCHAIN=GNU \ + -DBUILD_LAGOM=ON \ + -DCMAKE_C_COMPILER=gcc-10 \ + -DCMAKE_CXX_COMPILER=g++-10 \ + -DENABLE_ALL_DEBUG_FACILITIES=ON \ + -DENABLE_PCI_IDS_DOWNLOAD=OFF \ + -DENABLE_USB_IDS_DOWNLOAD=OFF if: ${{ matrix.debug-options == 'ALL_DEBUG' }} - name: Create build environment - working-directory: ${{ github.workspace }}/Build + working-directory: ${{ github.workspace }} # Note that we do not set BUILD_LAGOM for the normal debug build # We build and run the Lagom tests in a separate job, and sanitizer builds take a good while longer than non-sanitized. - run: cmake .. -GNinja -DSERENITY_ARCH=${{ matrix.arch }} -DENABLE_UNDEFINED_SANITIZER=ON -DENABLE_PCI_IDS_DOWNLOAD=OFF -DENABLE_USB_IDS_DOWNLOAD=OFF -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 + run: | + cmake -S Meta/CMake/Superbuild -B Build/superbuild -GNinja \ + -DSERENITY_ARCH=${{ matrix.arch }} \ + -DSERENITY_TOOLCHAIN=GNU \ + -DCMAKE_C_COMPILER=gcc-10 \ + -DCMAKE_CXX_COMPILER=g++-10 \ + -DENABLE_UNDEFINED_SANITIZER=ON \ + -DENABLE_PCI_IDS_DOWNLOAD=OFF \ + -DENABLE_USB_IDS_DOWNLOAD=OFF if: ${{ matrix.debug-options == 'NORMAL_DEBUG' }} # === ACTUALLY BUILD === - name: Build Serenity and Tests - working-directory: ${{ github.workspace }}/Build + working-directory: ${{ github.workspace }}/Build/superbuild run: cmake --build . - name: Show ccache stats after build run: ccache -s @@ -159,12 +174,12 @@ jobs: - name: Create Serenity Rootfs if: ${{ matrix.debug-options == 'NORMAL_DEBUG'}} - working-directory: ${{ github.workspace }}/Build + working-directory: ${{ github.workspace }}/Build/${{ matrix.arch }} run: ninja install && ninja image - name: Run On-Target Tests if: ${{ matrix.debug-options == 'NORMAL_DEBUG'}} - working-directory: ${{ github.workspace }}/Build + working-directory: ${{ github.workspace }}/Build/${{ matrix.arch }} env: SERENITY_QEMU_CPU: "max,vmx=off" SERENITY_KERNEL_CMDLINE: "boot_mode=self-test" @@ -189,5 +204,5 @@ jobs: - name: Print Target Logs # Extremely useful if Serenity hangs trying to run one of the tests if: ${{ !cancelled() && matrix.debug-options == 'NORMAL_DEBUG'}} - working-directory: ${{ github.workspace }}/Build + working-directory: ${{ github.workspace }}/Build/${{ matrix.arch }} run: '[ ! -e debug.log ] || cat debug.log' diff --git a/CMakeLists.txt b/CMakeLists.txt index 239fedfdfc..00b1498de2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,16 +11,19 @@ if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "") "and that's all there is.") endif() -if (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 10.2) - message(FATAL_ERROR - "A GCC version less than 10.2 was detected (${CMAKE_CXX_COMPILER_VERSION}), this is unsupported.\n" - "Please re-read the build instructions documentation, and upgrade your host compiler.\n") +if(NOT CMAKE_SYSTEM_NAME STREQUAL "SerenityOS") + message(FATAL_ERROR "System name is not SerenityOS, this is unsupported.\n" + "Please re-read the BuildInstructions documentation, and use the superbuild configuration\n") +endif() + +if(SERENITY_ARCH STREQUAL "i686") + set(SERENITY_CLANG_ARCH "i386") +else() + set(SERENITY_CLANG_ARCH "${SERENITY_ARCH}") endif() set(CMAKE_INSTALL_MESSAGE NEVER) -enable_testing() - set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if(NOT COMMAND serenity_option) @@ -30,14 +33,19 @@ if(NOT COMMAND serenity_option) endif() include(serenity_options) -set(SERENITY_ARCH "i686" CACHE STRING "Target architecture for SerenityOS.") - -if("${SERENITY_ARCH}" STREQUAL "i686") - set(SERENITY_CLANG_ARCH "i386") -else() - set(SERENITY_CLANG_ARCH ${SERENITY_ARCH}) +find_program(CCACHE_PROGRAM ccache) +if(CCACHE_PROGRAM) + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE FILEPATH "Path to a compiler launcher program, e.g. ccache") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE FILEPATH "Path to a compiler launcher program, e.g. ccache") endif() +# FIXME: With cmake 3.18, we can change unzip/untar steps to use +# file(ARCHIVE_EXTRACT) instead +find_program(UNZIP unzip REQUIRED) +find_program(TAR tar REQUIRED) + +# Host tools, required to generate files for the build +find_package(Lagom CONFIG REQUIRED) # Meta target to run all code-gen steps in the build. add_custom_target(all_generated) @@ -63,21 +71,18 @@ add_custom_target(image DEPENDS qemu-image ) -set(GCC_VERSION 11.2.0) -set(LLVM_VERSION 12.0.1) - add_custom_target(qemu-image - COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "USE_CLANG_TOOLCHAIN=$" "LLVM_VERSION=${LLVM_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-qemu.sh" + COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "SERENITY_TOOLCHAIN=${CMAKE_CXX_COMPILER_ID}" "LLVM_VERSION=${CMAKE_CXX_COMPILER_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-qemu.sh" BYPRODUCTS "${CMAKE_BINARY_DIR}/_disk_image" USES_TERMINAL ) add_custom_target(grub-image - COMMAND ${CMAKE_COMMAND} -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "USE_CLANG_TOOLCHAIN=$" "LLVM_VERSION=${LLVM_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-grub.sh" + COMMAND ${CMAKE_COMMAND} -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "SERENITY_TOOLCHAIN=${CMAKE_CXX_COMPILER_ID}" "LLVM_VERSION=${CMAKE_CXX_COMPILER_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-grub.sh" BYPRODUCTS ${CMAKE_BINARY_DIR}/grub_disk_image USES_TERMINAL ) add_custom_target(extlinux-image - COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "USE_CLANG_TOOLCHAIN=$" "LLVM_VERSION=${LLVM_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-extlinux.sh" + COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "SERENITY_TOOLCHAIN=${CMAKE_CXX_COMPILER_ID}" "LLVM_VERSION=${CMAKE_CXX_COMPILER_VERSION}" "${SerenityOS_SOURCE_DIR}/Meta/build-image-extlinux.sh" BYPRODUCTS "${CMAKE_BINARY_DIR}/extlinux_disk_image" USES_TERMINAL ) @@ -92,7 +97,7 @@ add_custom_target(check-style ) add_custom_target(install-ports - COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "${SerenityOS_SOURCE_DIR}/Meta/install-ports-tree.sh" + COMMAND "${CMAKE_COMMAND}" -E env "SERENITY_SOURCE_DIR=${SerenityOS_SOURCE_DIR}" "SERENITY_ARCH=${SERENITY_ARCH}" "SERENITY_TOOLCHAIN=${CMAKE_CXX_COMPILER_ID}" "${SerenityOS_SOURCE_DIR}/Meta/install-ports-tree.sh" USES_TERMINAL ) @@ -106,18 +111,6 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -add_compile_options(-fsized-deallocation) - -add_compile_options(-fno-delete-null-pointer-checks) - -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - add_compile_options(-Wno-literal-suffix) -elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang$") - add_compile_options(-Wno-overloaded-virtual) - add_compile_options(-Wno-user-defined-literals) - add_compile_options(-fconstexpr-steps=16777216) -endif() - if (ENABLE_ALL_DEBUG_FACILITIES) set(ENABLE_ALL_THE_DEBUG_MACROS ON) set(ENABLE_EXTRA_KERNEL_DEBUG_SYMBOLS ON) @@ -141,98 +134,23 @@ endif(ENABLE_ALL_THE_DEBUG_MACROS) configure_file(AK/Debug.h.in AK/Debug.h @ONLY) configure_file(Kernel/Debug.h.in Kernel/Debug.h @ONLY) -include_directories(Userland/Libraries) -include_directories(.) -include_directories(${CMAKE_BINARY_DIR}) - -add_subdirectory(Meta/Lagom) - -find_program(CCACHE_PROGRAM ccache) -if(CCACHE_PROGRAM) - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") -endif() - -# FIXME: With cmake 3.18, we can change unzip/untar steps to use -# file(ARCHIVE_EXTRACT) instead -find_program(UNZIP unzip REQUIRED) -find_program(TAR tar REQUIRED) - -unset(CMAKE_SYSROOT) set(CMAKE_STAGING_PREFIX ${CMAKE_BINARY_DIR}/Root) set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Root) set(CMAKE_INSTALL_DATAROOTDIR ${CMAKE_BINARY_DIR}/Root/res) - -if (${CMAKE_HOST_SYSTEM_NAME} MATCHES SerenityOS) - message("Good job on building cmake!") -elseif(USE_CLANG_TOOLCHAIN) - set(TOOLCHAIN_ROOT ${CMAKE_SOURCE_DIR}/Toolchain/Local/clang/${SERENITY_ARCH}/) - set(TOOLCHAIN_PATH ${TOOLCHAIN_ROOT}/bin) - - set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/clang) - set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/clang++) - set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PATH}/clang) - set(CMAKE_LINKER ${TOOLCHAIN_PATH}/ld.lld) - set(CMAKE_RANLIB ${TOOLCHAIN_PATH}/llvm-ranlib) - set(CMAKE_STRIP ${TOOLCHAIN_PATH}/llvm-strip) - set(CMAKE_AR ${TOOLCHAIN_PATH}/llvm-ar) - set(CMAKE_CXXFILT ${TOOLCHAIN_PATH}/llvm-cxxfilt) - # FIXME: Persuade LLVM maintainers to add `--update-section` to llvm-objcopy, as it's required for the kernel symbol map. - set(CMAKE_OBJCOPY ${TOOLCHAIN_ROOT}/binutils/bin/${SERENITY_ARCH}-pc-serenity-objcopy) -else() - set(TOOLCHAIN_ROOT ${SerenityOS_SOURCE_DIR}/Toolchain/Local/${SERENITY_ARCH}/) - set(TOOLCHAIN_PATH ${TOOLCHAIN_ROOT}/bin) - set(TOOLCHAIN_PREFIX ${TOOLCHAIN_PATH}/${SERENITY_ARCH}-pc-serenity-) - - set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) - set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) - set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}gcc) - set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}ld) - set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}gcc-ranlib) - set(CMAKE_STRIP ${TOOLCHAIN_PREFIX}strip) - set(CMAKE_AR ${TOOLCHAIN_PREFIX}gcc-ar) - set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) - set(CMAKE_CXXFILT ${TOOLCHAIN_PREFIX}c++filt) -endif() - -foreach(lang ASM C CXX OBJC OBJCXX) - unset(CMAKE_${lang}_OSX_COMPATIBILITY_VERSION_FLAG) - unset(CMAKE_${lang}_OSX_CURRENT_VERSION_FLAG) - unset(CMAKE_${lang}_LINK_FLAGS) - unset(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS) - unset(CMAKE_SHARED_MODULE_CREATE_${lang}_FLAGS) - unset(CMAKE_SHARED_MODULE_LOADER_${lang}_FLAG ) - unset(CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG) - unset(CMAKE_${lang}_SYSROOT_FLAG) - if (CMAKE_SYSTEM_NAME MATCHES Darwin) - ## macOS workaround. Use GNU ld flags for SONAMEs. - set(CMAKE_${lang}_CREATE_SHARED_LIBRARY - " -o ") - set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-soname,") - endif() -endforeach() - -set(CMAKE_INSTALL_NAME_TOOL "") -set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") -set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-shared -Wl,--hash-style=gnu,-z,relro,-z,now,-z,noexecstack,-z,separate-code") -set(CMAKE_CXX_LINK_FLAGS "-Wl,--hash-style=gnu,-z,relro,-z,now,-z,noexecstack,-z,max-page-size=0x1000,-z,separate-code") - # We disable it completely because it makes cmake very spammy. # This will need to be revisited when the Loader supports RPATH/RUN_PATH. set(CMAKE_SKIP_RPATH TRUE) -add_compile_options(-Wformat=2) -add_compile_options(-fdiagnostics-color=always) +add_compile_options(-Wall) +add_compile_options(-Wextra) -if (NOT ${CMAKE_HOST_SYSTEM_NAME} MATCHES SerenityOS) +if (NOT CMAKE_HOST_SYSTEM_NAME MATCHES SerenityOS) # FIXME: Something makes this go crazy and flag unused variables that aren't flagged as such when building with the toolchain. # Disable -Werror for now. add_compile_options(-Werror) endif() -add_compile_options(-Wall) -add_compile_options(-Wextra) - # The following warnings are sorted by the "base" name (the part excluding the initial Wno or W). add_compile_options(-Wno-address-of-packed-member) add_compile_options(-Wcast-qual) @@ -254,15 +172,24 @@ add_compile_options(-Wno-unused-command-line-argument) add_compile_options(-Wwrite-strings) add_compile_options(-Wno-maybe-uninitialized) +add_compile_options(-fdiagnostics-color=always) +add_compile_options(-fno-delete-null-pointer-checks) add_compile_options(-ffile-prefix-map=${SerenityOS_SOURCE_DIR}=.) add_compile_options(-fno-exceptions) add_compile_options(-ftls-model=initial-exec) add_compile_options(-fno-semantic-interposition) +add_compile_options(-fsized-deallocation) add_compile_options(-fstack-clash-protection) add_compile_options(-fstack-protector-strong) add_compile_options(-g1) -if (USE_CLANG_TOOLCHAIN) +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + add_compile_options(-Wno-literal-suffix) + add_compile_options(-Wcast-align) + add_compile_options(-Wdouble-promotion) +elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang$") + add_compile_options(-Wno-overloaded-virtual) + add_compile_options(-Wno-user-defined-literals) add_compile_options(-Wno-atomic-alignment) add_compile_options(-Wno-c99-designator) add_compile_options(-Wno-implicit-const-int-float-conversion) @@ -270,24 +197,13 @@ if (USE_CLANG_TOOLCHAIN) add_compile_options(-Wno-tautological-constant-out-of-range-compare) add_compile_options(-Wno-unneeded-internal-declaration) add_compile_options(-Wno-unused-function) - add_compile_options(-Wno-user-defined-literals) - # Without the 'SHELL' prefix, this would get removed through de-duplication with the flags set for the host compiler. - # Then, that would come before '-Wextra', so it would not negate the '-Woverloaded-virtual' set by '-Wextra'. - add_compile_options(SHELL:-Wno-overloaded-virtual) - - add_compile_options(--sysroot=${CMAKE_BINARY_DIR}/Root) - add_compile_options(--target=${SERENITY_CLANG_ARCH}-pc-serenity) add_compile_options(-fno-aligned-allocation) add_compile_options(-fconstexpr-steps=16777216) add_compile_options(-gdwarf-4) - # FIXME: Why is Clang not picking up this path? - link_directories(${TOOLCHAIN_ROOT}/lib/clang/${LLVM_VERSION}/lib/serenity) - + # FIXME: Why can't clang find this path for compiler_rt builtins? + link_directories(${TOOLCHAIN_ROOT}/lib/clang/${CMAKE_CXX_COMPILER_VERSION}/lib/serenity) add_link_options(LINKER:--allow-shlib-undefined) -else() - add_compile_options(-Wcast-align) - add_compile_options(-Wdouble-promotion) endif() add_link_options(LINKER:-z,text) @@ -306,7 +222,6 @@ if (ENABLE_COMPILETIME_FORMAT_CHECK) add_compile_definitions(ENABLE_COMPILETIME_FORMAT_CHECK) endif() -add_link_options(--sysroot ${CMAKE_BINARY_DIR}/Root) add_link_options(-Wno-unused-command-line-argument) include_directories(.) @@ -326,7 +241,8 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/Userland) # FIXME: vptr sanitizing requires.. intense ABI wrangling of std::type_info # And would be better served by porting ubsan_type_hash_itanium.cpp from compiler-rt if (ENABLE_UNDEFINED_SANITIZER) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize=vptr") + add_compile_options(-fsanitize=undefined -fno-sanitize=vptr) + add_link_options(-fsanitize=undefined -fno-sanitize=vptr) endif() add_custom_target(components ALL) diff --git a/Kernel/CMakeLists.txt b/Kernel/CMakeLists.txt index eb045e5843..83c3ee8015 100644 --- a/Kernel/CMakeLists.txt +++ b/Kernel/CMakeLists.txt @@ -360,44 +360,42 @@ else() ) endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-warning-option -Wvla -Wnull-dereference") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -ffreestanding -fbuiltin") - +add_compile_options(-Wno-unknown-warning-option -Wvla -Wnull-dereference) +add_compile_options(-fno-rtti -ffreestanding -fbuiltin) if ("${SERENITY_ARCH}" STREQUAL "i686" OR "${SERENITY_ARCH}" STREQUAL "x86_64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mno-80387 -mno-mmx -mno-sse -mno-sse2") + add_compile_options(-mno-80387 -mno-mmx -mno-sse -mno-sse2) endif() - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-asynchronous-unwind-tables") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fstack-protector-strong") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") +add_compile_options(-fno-asynchronous-unwind-tables) +add_compile_options(-fstack-protector-strong) +add_compile_options(-fno-exceptions) # FIXME: remove -nodefaultlibs after the next toolchain update -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nodefaultlibs -nostdlib") +add_compile_options(-nodefaultlibs -nostdlib) -if (USE_CLANG_TOOLCHAIN) +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + # Apply any flags that are only available on >= GCC 11.1 + if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "11.1") + # Zero any registers used within a function on return (to reduce data lifetime and ROP gadgets). + add_compile_options(-fzero-call-used-regs=used-gpr) + endif() + link_directories(${TOOLCHAIN_ROOT}/${SERENITY_ARCH}-pc-serenity/lib) + link_directories(${TOOLCHAIN_ROOT}/lib/gcc/${SERENITY_ARCH}-pc-serenity/${GCC_VERSION}/) +else() # Assume Clang add_compile_options(-Waddress-of-packed-member) -endif() - -# Apply any flags that are only available on >= GCC 11.1 -if (NOT USE_CLANG_TOOLCHAIN AND CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 11.1) - # Zero any registers used within a function on return (to reduce data lifetime and ROP gadgets). - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fzero-call-used-regs=used-gpr") -endif() - -if (NOT USE_CLANG_TOOLCHAIN) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc -nostdinc++") + add_compile_options(-faligned-allocation) + + add_link_options(LINKER:--build-id=none) endif() macro (set_new_alignment alignment) - if (USE_CLANG_TOOLCHAIN) - add_compile_options(-faligned-allocation) - add_compile_options(-fnew-alignment=${alignment}) - else() + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") add_compile_options(-faligned-new=${alignment}) + elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang$") + add_compile_options(-fnew-alignment=${alignment}) endif() endmacro() if ("${SERENITY_ARCH}" STREQUAL "x86_64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcmodel=large -mno-red-zone") + add_compile_options(-mcmodel=large -mno-red-zone) set_new_alignment(8) else() set_new_alignment(4) @@ -443,41 +441,15 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") # if (ENABLE_KERNEL_ADDRESS_SANITIZER) add_compile_options(-fsanitize=kernel-address) + add_link_options(-fsanitize=kernel-address) endif() add_compile_definitions(KERNEL) - -# HACK: This is a workaround for CLion to grok the kernel sources. -# It's needed because CLion doesn't understand the way we switch compilers mid-build. -add_compile_definitions(__serenity__) - add_link_options(LINKER:-z,notext) -if (USE_CLANG_TOOLCHAIN) - add_link_options(LINKER:--build-id=none) -endif() - if (NOT "${SERENITY_ARCH}" STREQUAL "aarch64") add_library(kernel_heap STATIC ${KERNEL_HEAP_SOURCES}) endif() - -if (${CMAKE_HOST_SYSTEM_NAME} MATCHES SerenityOS) - include_directories(/usr/local/include/c++/${GCC_VERSION}/) -elseif (USE_CLANG_TOOLCHAIN) - include_directories("${TOOLCHAIN_ROOT}/include/c++/v1") -else() - if (NOT EXISTS ${TOOLCHAIN_ROOT}/${SERENITY_ARCH}-pc-serenity/include/c++/${GCC_VERSION}/) - message(FATAL_ERROR "Toolchain version ${GCC_VERSION} (${SERENITY_ARCH}) appears to be missing! Please run: Meta/serenity.sh rebuild-toolchain ${SERENITY_ARCH}") - endif() - include_directories(${TOOLCHAIN_ROOT}/${SERENITY_ARCH}-pc-serenity/include/c++/${GCC_VERSION}/) - include_directories(${TOOLCHAIN_ROOT}/${SERENITY_ARCH}-pc-serenity/include/c++/${GCC_VERSION}/${SERENITY_ARCH}-pc-serenity/) -endif() - -if (NOT USE_CLANG_TOOLCHAIN) - link_directories(${TOOLCHAIN_ROOT}/${SERENITY_ARCH}-pc-serenity/lib) - link_directories(${TOOLCHAIN_ROOT}/lib/gcc/${SERENITY_ARCH}-pc-serenity/${GCC_VERSION}/) -endif() - add_executable(Kernel ${SOURCES}) add_dependencies(Kernel generate_EscapeSequenceStateMachine.h) @@ -490,8 +462,7 @@ add_custom_command( ) add_custom_target(generate_kernel_linker_script DEPENDS linker.ld) - -target_link_options(Kernel PRIVATE LINKER:-T ${CMAKE_CURRENT_BINARY_DIR}/linker.ld -nostdlib) +target_link_options(Kernel PRIVATE LINKER:-T ${CMAKE_CURRENT_BINARY_DIR}/linker.ld -nostdlib -nodefaultlibs) set_target_properties(Kernel PROPERTIES LINK_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/linker.ld") if (ENABLE_KERNEL_LTO) @@ -501,16 +472,13 @@ if (ENABLE_KERNEL_LTO) endif() if (NOT "${SERENITY_ARCH}" STREQUAL "aarch64") - if (USE_CLANG_TOOLCHAIN) - target_link_libraries(Kernel kernel_heap clang_rt.builtins-${SERENITY_CLANG_ARCH}) - else() - target_link_libraries(Kernel kernel_heap gcc) + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_link_libraries(Kernel PRIVATE kernel_heap gcc) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang$") + target_link_libraries(Kernel PRIVATE kernel_heap "clang_rt.builtins-${SERENITY_CLANG_ARCH}") endif() - - add_dependencies(Kernel kernel_heap) endif() - add_custom_command( TARGET Kernel POST_BUILD COMMAND ${CMAKE_COMMAND} -E env CXXFILT=${CMAKE_CXXFILT} sh ${CMAKE_CURRENT_SOURCE_DIR}/mkmap.sh diff --git a/Kernel/Prekernel/CMakeLists.txt b/Kernel/Prekernel/CMakeLists.txt index 1da2421bae..6d1d7704d8 100644 --- a/Kernel/Prekernel/CMakeLists.txt +++ b/Kernel/Prekernel/CMakeLists.txt @@ -43,10 +43,10 @@ target_compile_options(${PREKERNEL_TARGET} PRIVATE -no-pie -fno-pic -fno-threads target_link_options(${PREKERNEL_TARGET} PRIVATE LINKER:-T ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld -nostdlib LINKER:--no-pie) set_target_properties(${PREKERNEL_TARGET} PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld) -if (USE_CLANG_TOOLCHAIN) - target_link_libraries(${PREKERNEL_TARGET} clang_rt.builtins-${SERENITY_CLANG_ARCH} c++abi) -else() - target_link_libraries(${PREKERNEL_TARGET} gcc) +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_link_libraries(${PREKERNEL_TARGET} PRIVATE kernel_heap gcc) +elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang$") + target_link_libraries(${PREKERNEL_TARGET} PRIVATE kernel_heap "clang_rt.builtins-${SERENITY_CLANG_ARCH}" c++abi) endif() if ("${SERENITY_ARCH}" STREQUAL "i686" OR "${SERENITY_ARCH}" STREQUAL "x86_64") diff --git a/Meta/Azure/Serenity.yml b/Meta/Azure/Serenity.yml index 42a406fe0f..04f3af3281 100644 --- a/Meta/Azure/Serenity.yml +++ b/Meta/Azure/Serenity.yml @@ -21,7 +21,7 @@ jobs: parameters: arch: '${{ parameters.arch }}' toolchain: 'clang' - build_directory: 'Build' + build_directory: 'Build/${{ parameters.arch }}clang' - script: ./Toolchain/BuildClang.sh displayName: Build Toolchain @@ -30,31 +30,30 @@ jobs: ARCH: '${{ parameters.arch }}' - script: | - mkdir -p Build + mkdir -p Build/superbuild displayName: 'Create Build Directory' - script: | - cmake -GNinja \ + cmake -S Meta/CMake/Superbuild -B Build/superbuild -GNinja \ -DSERENITY_ARCH=${{ parameters.arch }} \ - -DUSE_CLANG_TOOLCHAIN=ON \ + -DSERENITY_TOOLCHAIN=Clang \ -DENABLE_UNDEFINED_SANITIZER=ON \ -DENABLE_PCI_IDS_DOWNLOAD=OFF \ -DENABLE_USB_IDS_DOWNLOAD=OFF \ -DCMAKE_C_COMPILER=gcc-10 \ - -DCMAKE_CXX_COMPILER=g++-10 \ - .. + -DCMAKE_CXX_COMPILER=g++-10 displayName: 'Create Build Environment' - workingDirectory: $(Build.SourcesDirectory)/Build + workingDirectory: $(Build.SourcesDirectory) - script: | - cmake --build . + cmake --build ./Build/superbuild displayName: 'Build' - workingDirectory: $(Build.SourcesDirectory)/Build + workingDirectory: $(Build.SourcesDirectory) - script: | ninja install && ninja image displayName: 'Create RootFS' - workingDirectory: $(Build.SourcesDirectory)/Build + workingDirectory: $(Build.SourcesDirectory)/Build/${{ parameters.arch }}clang - script: | ninja run @@ -73,7 +72,7 @@ jobs: exit 1 fi displayName: 'Test' - workingDirectory: $(Build.SourcesDirectory)/Build + workingDirectory: $(Build.SourcesDirectory)/Build/${{ parameters.arch }}clang timeoutInMinutes: 60 env: SERENITY_QEMU_CPU: 'max,vmx=off' @@ -83,7 +82,7 @@ jobs: - script: | [ ! -e debug.log ] || cat debug.log displayName: 'Print Target Logs' - workingDirectory: $(Build.SourcesDirectory)/Build + workingDirectory: $(Build.SourcesDirectory)/Build/${{ parameters.arch }}clang condition: failed() - script: | diff --git a/Meta/CMake/Superbuild/CMakeLists.txt b/Meta/CMake/Superbuild/CMakeLists.txt new file mode 100644 index 0000000000..b1c7128b8f --- /dev/null +++ b/Meta/CMake/Superbuild/CMakeLists.txt @@ -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=" + "-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) diff --git a/Meta/CMake/utils.cmake b/Meta/CMake/utils.cmake index d2e315ffec..f992c7c11a 100644 --- a/Meta/CMake/utils.cmake +++ b/Meta/CMake/utils.cmake @@ -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 "") diff --git a/Meta/Lagom/CMakeLists.txt b/Meta/Lagom/CMakeLists.txt index 69fcdd6a5c..e9f02ac40c 100644 --- a/Meta/Lagom/CMakeLists.txt +++ b/Meta/Lagom/CMakeLists.txt @@ -8,9 +8,10 @@ project( LANGUAGES C CXX ) -option(BUILD_SHARED_LIBS "Build shared libraries instead of static libraries" ON) -if (ENABLE_OSS_FUZZ) - set(BUILD_SHARED_LIBS OFF) # Don't use shared libraries on oss-fuzz, for ease of integration with their infrastructure +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "10.2") + message(FATAL_ERROR + "A GCC version less than 10.2 was detected (${CMAKE_CXX_COMPILER_VERSION}), this is unsupported.\n" + "Please re-read the build instructions documentation, and upgrade your host compiler.\n") endif() # This is required for CMake (when invoked for a Lagom-only build) to @@ -33,12 +34,22 @@ endif() include(lagom_options) +if(ENABLE_ALL_THE_DEBUG_MACROS) + include(all_the_debug_macros) +endif() + +option(BUILD_SHARED_LIBS "Build shared libraries instead of static libraries" ON) +if (ENABLE_OSS_FUZZ) + set(BUILD_SHARED_LIBS OFF) # Don't use shared libraries on oss-fuzz, for ease of integration with their infrastructure +endif() + find_package(Threads REQUIRED) if (ENABLE_LAGOM_CCACHE) find_program(CCACHE_PROGRAM ccache) if(CCACHE_PROGRAM) - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}") + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE FILEPATH "Path to a compiler launcher program, e.g. ccache") + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE FILEPATH "Path to a compiler launcher program, e.g. ccache") endif() endif() @@ -58,7 +69,7 @@ set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) # See slide 100 of the following ppt :^) # https://crascit.com/wp-content/uploads/2019/09/Deep-CMake-For-Library-Authors-Craig-Scott-CppCon-2019.pdf if (NOT APPLE) - set(CMAKE_INSTALL_RPATH $ORIGIN) + set(CMAKE_INSTALL_RPATH $ORIGIN:$ORIGIN/../lib) endif() set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) @@ -79,7 +90,7 @@ if (ENABLE_UNDEFINED_SANITIZER) set(LINKER_FLAGS "${LINKER_FLAGS} -fsanitize=undefined -fno-sanitize=vptr") endif() -if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang$") +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang$") # Clang's default constexpr-steps limit is 1048576(2^20), GCC doesn't have one add_compile_options(-Wno-overloaded-virtual -Wno-user-defined-literals -fconstexpr-steps=16777216) @@ -88,7 +99,7 @@ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang$") set(LINKER_FLAGS "${LINKER_FLAGS} -fsanitize=fuzzer") endif() -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") add_compile_options(-Wno-expansion-to-defined) endif() @@ -101,11 +112,7 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINKER_FLAGS}") set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}") set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}") -# FIXME: This is a hack, because the lagom stuff can be built individually or -# in combination with the system, we generate two Debug.h files. One in -# Build/AK/Debug.h and the other in Build/Meta/Lagom/AK/Debug.h. configure_file(../../AK/Debug.h.in AK/Debug.h @ONLY) -configure_file(../../Kernel/Debug.h.in Kernel/Debug.h @ONLY) include_directories(../../) include_directories(../../Userland/) @@ -114,59 +121,36 @@ include_directories(${CMAKE_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR}) # install rules, think about moving to its own helper cmake file -# Don't install Lagom libs into the target Root/ -# FIXME: Remove this check for 4594 -if (CMAKE_SOURCE_DIR MATCHES ".*/Lagom") - include(CMakePackageConfigHelpers) - include(GNUInstallDirs) +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) - # find_package() call for consumers to find this project - set(package Lagom) +# find_package() call for consumers to find this project +set(package Lagom) - write_basic_package_version_file( - "${package}ConfigVersion.cmake" - COMPATIBILITY SameMajorVersion - ) +# Allow package maintainers to freely override the path for the configs +set(Lagom_INSTALL_CMAKEDIR "${CMAKE_INSTALL_DATADIR}/${package}" + CACHE PATH "CMake package config location relative to the install prefix") +mark_as_advanced(Lagom_INSTALL_CMAKEDIR) - # Allow package maintainers to freely override the path for the configs - set(Lagom_INSTALL_CMAKEDIR "${CMAKE_INSTALL_DATADIR}/${package}" - CACHE PATH "CMake package config location relative to the install prefix") - mark_as_advanced(Lagom_INSTALL_CMAKEDIR) +install( + FILES "${SERENITY_PROJECT_ROOT}/Meta/CMake/lagom-install-config.cmake" + DESTINATION "${Lagom_INSTALL_CMAKEDIR}" + RENAME "${package}Config.cmake" + COMPONENT Lagom_Development +) - install( - FILES ${SERENITY_PROJECT_ROOT}/Meta/CMake/lagom-install-config.cmake - DESTINATION "${Lagom_INSTALL_CMAKEDIR}" - RENAME "${package}Config.cmake" - COMPONENT Lagom_Development - ) - - install( - FILES "${PROJECT_BINARY_DIR}/${package}ConfigVersion.cmake" - DESTINATION "${Lagom_INSTALL_CMAKEDIR}" - COMPONENT Lagom_Development - ) - - install( - EXPORT LagomTargets - NAMESPACE Lagom:: - DESTINATION "${Lagom_INSTALL_CMAKEDIR}" - COMPONENT Lagom_Development - ) - - # Manually install AK - install( - DIRECTORY "${SERENITY_PROJECT_ROOT}/AK" - COMPONENT Lagom_Development - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING PATTERN "*.h" - ) -endif() +install( + EXPORT LagomTargets + NAMESPACE Lagom:: + DESTINATION "${Lagom_INSTALL_CMAKEDIR}" + COMPONENT Lagom_Development +) function(lagom_lib library fs_name) cmake_parse_arguments(LAGOM_LIBRARY "" "" "SOURCES;LIBS" ${ARGN}) set(target_name "Lagom${library}") add_library(${target_name} ${LAGOM_LIBRARY_SOURCES}) - # alias for pretty exports + # alias for parity with exports add_library(Lagom::${library} ALIAS ${target_name}) set_target_properties( @@ -180,29 +164,25 @@ function(lagom_lib library fs_name) if (NOT ${target_name} STREQUAL "LagomCore") target_link_libraries(${target_name} LagomCore) endif() - # Don't install Lagom libs into the target Root/ - # FIXME: Remove this check for 4594 - if (CMAKE_SOURCE_DIR MATCHES ".*/Lagom") - install( - TARGETS ${target_name} - EXPORT LagomTargets - RUNTIME # - COMPONENT Lagom_Runtime - LIBRARY # - COMPONENT Lagom_Runtime - NAMELINK_COMPONENT Lagom_Development - ARCHIVE # - COMPONENT Lagom_Development - INCLUDES # - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ) - install( - DIRECTORY "${SERENITY_PROJECT_ROOT}/Userland/Libraries/Lib${library}" + install( + TARGETS ${target_name} + EXPORT LagomTargets + RUNTIME # + COMPONENT Lagom_Runtime + LIBRARY # + COMPONENT Lagom_Runtime + NAMELINK_COMPONENT Lagom_Development + ARCHIVE # COMPONENT Lagom_Development + INCLUDES # DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - FILES_MATCHING PATTERN "*.h" - ) - endif() + ) + install( + DIRECTORY "${SERENITY_PROJECT_ROOT}/Userland/Libraries/Lib${library}" + COMPONENT Lagom_Development + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.h" + ) endfunction() function(lagom_test source) @@ -229,6 +209,14 @@ if (NOT APPLE) target_link_libraries(LagomCore crypt) # Core::Account uses crypt() but it's not in libcrypt on macOS endif() +# Manually install AK headers +install( + DIRECTORY "${SERENITY_PROJECT_ROOT}/AK" + COMPONENT Lagom_Development + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FILES_MATCHING PATTERN "*.h" +) + # Code Generators and other host tools # We need to make sure not to build code generators for Fuzzer builds, as they already have their own main.cpp if (NOT ENABLE_OSS_FUZZ AND NOT ENABLE_FUZZER_SANITIZER) diff --git a/Meta/build-root-filesystem.sh b/Meta/build-root-filesystem.sh index 33cbe10c49..3dd09ceaf0 100755 --- a/Meta/build-root-filesystem.sh +++ b/Meta/build-root-filesystem.sh @@ -48,7 +48,7 @@ fi SERENITY_ARCH="${SERENITY_ARCH:-i686}" LLVM_VERSION="${LLVM_VERSION:-12.0.1}" -if [ "$USE_CLANG_TOOLCHAIN" = "1" ]; then +if [ "$SERENITY_TOOLCHAIN" = "Clang" ]; then TOOLCHAIN_DIR="$SERENITY_SOURCE_DIR"/Toolchain/Local/clang/"$SERENITY_ARCH" mkdir -p mnt/usr/lib/clang/"$LLVM_VERSION"/lib/serenity $CP "$TOOLCHAIN_DIR"/lib/clang/"$LLVM_VERSION"/lib/serenity/* mnt/usr/lib/clang/"$LLVM_VERSION"/lib/serenity diff --git a/Toolchain/CMake/CMakeToolchain.txt b/Toolchain/CMake/CMakeToolchain.txt deleted file mode 100644 index 6c30b7d98f..0000000000 --- a/Toolchain/CMake/CMakeToolchain.txt +++ /dev/null @@ -1,33 +0,0 @@ -set(CMAKE_SYSTEM_NAME SerenityOS) - -if (NOT DEFINED ENV{SERENITY_ARCH}) - message(FATAL_ERROR "SERENITY_ARCH not set.") -endif() - -if (NOT DEFINED ENV{SERENITY_SOURCE_DIR}) - message(FATAL_ERROR "SERENITY_SOURCE_DIR not set.") -endif() - -set(SERENITYOS 1) - -set(CMAKE_SYSTEM_PROCESSOR "$ENV{SERENITY_ARCH}") - -set(SERENITY_BUILD_DIR $ENV{SERENITY_SOURCE_DIR}/Build/$ENV{SERENITY_ARCH}) - -# where to read from/write to -set(CMAKE_SYSROOT ${SERENITY_BUILD_DIR}/Root) -set(CMAKE_STAGING_PREFIX ${SERENITY_BUILD_DIR}/Root/usr/local) -set(CMAKE_INSTALL_PREFIX ${SERENITY_BUILD_DIR}/Root/usr/local) -set(CMAKE_INSTALL_DATAROOTDIR ${SERENITY_BUILD_DIR}/Root/usr/local/share) - -set(CMAKE_AR $ENV{SERENITY_ARCH}-pc-serenity-gcc-ar) -set(CMAKE_RANLIB $ENV{SERENITY_ARCH}-pc-serenity-gcc-ranlib) -set(CMAKE_C_COMPILER $ENV{SERENITY_ARCH}-pc-serenity-gcc) -set(CMAKE_CXX_COMPILER $ENV{SERENITY_ARCH}-pc-serenity-g++) - -set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) -set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - -list(APPEND CMAKE_MODULE_PATH "$ENV{SERENITY_SOURCE_DIR}/Toolchain/CMake") diff --git a/Toolchain/CMake/ClangToolchain.txt.in b/Toolchain/CMake/ClangToolchain.txt.in new file mode 100644 index 0000000000..10f123bee9 --- /dev/null +++ b/Toolchain/CMake/ClangToolchain.txt.in @@ -0,0 +1,41 @@ +list(APPEND CMAKE_MODULE_PATH "@SERENITY_SOURCE_DIR@/Toolchain/CMake") + +set(CMAKE_SYSTEM_NAME SerenityOS) +set(CMAKE_SYSTEM_PROCESSOR "@SERENITY_ARCH@") + +set(SERENITYOS 1) +set(triple @SERENITY_ARCH@-pc-serenity) +set(TOOLCHAIN_ROOT @SERENITY_SOURCE_DIR@/Toolchain/Local/clang/@SERENITY_ARCH@) +set(TOOLCHAIN_PATH ${TOOLCHAIN_ROOT}/bin) + +# where to read from/write to +set(CMAKE_SYSROOT @SERENITY_BUILD_DIR@/Root) +set(CMAKE_STAGING_PREFIX @SERENITY_BUILD_DIR@/Root/usr/local) +set(CMAKE_INSTALL_PREFIX @SERENITY_BUILD_DIR@/Root/usr/local) +set(CMAKE_INSTALL_DATAROOTDIR @SERENITY_BUILD_DIR@/Root/usr/local/share) + +set(CMAKE_C_COMPILER ${TOOLCHAIN_PATH}/clang) +set(CMAKE_C_COMPILER_TARGET ${triple}) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PATH}/clang++) +set(CMAKE_CXX_COMPILER_TARGET ${triple}) +set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PATH}/clang) +set(CMAKE_ASM_COMPILER_TARGET ${triple}) +set(CMAKE_LINKER ${TOOLCHAIN_PATH}/ld.lld) +set(CMAKE_RANLIB ${TOOLCHAIN_PATH}/llvm-ranlib) +set(CMAKE_STRIP ${TOOLCHAIN_PATH}/llvm-strip) +set(CMAKE_AR ${TOOLCHAIN_PATH}/llvm-ar) +set(CMAKE_CXXFILT ${TOOLCHAIN_PATH}/llvm-cxxfilt) +# FIXME: Persuade LLVM maintainers to add `--update-section` to llvm-objcopy, as it's required for the kernel symbol map. +set(CMAKE_OBJCOPY ${TOOLCHAIN_ROOT}/binutils/bin/@SERENITY_ARCH@-pc-serenity-objcopy) + +set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,--hash-style=gnu,-z,relro,-z,now,-z,noexecstack,-z,max-page-size=0x1000,-z,separate-code") + +# FIXME: We could eliminate this setting by building LibC and support asm files (crti.o, crtn.o) +# in a separate build stage before the main build to ensure that LibC is available +# for the try_compile check for the main build. +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) diff --git a/Toolchain/CMake/GNUToolchain.txt.in b/Toolchain/CMake/GNUToolchain.txt.in new file mode 100644 index 0000000000..9a0a2efdc8 --- /dev/null +++ b/Toolchain/CMake/GNUToolchain.txt.in @@ -0,0 +1,37 @@ +list(APPEND CMAKE_MODULE_PATH "@SERENITY_SOURCE_DIR@/Toolchain/CMake") + +set(CMAKE_SYSTEM_NAME SerenityOS) +set(CMAKE_SYSTEM_PROCESSOR "@SERENITY_ARCH@") + +set(SERENITYOS 1) +set(triple @SERENITY_ARCH@-pc-serenity) +set(TOOLCHAIN_PATH @SERENITY_SOURCE_DIR@/Toolchain/Local/@SERENITY_ARCH@/bin) +set(TOOLCHAIN_PREFIX ${TOOLCHAIN_PATH}/${triple}-) + +# where to read from/write to +set(CMAKE_SYSROOT @SERENITY_BUILD_DIR@/Root) +set(CMAKE_STAGING_PREFIX @SERENITY_BUILD_DIR@/Root/usr/local) +set(CMAKE_INSTALL_PREFIX @SERENITY_BUILD_DIR@/Root/usr/local) +set(CMAKE_INSTALL_DATAROOTDIR @SERENITY_BUILD_DIR@/Root/usr/local/share) + +set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc) +set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++) +set(CMAKE_ASM_COMPILER ${TOOLCHAIN_PREFIX}gcc) +set(CMAKE_LINKER ${TOOLCHAIN_PREFIX}ld) +set(CMAKE_RANLIB ${TOOLCHAIN_PREFIX}gcc-ranlib) +set(CMAKE_STRIP ${TOOLCHAIN_PREFIX}strip) +set(CMAKE_AR ${TOOLCHAIN_PREFIX}gcc-ar) +set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy) +set(CMAKE_CXXFILT ${TOOLCHAIN_PREFIX}c++filt) + +set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,--hash-style=gnu,-z,relro,-z,now,-z,noexecstack,-z,max-page-size=0x1000,-z,separate-code") + +# FIXME: We could eliminate this setting by building LibC and support asm files (crti.o, crtn.o) +# in a separate build stage before the main build to ensure that LibC is available +# for the try_compile check for the main build. +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) diff --git a/Toolchain/CMake/Platform/SerenityOS.cmake b/Toolchain/CMake/Platform/SerenityOS.cmake index 38dfda3ad1..fecf81df92 100644 --- a/Toolchain/CMake/Platform/SerenityOS.cmake +++ b/Toolchain/CMake/Platform/SerenityOS.cmake @@ -5,6 +5,8 @@ set(CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN "\$ORIGIN") set(CMAKE_SHARED_LIBRARY_RPATH_LINK_C_FLAG "-Wl,-rpath-link,") set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-soname,") set(CMAKE_EXE_EXPORTS_C_FLAG "-Wl,--export-dynamic") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".so") +set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-shared -Wl,--hash-style=gnu,-z,relro,-z,now,-z,noexecstack,-z,separate-code") # Initialize C link type selection flags. These flags are used when # building a shared library, shared module, or executable that links diff --git a/Userland/DynamicLoader/CMakeLists.txt b/Userland/DynamicLoader/CMakeLists.txt index 1e4e3ad764..31f46e3de2 100644 --- a/Userland/DynamicLoader/CMakeLists.txt +++ b/Userland/DynamicLoader/CMakeLists.txt @@ -39,11 +39,10 @@ set_source_files_properties(../Libraries/LibC/stdio.cpp PROPERTIES COMPILE_FLAGS add_executable(Loader.so ${SOURCES}) -if (USE_CLANG_TOOLCHAIN) - target_link_libraries(Loader.so clang_rt.builtins-${SERENITY_CLANG_ARCH}) -else() - target_link_libraries(Loader.so gcc) -endif() - +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_link_libraries(Loader.so PRIVATE gcc) +elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang$") + target_link_libraries(Loader.so PRIVATE "clang_rt.builtins-${SERENITY_CLANG_ARCH}") +endif () target_link_options(Loader.so PRIVATE LINKER:--no-dynamic-linker) install(TARGETS Loader.so RUNTIME DESTINATION usr/lib/) diff --git a/Userland/Libraries/LibC/CMakeLists.txt b/Userland/Libraries/LibC/CMakeLists.txt index 5ad420f047..48a627d85e 100644 --- a/Userland/Libraries/LibC/CMakeLists.txt +++ b/Userland/Libraries/LibC/CMakeLists.txt @@ -119,7 +119,7 @@ add_custom_command( set(SOURCES ${LIBC_SOURCES} ${AK_SOURCES} ${ELF_SOURCES} ${ASM_SOURCES}) -if (NOT USE_CLANG_TOOLCHAIN) +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++") endif()