Skip to content

Commit

Permalink
Merge branch 'main' into unaligned-lib
Browse files Browse the repository at this point in the history
  • Loading branch information
simpal01 authored Nov 25, 2024
2 parents 967284d + 327f60c commit 2b68e57
Show file tree
Hide file tree
Showing 86 changed files with 7,224 additions and 1,704 deletions.
1,685 changes: 122 additions & 1,563 deletions CMakeLists.txt

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Omax.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
-mllvm -enable-dfa-jump-thread \
-mllvm -enable-loop-flatten \
-mllvm -enable-unroll-and-jam \
-mllvm -enable-inline-memcpy-ld-st
298 changes: 298 additions & 0 deletions arm-multilib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,298 @@
#
# 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")
option(
ENABLE_FVP_TESTING
"Tests using FVP need to be explictly enabled."
)
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})

# Read info from the variant specific json.
file(READ ${variant_json_file} variant_json_str)
string(JSON test_executor GET ${variant_json_str} "args" "common" "TEST_EXECUTOR")

# FVP testing should default to off, so override any
# settings from the JSON.
if(test_executor STREQUAL "fvp" AND NOT ${ENABLE_FVP_TESTING})
set(additional_cmake_args "-DENABLE_LIBC_TESTS=OFF" "-DENABLE_COMPILER_RT_TESTS=OFF" "-DENABLE_LIBCXX_TESTS=OFF")
set(read_ENABLE_LIBC_TESTS "OFF")
set(read_ENABLE_COMPILER_RT_TESTS "OFF")
set(read_ENABLE_LIBCXX_TESTS "OFF")
else()
# From the json, check which tests are enabled.
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()
endif()

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}
${additional_cmake_args}
-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
)
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 .
)
Loading

0 comments on commit 2b68e57

Please sign in to comment.