-
Notifications
You must be signed in to change notification settings - Fork 101
Move CMake code for building multilib and variants to subprojects #562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
454b3dd
Move CMake code for building multilib and variants to subprojects
dcandler 8314dc0
fixup! Move CMake code for building multilib and variants to subprojects
dcandler 1d393b0
fixup! Move CMake code for building multilib and variants to subprojects
dcandler 61e2c74
fixup! Move CMake code for building multilib and variants to subprojects
dcandler File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,282 @@ | ||
| # | ||
| # Copyright (c) 2024, Arm Limited and affiliates. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| # | ||
|
|
||
| # CMake build for a multilib layout of library variants, with each | ||
| # variant in a subdirectory and a multilib.yaml file to map flags to | ||
| # a variant. | ||
|
|
||
| cmake_minimum_required(VERSION 3.20) | ||
|
|
||
| project(arm-multilib) | ||
|
|
||
| # Root directory of the repo. | ||
| set(TOOLCHAIN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) | ||
|
|
||
| # Cache variables to be set by user | ||
| set(MULTILIB_JSON "" CACHE STRING "JSON file to load library definitions from.") | ||
| set(ENABLE_VARIANTS "all" CACHE STRING "Semicolon separated list of variants to build, or \"all\". Must match entries in the json.") | ||
| set(C_LIBRARY "picolibc" CACHE STRING "Which C library to use.") | ||
| set_property(CACHE C_LIBRARY PROPERTY STRINGS picolibc newlib llvmlibc) | ||
| set(LLVM_BINARY_DIR "" CACHE PATH "Path to LLVM toolchain build or install root.") | ||
| set(LIBC_HDRGEN "" CACHE PATH "Path to prebuilt lbc-hdrgen if not included in LLVM binaries set by LLVM_BINARY_DIR") | ||
| set( | ||
| FVP_INSTALL_DIR | ||
| "" CACHE STRING | ||
| "The directory in which the FVP models are installed. These are not | ||
| included in this repository, but can be downloaded by the script | ||
| fvp/get_fvps.sh" | ||
| ) | ||
| set(FVP_CONFIG_DIR "${TOOLCHAIN_SOURCE_DIR}/fvp/config" CACHE STRING "The directory in which the FVP models are installed.") | ||
|
|
||
| # If a compiler launcher such as ccache has been set, it should be | ||
| # passed down to each subproject build. | ||
| set(compiler_launcher_cmake_args "") | ||
| if(CMAKE_C_COMPILER_LAUNCHER) | ||
| list(APPEND compiler_launcher_cmake_args "-DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER}") | ||
| endif() | ||
| if(CMAKE_CXX_COMPILER_LAUNCHER) | ||
| list(APPEND compiler_launcher_cmake_args "-DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER}") | ||
| endif() | ||
|
|
||
| # Arguments to pass down to the library projects. | ||
| foreach(arg | ||
| LLVM_BINARY_DIR | ||
| LIBC_HDRGEN | ||
| FVP_INSTALL_DIR | ||
| FVP_CONFIG_DIR | ||
| ) | ||
| if(${arg}) | ||
| list(APPEND passthrough_dirs "-D${arg}=${${arg}}") | ||
| endif() | ||
| endforeach() | ||
|
|
||
| include(ExternalProject) | ||
| include(${TOOLCHAIN_SOURCE_DIR}/cmake/fetch_llvm.cmake) | ||
| list(APPEND passthrough_dirs "-DFETCHCONTENT_SOURCE_DIR_LLVMPROJECT=${FETCHCONTENT_SOURCE_DIR_LLVMPROJECT}") | ||
| if(C_LIBRARY STREQUAL picolibc) | ||
| include(${TOOLCHAIN_SOURCE_DIR}/cmake/fetch_picolibc.cmake) | ||
| list(APPEND passthrough_dirs "-DFETCHCONTENT_SOURCE_DIR_PICOLIBC=${FETCHCONTENT_SOURCE_DIR_PICOLIBC}") | ||
| elseif(C_LIBRARY STREQUAL newlib) | ||
| include(${TOOLCHAIN_SOURCE_DIR}/cmake/fetch_newlib.cmake) | ||
| list(APPEND passthrough_dirs "-DFETCHCONTENT_SOURCE_DIR_NEWLIB=${FETCHCONTENT_SOURCE_DIR_NEWLIB}") | ||
| endif() | ||
|
|
||
| # Target for any dependencies to build the runtimes project. | ||
| add_custom_target(runtimes-depends) | ||
|
|
||
| # If building llvm-libc, ensure libc-hdrgen is available. | ||
| if(C_LIBRARY STREQUAL llvmlibc) | ||
| if(NOT LIBC_HDRGEN) | ||
| if(EXISTS ${LLVM_BINARY_DIR}/bin/libc-hdrgen${CMAKE_EXECUTABLE_SUFFIX}) | ||
| set(LIBC_HDRGEN ${LLVM_BINARY_DIR}/bin/libc-hdrgen${CMAKE_EXECUTABLE_SUFFIX}) | ||
| else() | ||
| ExternalProject_Add( | ||
| libc_hdrgen | ||
| SOURCE_DIR ${llvmproject_SOURCE_DIR}/llvm | ||
| CMAKE_ARGS | ||
| -DLLVM_ENABLE_RUNTIMES=libc | ||
| -DLLVM_LIBC_FULL_BUILD=ON | ||
| -DCMAKE_BUILD_TYPE=Debug | ||
| BUILD_COMMAND ${CMAKE_COMMAND} --build . --target libc-hdrgen | ||
| INSTALL_COMMAND ${CMAKE_COMMAND} -E true | ||
| CONFIGURE_HANDLED_BY_BUILD TRUE | ||
| ) | ||
| ExternalProject_Get_property(libc_hdrgen BINARY_DIR) | ||
| set(LIBC_HDRGEN ${BINARY_DIR}/bin/libc-hdrgen${CMAKE_EXECUTABLE_SUFFIX}) | ||
| add_dependencies(runtimes-depends libc_hdrgen) | ||
| endif() | ||
| endif() | ||
| list(APPEND passthrough_dirs "-DLIBC_HDRGEN=${LIBC_HDRGEN}") | ||
| endif() | ||
|
|
||
| # Create one target to run all the tests. | ||
| add_custom_target(check-${C_LIBRARY}) | ||
| add_custom_target(check-compiler-rt) | ||
| add_custom_target(check-cxx) | ||
| add_custom_target(check-cxxabi) | ||
| add_custom_target(check-unwind) | ||
|
|
||
| add_custom_target(check-all) | ||
| add_dependencies( | ||
| check-all | ||
| check-${C_LIBRARY} | ||
| check-compiler-rt | ||
| check-cxx | ||
| check-cxxabi | ||
| check-unwind | ||
| ) | ||
|
|
||
| # Read the JSON file to load a multilib configuration. | ||
| file(READ ${MULTILIB_JSON} multilib_json_str) | ||
| string(JSON multilib_defs GET ${multilib_json_str} "libs") | ||
|
|
||
| string(JSON lib_count LENGTH ${multilib_defs}) | ||
| math(EXPR lib_count_dec "${lib_count} - 1") | ||
|
|
||
| foreach(lib_idx RANGE ${lib_count_dec}) | ||
| string(JSON lib_def GET ${multilib_defs} ${lib_idx}) | ||
| string(JSON variant GET ${lib_def} "variant") | ||
|
|
||
| if(variant IN_LIST ENABLE_VARIANTS OR ENABLE_VARIANTS STREQUAL "all") | ||
| string(JSON variant_multilib_flags GET ${lib_def} "flags") | ||
| # Placeholder libraries won't have a json, so store the error in | ||
| # a variable so a fatal error isn't generated. | ||
| string(JSON variant_json ERROR_VARIABLE json_error GET ${lib_def} "json") | ||
|
|
||
| if(NOT variant_json STREQUAL "json-NOTFOUND") | ||
| # Sort by target triple | ||
| if(variant MATCHES "^aarch64") | ||
| set(parent_dir_name aarch64-none-elf) | ||
| else() | ||
| set(parent_dir_name arm-none-eabi) | ||
| endif() | ||
| set(destination_directory "${CMAKE_CURRENT_BINARY_DIR}/multilib/${parent_dir_name}/${variant}") | ||
| install( | ||
| DIRECTORY ${destination_directory} | ||
| DESTINATION ${parent_dir_name} | ||
| ) | ||
| set(variant_json_file ${CMAKE_CURRENT_SOURCE_DIR}/json/variants/${variant_json}) | ||
|
|
||
| ExternalProject_Add( | ||
| runtimes-${variant} | ||
| PREFIX ${CMAKE_BINARY_DIR}/lib-builds | ||
| SOURCE_DIR ${TOOLCHAIN_SOURCE_DIR}/arm-runtimes | ||
| INSTALL_DIR ${destination_directory} | ||
| DEPENDS runtimes-depends | ||
| CMAKE_ARGS | ||
| ${compiler_launcher_cmake_args} | ||
| ${passthrough_dirs} | ||
| -DVARIANT_JSON=${variant_json_file} | ||
| -DC_LIBRARY=${C_LIBRARY} | ||
| -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR> | ||
| STEP_TARGETS build install | ||
| USES_TERMINAL_CONFIGURE FALSE | ||
| USES_TERMINAL_BUILD TRUE | ||
| USES_TERMINAL_TEST TRUE | ||
| LIST_SEPARATOR , | ||
| CONFIGURE_HANDLED_BY_BUILD TRUE | ||
| TEST_EXCLUDE_FROM_MAIN TRUE | ||
| ) | ||
|
|
||
| # Read info from the variant specific json. | ||
| # From the json, check which tests are enabled. | ||
| file(READ ${variant_json_file} variant_json_str) | ||
| foreach(test_enable_var | ||
| ENABLE_LIBC_TESTS | ||
| ENABLE_COMPILER_RT_TESTS | ||
| ENABLE_LIBCXX_TESTS | ||
| ) | ||
| string(JSON read_${test_enable_var} ERROR_VARIABLE json_error GET ${variant_json_str} "args" ${C_LIBRARY} ${test_enable_var}) | ||
| if(read_${test_enable_var} STREQUAL "json-NOTFOUND") | ||
| string(JSON read_${test_enable_var} ERROR_VARIABLE json_error GET ${variant_json_str} "args" "common" ${test_enable_var}) | ||
| if(read_${test_enable_var} STREQUAL "json-NOTFOUND") | ||
| set(read_${test_enable_var} "OFF") | ||
| endif() | ||
| endif() | ||
| endforeach() | ||
| set(check_targets "") | ||
| if(read_ENABLE_LIBC_TESTS) | ||
| list(APPEND check_targets check-${C_LIBRARY}) | ||
| endif() | ||
| if(read_ENABLE_COMPILER_RT_TESTS) | ||
| list(APPEND check_targets check-compiler-rt) | ||
| endif() | ||
| if(read_ENABLE_LIBCXX_TESTS) | ||
| list(APPEND check_targets check-cxx) | ||
| list(APPEND check_targets check-cxxabi) | ||
| list(APPEND check_targets check-unwind) | ||
| endif() | ||
| foreach(check_target ${check_targets}) | ||
| ExternalProject_Add_Step( | ||
| runtimes-${variant} | ||
| ${check_target} | ||
| COMMAND "${CMAKE_COMMAND}" --build <BINARY_DIR> --target ${check_target} | ||
| USES_TERMINAL TRUE | ||
| EXCLUDE_FROM_MAIN TRUE | ||
| ALWAYS TRUE | ||
| ) | ||
| ExternalProject_Add_StepTargets(runtimes-${variant} ${check_target}) | ||
| ExternalProject_Add_StepDependencies( | ||
| runtimes-${variant} | ||
| ${check_target} | ||
| runtimes-${variant}-build | ||
| ) | ||
| add_custom_target(${check_target}-${variant}) | ||
| add_dependencies(${check_target} runtimes-${variant}-${check_target}) | ||
| add_dependencies(${check_target}-${variant} runtimes-${variant}-${check_target}) | ||
| endforeach() | ||
|
|
||
| # Add the variant to the multilib yaml | ||
| string(APPEND multilib_yaml_content "- Dir: ${parent_dir_name}/${variant}\n") | ||
| string(APPEND multilib_yaml_content " Flags:\n") | ||
| string(REPLACE " " ";" multilib_flags_list ${variant_multilib_flags}) | ||
| foreach(flag ${multilib_flags_list}) | ||
| string(APPEND multilib_yaml_content " - ${flag}\n") | ||
| endforeach() | ||
| string(APPEND multilib_yaml_content " Group: stdlibs\n") | ||
| else() | ||
| # In place of a json, an error message is expected. | ||
| string(JSON variant_error_msg GET ${lib_def} "error") | ||
|
|
||
| string(APPEND multilib_yaml_content "- Error: \"${variant_error_msg}\"\n") | ||
| string(APPEND multilib_yaml_content " Flags:\n") | ||
| string(REPLACE " " ";" multilib_flags_list ${variant_multilib_flags}) | ||
| foreach(flag ${multilib_flags_list}) | ||
| string(APPEND multilib_yaml_content " - ${flag}\n") | ||
| endforeach() | ||
| string(APPEND multilib_yaml_content " Group: stdlibs\n") | ||
| endif() | ||
| endif() | ||
|
|
||
| endforeach() | ||
|
|
||
| # Multilib file is generated in two parts. | ||
| # 1. Template is filled with multilib flags from json | ||
| configure_file( | ||
| ${CMAKE_CURRENT_SOURCE_DIR}/multilib.yaml.in | ||
| ${CMAKE_CURRENT_BINARY_DIR}/multilib-without-fpus.yaml | ||
| @ONLY | ||
| ) | ||
|
|
||
| # 2. multilib-generate.py maps compiler command line options to flags | ||
| add_custom_command( | ||
| OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/multilib-fpus.yaml | ||
| COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/multilib-generate.py" | ||
| "--clang=${LLVM_BINARY_DIR}/bin/clang${CMAKE_EXECUTABLE_SUFFIX}" | ||
| "--llvm-source=${FETCHCONTENT_SOURCE_DIR_LLVMPROJECT}" | ||
| >> ${CMAKE_CURRENT_BINARY_DIR}/multilib-fpus.yaml | ||
| ) | ||
|
|
||
| # Combine the two parts. | ||
| add_custom_command( | ||
| OUTPUT | ||
| ${CMAKE_CURRENT_BINARY_DIR}/multilib/multilib.yaml | ||
| COMMAND | ||
| ${CMAKE_COMMAND} -E cat | ||
| ${CMAKE_CURRENT_BINARY_DIR}/multilib-without-fpus.yaml | ||
| ${CMAKE_CURRENT_BINARY_DIR}/multilib-fpus.yaml | ||
| > ${CMAKE_CURRENT_BINARY_DIR}/multilib/multilib.yaml | ||
| DEPENDS | ||
| ${CMAKE_CURRENT_BINARY_DIR}/multilib-without-fpus.yaml | ||
| ${CMAKE_CURRENT_BINARY_DIR}/multilib-fpus.yaml | ||
| ) | ||
|
|
||
| add_custom_target(multilib-yaml ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/multilib/multilib.yaml) | ||
| install( | ||
| FILES ${CMAKE_CURRENT_BINARY_DIR}/multilib/multilib.yaml | ||
| DESTINATION . | ||
| ) | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.