diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52d3f922..3f6f208c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ on: zephyr-ref: description: 'Zephyr Ref (branch, tag, SHA, ...)' required: true - default: collab-sdk-dev + default: collab-sdk-0.18-dev host: description: 'Host' type: choice @@ -82,6 +82,8 @@ on: - toolchain-pre - toolchain-post - hosttools + - test-pre + - test-post concurrency: group: ${{ github.event_name == 'workflow_dispatch' && github.run_id || github.head_ref || github.ref }} @@ -91,7 +93,7 @@ env: BUG_URL: 'https://github.com/zephyrproject-rtos/sdk-ng/issues' BUNDLE_NAME: Zephyr SDK BUNDLE_PREFIX: zephyr-sdk - ZEPHYR_REF: collab-sdk-dev + ZEPHYR_REF: collab-sdk-0.18-dev jobs: # Setup @@ -150,6 +152,8 @@ jobs: ${{ contains(github.event.pull_request.labels.*.name, 'debug-toolchain-pre') }} && MATRIX_DEBUG="toolchain-pre" ${{ contains(github.event.pull_request.labels.*.name, 'debug-toolchain-post') }} && MATRIX_DEBUG="toolchain-post" ${{ contains(github.event.pull_request.labels.*.name, 'debug-hosttools') }} && MATRIX_DEBUG="hosttools" + ${{ contains(github.event.pull_request.labels.*.name, 'debug-test-pre') }} && MATRIX_DEBUG="test-pre" + ${{ contains(github.event.pull_request.labels.*.name, 'debug-test-post') }} && MATRIX_DEBUG="test-post" elif [ "${{ github.event_name }}" == "workflow_dispatch" ]; then # Set configurations based on the user selection case '${{ github.event.inputs.host }}' in @@ -256,7 +260,7 @@ jobs: MATRIX_HOSTS+='{ "name": "linux-x86_64", "runner": "zephyr-runner-v2-linux-x64-4xlarge", - "container": "ghcr.io/zephyrproject-rtos/sdk-build:v1.3.2", + "container": "ghcr.io/zephyrproject-rtos/sdk-build:v1.3.8", "archive": "tar.xz" },' fi @@ -265,7 +269,7 @@ jobs: MATRIX_HOSTS+='{ "name": "linux-aarch64", "runner": "zephyr-runner-v2-linux-arm64-4xlarge", - "container": "ghcr.io/zephyrproject-rtos/sdk-build:v1.3.2", + "container": "ghcr.io/zephyrproject-rtos/sdk-build:v1.3.8", "archive": "tar.xz" },' fi @@ -292,7 +296,7 @@ jobs: MATRIX_HOSTS+='{ "name": "windows-x86_64", "runner": "zephyr-runner-v2-linux-x64-4xlarge", - "container": "ghcr.io/zephyrproject-rtos/sdk-build:v1.3.2", + "container": "ghcr.io/zephyrproject-rtos/sdk-build:v1.3.8", "archive": "7z" },' fi @@ -341,7 +345,7 @@ jobs: MATRIX_TESTENVS+='{ "name": "ubuntu-20.04-x86_64", "runner": "zephyr-runner-v2-linux-x64-4xlarge", - "container": "ghcr.io/zephyrproject-rtos/ci:master", + "container": "ghcr.io/zephyrproject-rtos/ci:main", "bundle-host": "linux-x86_64", "bundle-archive": "tar.xz" },' @@ -351,7 +355,7 @@ jobs: MATRIX_TESTENVS+='{ "name": "ubuntu-20.04-aarch64", "runner": "zephyr-runner-v2-linux-arm64-4xlarge", - "container": "ghcr.io/zephyrproject-rtos/ci:master", + "container": "ghcr.io/zephyrproject-rtos/ci:main", "bundle-host": "linux-aarch64", "bundle-archive": "tar.xz" },' @@ -379,7 +383,7 @@ jobs: if [ "${build_host_windows_x86_64}" == "y" ]; then MATRIX_TESTENVS+='{ - "name": "windows-2019-x86_64", + "name": "windows-2022-x86_64", "runner": "zephyr-runner-v2-windows-x64-2xlarge", "container": "", "bundle-host": "windows-x86_64", @@ -431,9 +435,9 @@ jobs: CONFIG_REPORT_CONTENT="${CONFIG_REPORT_CONTENT//$'\r'/'%0D'}" echo "::notice:: ${CONFIG_REPORT_CONTENT}" - # Build toolchain - build-toolchain: - name: Toolchain ${{ matrix.target }} (${{ matrix.host.name }}) + # Build GNU toolchain + build-gnu-toolchain: + name: GNU Toolchain ${{ matrix.target }} (${{ matrix.host.name }}) needs: setup runs-on: group: ${{ matrix.host.runner }} @@ -472,30 +476,24 @@ jobs: run: | # Create workspace directory WORKSPACE="${RUNNER_TEMP}/workspace" - sudo mkdir -p ${WORKSPACE} - - # Clean up working directories - shopt -s dotglob - sudo rm -rf ${GITHUB_WORKSPACE}/* - sudo rm -rf ${WORKSPACE}/* - shopt -u dotglob + mkdir -p ${WORKSPACE} # Allow non-root access to the working directories - sudo chmod -R 777 ${GITHUB_WORKSPACE} - sudo chmod -R 777 ${RUNNER_TEMP} + chmod -R 777 ${GITHUB_WORKSPACE} + chmod -R 777 ${RUNNER_TEMP} # Install common dependencies - sudo apt-get update - sudo apt-get install -y autoconf automake bison flex gettext \ + apt-get update + apt-get install -y autoconf automake bison flex gettext \ help2man libboost-dev libboost-regex-dev \ libncurses5-dev libtool-bin libtool-doc \ pkg-config texinfo p7zip # Install dependencies for cross compilation if [ "${{ matrix.host.name }}" == "windows-x86_64" ]; then - # Install MinGW-w64 cross toolchain - sudo apt-get install -y binutils-mingw-w64 gcc-mingw-w64 \ - g++-mingw-w64 + # Make MinGW-w64 win32 cross toolchain available in PATH + echo "/opt/mingw-w64-win32/bin" >> $GITHUB_PATH + export PATH="/opt/mingw-w64-win32/bin:$PATH" # Build and install libboost-regex for MinGW-w64 host ## Check out Boost library source code @@ -518,13 +516,13 @@ jobs: project-config.jam ## Build and install boost-regex library - sudo ./b2 install \ + ./b2 install \ toolset=gcc-mingw link=static threading=multi variant=release \ --prefix=/usr/x86_64-w64-mingw32 ## Clean up to reduce disk usage popd - sudo rm -rf ${WORKSPACE}/boost + rm -rf ${WORKSPACE}/boost fi # Set environment variables @@ -534,43 +532,12 @@ jobs: - name: Set up build environment (macOS) if: ${{ runner.os == 'macOS' }} run: | - # Delete workspace from the previous run - WORKSPACE="/Volumes/Workspace" - if [ -d ${WORKSPACE} ]; then - # Get disk device name - OLDDISK=$(diskutil info -plist "${WORKSPACE}" | - plutil -extract ParentWholeDisk xml1 - -o - | - sed -n "s/.*\(.*\)<\/string>.*/\1/p") - - # Force unmount and eject to deallocate disk blocks - if [ ! -z "${OLDDISK}" ]; then - diskutil unmountDisk force ${OLDDISK} - diskutil eject ${OLDDISK} - fi - fi - - # Clean up working directories - shopt -s dotglob - rm -rf ${GITHUB_WORKSPACE}/* - rm -f ${RUNNER_TEMP}/Workspace.sparseimage - shopt -u dotglob - # Create case-sensitive workspace volume for macOS + WORKSPACE="/Volumes/Workspace" hdiutil create ${RUNNER_TEMP}/Workspace.sparseimage \ -volname Workspace -type SPARSE -size 150g -fs HFSX hdiutil mount ${RUNNER_TEMP}/Workspace.sparseimage -mountpoint ${WORKSPACE} - # Install required dependencies if running inside a GitHub-hosted runner - # (self-hosted runners are expected to provide all required dependencies) - if [[ "${{ matrix.host.runner }}" =~ ^macos.* ]]; then - brew install autoconf automake bash binutils boost coreutils gawk \ - gnu-sed gnu-tar help2man meson ncurses ninja pkg-config - fi - - # Install Python 3.10 (temporary until the sdk-build-macos image is - # updated) - brew install python@3.10 - # Install dependencies for cross compilation if [ "${{ matrix.host.name }}" == "macos-x86_64" ]; then # Make crosskit available in PATH @@ -792,7 +759,7 @@ jobs: fi # Create archive - ARCHIVE_NAME=toolchain_${{ matrix.host.name }}_${{ matrix.target }} + ARCHIVE_NAME=toolchain_gnu_${{ matrix.host.name }}_${{ matrix.target }} ARCHIVE_FILE=${ARCHIVE_NAME}.${{ matrix.host.archive }} if [ "${{ matrix.host.archive }}" == "tar.xz" ]; then @@ -832,15 +799,169 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: log_${{ matrix.host.name }}_${{ matrix.target }} + name: log_toolchain_gnu_${{ matrix.host.name }}_${{ matrix.target }} path: ${{ matrix.target }}.log - name: Upload toolchain build artifact uses: actions/upload-artifact@v4 with: - name: toolchain_${{ matrix.host.name }}_${{ matrix.target }} + name: toolchain_gnu_${{ matrix.host.name }}_${{ matrix.target }} path: | - toolchain_${{ matrix.host.name }}_${{ matrix.target }}.${{ matrix.host.archive }} + toolchain_gnu_${{ matrix.host.name }}_${{ matrix.target }}.${{ matrix.host.archive }} + md5.sum + sha256.sum + + # Build LLVM toolchain + build-llvm-toolchain: + name: LLVM Toolchain (${{ matrix.host.name }}) + needs: setup + runs-on: + group: ${{ matrix.host.runner }} + container: ${{ matrix.host.container }} + + defaults: + run: + shell: bash + + strategy: + fail-fast: false + matrix: + host: ${{ fromJSON(needs.setup.outputs.hosts) }} + + steps: + - name: Set up build environment (Linux) + if: ${{ runner.os == 'Linux' }} + run: | + # Create workspace directory + WORKSPACE="${RUNNER_TEMP}/workspace" + mkdir -p ${WORKSPACE} + + # Allow non-root access to the working directories + chmod -R 777 ${GITHUB_WORKSPACE} + chmod -R 777 ${RUNNER_TEMP} + + # Install common dependencies + apt-get update + + # Install dependencies for cross compilation + if [ "${{ matrix.host.name }}" == "windows-x86_64" ]; then + # Make MinGW-w64 posix cross toolchain available in PATH + echo "/opt/mingw-w64-posix/bin" >> $GITHUB_PATH + fi + + # Set environment variables + echo "TAR=tar" >> $GITHUB_ENV + echo "WORKSPACE=${WORKSPACE}" >> $GITHUB_ENV + + - name: Set up build environment (macOS) + if: ${{ runner.os == 'macOS' }} + run: | + # Create case-sensitive workspace volume for macOS + WORKSPACE="/Volumes/Workspace" + hdiutil create ${RUNNER_TEMP}/Workspace.sparseimage \ + -volname Workspace -type SPARSE -size 150g -fs HFSX + hdiutil mount ${RUNNER_TEMP}/Workspace.sparseimage -mountpoint ${WORKSPACE} + + # Install dependencies + brew install qemu + + # Set environment variables + echo "TAR=gtar" >> $GITHUB_ENV + echo "WORKSPACE=${WORKSPACE}" >> $GITHUB_ENV + + - name: Check out source code + if: ${{ github.event_name != 'pull_request_target' }} + uses: actions/checkout@v4 + with: + submodules: recursive + persist-credentials: false + + - name: Check out source code (pull request) + if: ${{ github.event_name == 'pull_request_target' }} + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + submodules: recursive + persist-credentials: false + + - name: Setup debug session (pre) + if: always() && needs.setup.outputs.debug == 'toolchain-pre' + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + + - name: Build LLVM toolchain + run: | + # Create build directory + pushd ${WORKSPACE} + mkdir -p llvm + mkdir -p llvm-build + cd llvm-build + + # Configure and generate LLVM build scripts + if [ "${{ matrix.host.name }}" == "windows-x86_64" ]; then + LLVM_CMAKE_ARGS+="-DLLVM_TOOLCHAIN_CROSS_BUILD_MINGW=ON " + elif [ "${{ matrix.host.name }}" == "macos-aarch64" ]; then + LLVM_CMAKE_ARGS+="-DCMAKE_OSX_ARCHITECTURES=arm64 " + elif [ "${{ matrix.host.name }}" == "macos-x86_64" ]; then + LLVM_CMAKE_ARGS+="-DCMAKE_OSX_ARCHITECTURES=x86_64 " + fi + + cmake \ + -GNinja \ + --install-prefix ${WORKSPACE}/llvm \ + -DLLVM_ENABLE_ZSTD=OFF \ + ${LLVM_CMAKE_ARGS} \ + ${GITHUB_WORKSPACE}/scripts/llvm \ + |& tee ${GITHUB_WORKSPACE}/llvm-cmake.log + + # Build LLVM toolchain + ninja llvm-toolchain |& tee ${GITHUB_WORKSPACE}/llvm-build.log + + # Run LLVM tests + ninja check-llvm-toolchain |& tee ${GITHUB_WORKSPACE}/llvm-test.log + + # Install LLVM toolchain + ninja install-llvm-toolchain |& tee ${GITHUB_WORKSPACE}/llvm-install.log + popd + + # Create archive + ARCHIVE_NAME=toolchain_llvm_${{ matrix.host.name }} + ARCHIVE_FILE=${ARCHIVE_NAME}.${{ matrix.host.archive }} + + if [ "${{ matrix.host.archive }}" == "tar.xz" ]; then + XZ_OPT="-T0" \ + ${TAR} -Jcvf ${ARCHIVE_FILE} \ + --owner=0 --group=0 -C ${WORKSPACE} llvm + elif [ "${{ matrix.host.archive }}" == "7z" ]; then + pushd ${WORKSPACE} + 7z a -t7z -l ${GITHUB_WORKSPACE}/${ARCHIVE_FILE} llvm + popd + fi + + # Compute checksum + md5sum ${ARCHIVE_FILE} > md5.sum + sha256sum ${ARCHIVE_FILE} > sha256.sum + + - name: Setup debug session (post) + if: always() && needs.setup.outputs.debug == 'toolchain-post' + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + + - name: Upload toolchain build log + if: always() + uses: actions/upload-artifact@v4 + with: + name: log_toolchain_llvm_${{ matrix.host.name }} + path: '*.log' + + - name: Upload toolchain build artifact + uses: actions/upload-artifact@v4 + with: + name: toolchain_llvm_${{ matrix.host.name }} + path: | + toolchain_llvm_${{ matrix.host.name }}.${{ matrix.host.archive }} md5.sum sha256.sum @@ -875,22 +996,12 @@ jobs: - name: Set up build environment (Linux) if: ${{ runner.os == 'Linux' }} run: | - # Clean up working directories - shopt -s dotglob - sudo rm -rf ${GITHUB_WORKSPACE}/* - shopt -u dotglob - # Set environment variables echo "TAR=tar" >> $GITHUB_ENV - name: Set up build environment (macOS) if: ${{ runner.os == 'macOS' }} run: | - # Clean up working directories - shopt -s dotglob - rm -rf ${GITHUB_WORKSPACE}/* - shopt -u dotglob - # Set environment variables echo "TAR=gtar" >> $GITHUB_ENV @@ -1018,14 +1129,9 @@ jobs: - name: Set up build environment (Linux) if: ${{ runner.os == 'Linux' }} run: | - # Clean up working directories - shopt -s dotglob - sudo rm -rf ${GITHUB_WORKSPACE}/* - shopt -u dotglob - # Install common dependencies - sudo apt-get update - sudo apt-get install -y p7zip + apt-get update + apt-get install -y p7zip # Set environment variables echo "TAR=tar" >> $GITHUB_ENV @@ -1033,17 +1139,6 @@ jobs: - name: Set up build environment (macOS) if: ${{ runner.os == 'macOS' }} run: | - # Clean up working directories - shopt -s dotglob - rm -rf ${GITHUB_WORKSPACE}/* - shopt -u dotglob - - # Install required dependencies if running inside a GitHub-hosted runner - # (self-hosted runners are expected to provide all required dependencies) - if [[ "${{ matrix.host.runner }}" =~ ^macos.* ]]; then - brew install gnu-tar - fi - # Set environment variables echo "TAR=gtar" >> $GITHUB_ENV @@ -1090,7 +1185,7 @@ jobs: # Build distribution bundle build-dist-bundle: name: Distribution Bundle (${{ matrix.host.name }}) - needs: [ setup, build-toolchain, build-hosttools, build-cmake-pkg ] + needs: [ setup, build-gnu-toolchain, build-llvm-toolchain, build-hosttools, build-cmake-pkg ] runs-on: group: ${{ matrix.host.runner }} container: ${{ matrix.host.container }} @@ -1108,14 +1203,9 @@ jobs: - name: Set up build environment (Linux) if: ${{ runner.os == 'Linux' }} run: | - # Clean up working directories - shopt -s dotglob - sudo rm -rf ${GITHUB_WORKSPACE}/* - shopt -u dotglob - # Install common dependencies - sudo apt-get update - sudo apt-get install -y jq p7zip + apt-get update + apt-get install -y jq p7zip # Set environment variables echo "TAR=tar" >> $GITHUB_ENV @@ -1123,17 +1213,6 @@ jobs: - name: Set up build environment (macOS) if: ${{ runner.os == 'macOS' }} run: | - # Clean up working directories - shopt -s dotglob - rm -rf ${GITHUB_WORKSPACE}/* - shopt -u dotglob - - # Install required dependencies if running inside a GitHub-hosted runner - # (self-hosted runners are expected to provide all required dependencies) - if [[ "${{ matrix.host.runner }}" =~ ^macos.* ]]; then - brew install coreutils gnu-tar jq - fi - # Set environment variables echo "TAR=gtar" >> $GITHUB_ENV @@ -1152,17 +1231,35 @@ jobs: path: repository persist-credentials: false - - name: Download Version + - name: Download version file uses: actions/download-artifact@v4 with: - path: artifacts pattern: version + path: artifacts - - name: Download artifacts + - name: Download CMake artifacts uses: actions/download-artifact@v4 with: + pattern: cmake_${{ matrix.host.name }} + path: artifacts + + - name: Download host tools artifacts + uses: actions/download-artifact@v4 + with: + pattern: hosttools_${{ matrix.host.name }} + path: artifacts + + - name: Download GNU toolchain artifacts + uses: actions/download-artifact@v4 + with: + pattern: toolchain_gnu_${{ matrix.host.name }}_* + path: artifacts + + - name: Download LLVM toolchain artifacts + uses: actions/download-artifact@v4 + with: + pattern: toolchain_llvm_${{ matrix.host.name }} path: artifacts - pattern: "*_${{ matrix.host.name }}*" - name: Create distribution bundle run: | @@ -1190,8 +1287,8 @@ jobs: # Stage version file echo "${VERSION}" > sdk_version - # Stage toolchain list file - echo '${{ needs.setup.outputs.targets }}' | jq -cr '.[]' > sdk_toolchains + # Stage GNU toolchain list file + echo '${{ needs.setup.outputs.targets }}' | jq -cr '.[]' > sdk_gnu_toolchains # Stage CMake package ## Verify CMake package archive checksum @@ -1212,8 +1309,13 @@ jobs: sha256sum --check sha256.sum popd + # Create host tools root directory + mkdir hosttools + # Extract host tools archive + pushd hosttools ${EXTRACT} ${ARTIFACT_ROOT}/${HOSTTOOLS_ARTIFACT}/${HOSTTOOLS_ARTIFACT}.${EXT} + popd fi # Stage setup script @@ -1237,15 +1339,16 @@ jobs: 7z a -t7z -l ${ARCHIVE_NAME}_minimal.${EXT} ${ARCHIVE_DIR} fi - # Stage toolchains - pushd ${ARCHIVE_DIR} + # Stage GNU toolchains + mkdir ${ARCHIVE_DIR}/gnu + pushd ${ARCHIVE_DIR}/gnu ## Generate target list from the workflow matrix TARGETS=$(echo '${{ needs.setup.outputs.targets }}' | jq -cr '.[]') ## Extract all toolchains for TARGET in ${TARGETS}; do - TOOLCHAIN_ARTIFACT=toolchain_${HOST}_${TARGET} + TOOLCHAIN_ARTIFACT=toolchain_gnu_${HOST}_${TARGET} # Verify toolchain archive checksum pushd ${ARTIFACT_ROOT}/${TOOLCHAIN_ARTIFACT} @@ -1258,32 +1361,67 @@ jobs: done popd - # Create full distribution bundle archive + # Create GNU distribution bundle archive if [ "${{ matrix.host.archive }}" == "tar.xz" ]; then XZ_OPT="-T0" \ - ${TAR} -Jcvf ${ARCHIVE_NAME}.${EXT} --owner=0 --group=0 \ + ${TAR} -Jcvf ${ARCHIVE_NAME}_gnu.${EXT} --owner=0 --group=0 \ -C . ${ARCHIVE_DIR} elif [ "${{ matrix.host.archive }}" == "7z" ]; then - 7z a -t7z -l ${ARCHIVE_NAME}.${EXT} ${ARCHIVE_DIR} + 7z a -t7z -l ${ARCHIVE_NAME}_gnu.${EXT} ${ARCHIVE_DIR} + fi + + # Unstage GNU toolchain directory + rm -rf ${ARCHIVE_DIR}/gnu + + # Stage LLVM toolchains + pushd ${ARCHIVE_DIR} + + ## Verify toolchain archive checksum + pushd ${ARTIFACT_ROOT}/toolchain_llvm_${HOST} + md5sum --check md5.sum + sha256sum --check sha256.sum + popd + + ## Extract toolchain archive + ${EXTRACT} ${ARTIFACT_ROOT}/toolchain_llvm_${HOST}/toolchain_llvm_${HOST}.${EXT} + popd + + # Create LLVM distribution bundle archive + if [ "${{ matrix.host.archive }}" == "tar.xz" ]; then + XZ_OPT="-T0" \ + ${TAR} -Jcvf ${ARCHIVE_NAME}_llvm.${EXT} --owner=0 --group=0 \ + -C . ${ARCHIVE_DIR} + elif [ "${{ matrix.host.archive }}" == "7z" ]; then + 7z a -t7z -l ${ARCHIVE_NAME}_llvm.${EXT} ${ARCHIVE_DIR} fi # Compute checksum - md5sum ${ARCHIVE_NAME}.${EXT} ${ARCHIVE_NAME}_minimal.${EXT} > md5.sum - sha256sum ${ARCHIVE_NAME}.${EXT} ${ARCHIVE_NAME}_minimal.${EXT} > sha256.sum + md5sum \ + ${ARCHIVE_NAME}_gnu.${EXT} \ + ${ARCHIVE_NAME}_llvm.${EXT} \ + ${ARCHIVE_NAME}_minimal.${EXT} \ + > md5.sum + + sha256sum \ + ${ARCHIVE_NAME}_gnu.${EXT} \ + ${ARCHIVE_NAME}_llvm.${EXT} \ + ${ARCHIVE_NAME}_minimal.${EXT} \ + > sha256.sum - name: Upload distribution bundle uses: actions/upload-artifact@v4 with: name: ${{ env.BUNDLE_ARCHIVE_NAME }} path: | - ${{ env.BUNDLE_ARCHIVE_NAME }}.${{ matrix.host.archive }} + ${{ env.BUNDLE_ARCHIVE_NAME }}_gnu.${{ matrix.host.archive }} + ${{ env.BUNDLE_ARCHIVE_NAME }}_llvm.${{ matrix.host.archive }} ${{ env.BUNDLE_ARCHIVE_NAME }}_minimal.${{ matrix.host.archive }} md5.sum sha256.sum # Test distribution bundle test-dist-bundle: - name: Test (${{ matrix.testenv.name }}) Subset ${{ matrix.subset }} + name: Test (${{ matrix.testenv.name }}, ${{ matrix.toolchain }}) Subset ${{ matrix.subset }} needs: [ setup, build-dist-bundle ] runs-on: group: ${{ matrix.testenv.runner }} @@ -1297,29 +1435,23 @@ jobs: fail-fast: false matrix: testenv: ${{ fromJSON(needs.setup.outputs.testenvs) }} + toolchain: [ gnu, llvm ] subset: [ 1, 2, 3 ] env: SUBSET_COUNT: 3 - ZEPHYR_TOOLCHAIN_VARIANT: zephyr steps: - name: Set up Python - if: ${{ runner.os == 'Windows' }} uses: actions/setup-python@v5 with: - # Force Python 3.10 because the twister is not compatible with a Python - # version lower than 3.8 on Windows. + # Force Python 3.10, which is the minimum Python version supported by + # Zephyr and intended to be used with Zephyr SDK. python-version: '3.10' - name: Set up test environment (Linux) if: ${{ runner.os == 'Linux' }} run: | - # Clean up working directories - shopt -s dotglob - sudo rm -rf ${GITHUB_WORKSPACE}/* - shopt -u dotglob - # Install required system packages sudo apt-get update sudo apt-get install -y dos2unix jq @@ -1331,17 +1463,6 @@ jobs: - name: Set up test environment (macOS) if: ${{ runner.os == 'macOS' }} run: | - # Clean up working directories - shopt -s dotglob - rm -rf ${GITHUB_WORKSPACE}/* - shopt -u dotglob - - # Install required dependencies if running inside a GitHub-hosted runner - # (self-hosted runners are expected to provide all required dependencies) - if [[ "${{ matrix.host.runner }}" =~ ^macos.* ]]; then - brew install ccache coreutils dos2unix dtc gperf jq ninja wget - fi - # Set environment variables echo "TAR=gtar" >> $GITHUB_ENV echo "ARTIFACT_ROOT=${GITHUB_WORKSPACE}/artifacts" >> $GITHUB_ENV @@ -1349,11 +1470,6 @@ jobs: - name: Set up test environment (Windows) if: ${{ runner.os == 'Windows' }} run: | - # Clean up working directories - shopt -s dotglob - rm -rf ${GITHUB_WORKSPACE}/* - shopt -u dotglob - # Install required system packages choco install ccache dtc-msys2 gperf jq ninja wget 7zip @@ -1364,7 +1480,6 @@ jobs: echo "ARTIFACT_ROOT=${GITHUB_WORKSPACE}/artifacts" >> $GITHUB_ENV - name: Create Python virtual environment - if: ${{ runner.os != 'Linux' }} run: | # Create Python virtual environment python3 -m venv ${GITHUB_WORKSPACE}/venv @@ -1425,8 +1540,8 @@ jobs: sha256sum --check sha256.sum popd - # Extract distribution bundle archive - BUNDLE_FILE=${BUNDLE_NAME}.${{ matrix.testenv.bundle-archive }} + # Extract GNU distribution bundle archive + BUNDLE_FILE=${BUNDLE_NAME}_${{ matrix.toolchain }}.${{ matrix.testenv.bundle-archive }} if [ "${{ matrix.testenv.bundle-archive }}" == "tar.xz" ]; then ${TAR} -Jxvf ${ARTIFACT_ROOT}/${BUNDLE_FILE} -C tools elif [ "${{ matrix.testenv.bundle-archive }}" == "7z" ]; then @@ -1443,10 +1558,18 @@ jobs: # NOTE: Escape forward slashes because MinGW (bash) # NOTE: A full path (using PWD) must be specified to ensure that the # setup script is launched from the shortened path. - ${PWD}/setup.cmd //t all //h //c + if [ "${{ matrix.toolchain }}" == "gnu" ]; then + ${PWD}/setup.cmd //t all //h //c + elif [ "${{ matrix.toolchain }}" == "llvm" ]; then + ${PWD}/setup.cmd //l //h //c + fi popd else - ./setup.sh -t all -h -c + if [ "${{ matrix.toolchain }}" == "gnu" ]; then + ./setup.sh -t all -h -c + elif [ "${{ matrix.toolchain }}" == "llvm" ]; then + ./setup.sh -l -h -c + fi fi # Clean up bundle archive to reduce disk usage @@ -1457,9 +1580,7 @@ jobs: - name: Install west run: | # Activate Python virtual environment - if [ ! -z "${VENV_ACTIVATE}" ]; then - source ${VENV_ACTIVATE} - fi + source ${VENV_ACTIVATE} # Install or upgrade west pip3 install --upgrade west @@ -1467,9 +1588,7 @@ jobs: - name: Set up Zephyr repository run: | # Activate Python virtual environment - if [ ! -z "${VENV_ACTIVATE}" ]; then - source ${VENV_ACTIVATE} - fi + source ${VENV_ACTIVATE} # Create Zephyr workspace ZEPHYR_WORKSPACE=${GITHUB_WORKSPACE}/zephyrproject @@ -1499,21 +1618,21 @@ jobs: - name: Install Python dependencies run: | # Activate Python virtual environment - if [ ! -z "${VENV_ACTIVATE}" ]; then - source ${VENV_ACTIVATE} + source ${VENV_ACTIVATE} - # Install Python dependencies from the checked out Zephyr repository - # if running inside a virtual environment; otherwise, it is assumed - # that the host already provides all the required dependencies. - pip3 install -r ${ZEPHYR_ROOT}/scripts/requirements.txt - fi + # Install Python dependencies from the checked out Zephyr repository. + pip3 install -r ${ZEPHYR_ROOT}/scripts/requirements.txt + + - name: Setup debug session (pre) + if: always() && needs.setup.outputs.debug == 'test-pre' + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true - name: Run test suites run: | # Activate Python virtual environment - if [ ! -z "${VENV_ACTIVATE}" ]; then - source ${VENV_ACTIVATE} - fi + source ${VENV_ACTIVATE} # Create working directory mkdir -p test @@ -1531,128 +1650,162 @@ jobs: HOST_ARGS+="--short-build-path " fi - # Generate platform list from the target list - TARGETS=$(echo '${{ needs.setup.outputs.targets }}' | jq -cr '.[]' | dos2unix) - - for TARGET in ${TARGETS}; do - case ${TARGET} in - aarch64-zephyr-elf) - PLATFORM_ARGS+="-p qemu_cortex_a53 " - ;; - arc64-zephyr-elf) - PLATFORM_ARGS+="-p qemu_arc/qemu_arc_hs6x " - ;; - arc-zephyr-elf) - PLATFORM_ARGS+="-p qemu_arc/qemu_arc_em " - PLATFORM_ARGS+="-p qemu_arc/qemu_arc_hs " - ;; - arm-zephyr-eabi) - PLATFORM_ARGS+="-p qemu_cortex_m0 " - PLATFORM_ARGS+="-p mps2/an385 " - PLATFORM_ARGS+="-p mps2/an521/cpu0 " - PLATFORM_ARGS+="-p mps3/corstone300/an547 " - ;; - # TODO: Release the microblaze arch source in a public repo - # microblazeel-zephyr-elf) - # PLATFORM_ARGS+="-p qemu_microblaze " - # ;; - mips-zephyr-elf) - PLATFORM_ARGS+="-p qemu_malta " - ;; - riscv64-zephyr-elf) - PLATFORM_ARGS+="-p qemu_riscv32 " - PLATFORM_ARGS+="-p qemu_riscv32e " - PLATFORM_ARGS+="-p qemu_riscv64 " - ;; - rx-zephyr-elf) - PLATFORM_ARGS+="-p qemu_rx " - ;; - sparc-zephyr-elf) - PLATFORM_ARGS+="-p qemu_leon3 " - ;; - x86_64-zephyr-elf) - PLATFORM_ARGS+="-p qemu_x86 " - PLATFORM_ARGS+="-p qemu_x86_64 " - ;; - xtensa-amd_acp_6_0_adsp_zephyr-elf) - # xtensa-sample_controller32_zephyr-elf is untested because no - # upstream user platform is currently available. - # PLATFORM_ARGS+="-p acp_6_0 " - ;; - xtensa-dc233c_zephyr-elf) - PLATFORM_ARGS+="-p qemu_xtensa/dc233c/mmu " - ;; - xtensa-espressif_esp32_zephyr-elf) - PLATFORM_ARGS+="-p esp32_devkitc/esp32/procpu " - ;; - xtensa-espressif_esp32s2_zephyr-elf) - PLATFORM_ARGS+="-p esp32s2_saola " - ;; - xtensa-espressif_esp32s3_zephyr-elf) - PLATFORM_ARGS+="-p esp32s3_devkitm/esp32s3/procpu " - ;; - xtensa-intel_ace15_mtpm_zephyr-elf) - PLATFORM_ARGS+="-p intel_adsp/ace15_mtpm " - ;; - xtensa-intel_ace30_ptl_zephyr-elf) - PLATFORM_ARGS+="-p intel_adsp/ace30/ptl " - ;; - xtensa-intel_tgl_adsp_zephyr-elf) - PLATFORM_ARGS+="-p intel_adsp/cavs25 " - ;; - xtensa-mtk_mt8195_adsp_zephyr-elf) - # Not merged yet, see Zephyr #81154 - #PLATFORM_ARGS+="-p mt8195/mt8195/adsp" - ;; - xtensa-mtk_mt818x_adsp_zephyr-elf) - # Not merged yet, see Zephyr #81154 - #PLATFORM_ARGS+="-p mt818x/mt818x/adsp" - ;; - xtensa-mtk_mt8196_adsp_zephyr-elf) - # Not merged yet, see Zephyr #81154 - #PLATFORM_ARGS+="-p mt8196/mt8196/adsp" - ;; - xtensa-mtk_mt8365_adsp_zephyr-elf) - # xtensa-mtk_mt8365_adsp_zephyr-elf is untested because no - # upstream user platform is currently available. - #PLATFORM_ARGS+="-p mt8365/mt8365/adsp" - ;; - xtensa-nxp_imx_adsp_zephyr-elf) - PLATFORM_ARGS+="-p imx8qm_mek/mimx8qm6/adsp " - ;; - xtensa-nxp_imx8m_adsp_zephyr-elf) - PLATFORM_ARGS+="-p imx8mp_evk/mimx8ml8/adsp " - ;; - xtensa-nxp_imx8ulp_adsp_zephyr-elf) - PLATFORM_ARGS+="-p imx8ulp_evk/mimx8ud7/adsp " - ;; - xtensa-nxp_rt500_adsp_zephyr-elf) - PLATFORM_ARGS+="-p mimxrt595_evk/mimxrt595s/f1 " - ;; - xtensa-nxp_rt600_adsp_zephyr-elf) - # xtensa-nxp_rt600_adsp_zephyr-elf is untested because no - # upstream user platform is currently available. - ;; - xtensa-nxp_rt700_hifi1_zephyr-elf) - # xtensa-nxp_rt700_hifi1_zephyr-elf is untested because no - # upstream user platform is currently available. - ;; - xtensa-nxp_rt700_hifi4_zephyr-elf) - # xtensa-nxp_rt700_hifi4_zephyr-elf is untested because no - # upstream user platform is currently available. - ;; - xtensa-sample_controller_zephyr-elf) - PLATFORM_ARGS+="-p qemu_xtensa/dc233c " - ;; - xtensa-sample_controller32_zephyr-elf) - # xtensa-sample_controller32_zephyr-elf is untested because no - # upstream user platform is currently available. - # PLATFORM_ARGS+="-p qemu_xtensa/sample_controller32/mpu " - ;; - esac - done + # Generate platform list + if [ "${{ matrix.toolchain }}" == "gnu" ]; then + # Generate platform list from the GNU toolchain target list + TARGETS=$(echo '${{ needs.setup.outputs.targets }}' | jq -cr '.[]' | dos2unix) + + for TARGET in ${TARGETS}; do + case ${TARGET} in + aarch64-zephyr-elf) + PLATFORM_ARGS+="-p qemu_cortex_a53 " + ;; + arc64-zephyr-elf) + PLATFORM_ARGS+="-p qemu_arc/qemu_arc_hs6x " + ;; + arc-zephyr-elf) + PLATFORM_ARGS+="-p qemu_arc/qemu_arc_em " + PLATFORM_ARGS+="-p qemu_arc/qemu_arc_hs " + ;; + arm-zephyr-eabi) + PLATFORM_ARGS+="-p qemu_cortex_m0 " + PLATFORM_ARGS+="-p mps2/an385 " + PLATFORM_ARGS+="-p mps2/an521/cpu0 " + PLATFORM_ARGS+="-p mps3/corstone300/an547 " + ;; + # TODO: Release the microblaze arch source in a public repo + # microblazeel-zephyr-elf) + # PLATFORM_ARGS+="-p qemu_microblaze " + # ;; + mips-zephyr-elf) + PLATFORM_ARGS+="-p qemu_malta " + ;; + riscv64-zephyr-elf) + PLATFORM_ARGS+="-p qemu_riscv32 " + PLATFORM_ARGS+="-p qemu_riscv32e " + PLATFORM_ARGS+="-p qemu_riscv64 " + ;; + rx-zephyr-elf) + PLATFORM_ARGS+="-p qemu_rx " + ;; + sparc-zephyr-elf) + PLATFORM_ARGS+="-p qemu_leon3 " + ;; + x86_64-zephyr-elf) + PLATFORM_ARGS+="-p qemu_x86 " + PLATFORM_ARGS+="-p qemu_x86_64 " + ;; + xtensa-amd_acp_6_0_adsp_zephyr-elf) + # xtensa-sample_controller32_zephyr-elf is untested because no + # upstream user platform is currently available. + # PLATFORM_ARGS+="-p acp_6_0 " + ;; + xtensa-dc233c_zephyr-elf) + PLATFORM_ARGS+="-p qemu_xtensa/dc233c/mmu " + ;; + xtensa-espressif_esp32_zephyr-elf) + PLATFORM_ARGS+="-p esp32_devkitc/esp32/procpu " + ;; + xtensa-espressif_esp32s2_zephyr-elf) + PLATFORM_ARGS+="-p esp32s2_saola " + ;; + xtensa-espressif_esp32s3_zephyr-elf) + PLATFORM_ARGS+="-p esp32s3_devkitm/esp32s3/procpu " + ;; + xtensa-intel_ace15_mtpm_zephyr-elf) + PLATFORM_ARGS+="-p intel_adsp/ace15_mtpm " + ;; + xtensa-intel_ace30_ptl_zephyr-elf) + # xtensa-intel_ace30_ptl_zephyr-elf testing is disabled because + # there are known issues causing build failures on this + # platform. + # PLATFORM_ARGS+="-p intel_adsp/ace30/ptl " + ;; + xtensa-intel_tgl_adsp_zephyr-elf) + PLATFORM_ARGS+="-p intel_adsp/cavs25 " + ;; + xtensa-mtk_mt8195_adsp_zephyr-elf) + # Not merged yet, see Zephyr #81154 + #PLATFORM_ARGS+="-p mt8195/mt8195/adsp" + ;; + xtensa-mtk_mt818x_adsp_zephyr-elf) + # Not merged yet, see Zephyr #81154 + #PLATFORM_ARGS+="-p mt818x/mt818x/adsp" + ;; + xtensa-mtk_mt8196_adsp_zephyr-elf) + # Not merged yet, see Zephyr #81154 + #PLATFORM_ARGS+="-p mt8196/mt8196/adsp" + ;; + xtensa-mtk_mt8365_adsp_zephyr-elf) + # xtensa-mtk_mt8365_adsp_zephyr-elf is untested because no + # upstream user platform is currently available. + #PLATFORM_ARGS+="-p mt8365/mt8365/adsp" + ;; + xtensa-nxp_imx_adsp_zephyr-elf) + PLATFORM_ARGS+="-p imx8qm_mek/mimx8qm6/adsp " + ;; + xtensa-nxp_imx8m_adsp_zephyr-elf) + PLATFORM_ARGS+="-p imx8mp_evk/mimx8ml8/adsp " + ;; + xtensa-nxp_imx8ulp_adsp_zephyr-elf) + PLATFORM_ARGS+="-p imx8ulp_evk/mimx8ud7/adsp " + ;; + xtensa-nxp_rt500_adsp_zephyr-elf) + PLATFORM_ARGS+="-p mimxrt595_evk/mimxrt595s/f1 " + ;; + xtensa-nxp_rt600_adsp_zephyr-elf) + # xtensa-nxp_rt600_adsp_zephyr-elf is untested because no + # upstream user platform is currently available. + ;; + xtensa-nxp_rt700_hifi1_zephyr-elf) + # xtensa-nxp_rt700_hifi1_zephyr-elf is untested because no + # upstream user platform is currently available. + ;; + xtensa-nxp_rt700_hifi4_zephyr-elf) + # xtensa-nxp_rt700_hifi4_zephyr-elf is untested because no + # upstream user platform is currently available. + ;; + xtensa-sample_controller_zephyr-elf) + PLATFORM_ARGS+="-p qemu_xtensa/dc233c " + ;; + xtensa-sample_controller32_zephyr-elf) + # xtensa-sample_controller32_zephyr-elf is untested because no + # upstream user platform is currently available. + # PLATFORM_ARGS+="-p qemu_xtensa/sample_controller32/mpu " + ;; + esac + done + elif [ "${{ matrix.toolchain }}" == "llvm" ]; then + # Add AArch64 platforms + # FIXME: qemu_cortex_a53 currently cannot build using LLVM. + # PLATFORM_ARGS+="-p qemu_cortex_a53 " + + # Add ARM platforms + ## ARMv6-M (Cortex-M0) + # FIXME: qemu_cortex_m0 currently cannot build using LLVM. + # PLATFORM_ARGS+="-p qemu_cortex_m0 " + ## ARMv7-M (Cortex-M3) + PLATFORM_ARGS+="-p mps2/an385 " + ## ARMv8-M (Cortex-M33) + PLATFORM_ARGS+="-p mps2/an521/cpu0 " + ## ARMv8.1-M (Cortex-M55) + # FIXME: mps3/an547 currently cannot build using LLVM. + # PLATFORM_ARGS+="-p mps3/an547 " + + # Add RISC-V platforms + ## RV32I + # FIXME: There are issues building some tests for qemu_riscv32. + # PLATFORM_ARGS+="-p qemu_riscv32 " + ## RV32E + # FIXME: There are issues building some tests for qemu_riscv32e. + # PLATFORM_ARGS+="-p qemu_riscv32e " + ## RV64I + # FIXME: There are issues building some tests for qemu_riscv64. + # PLATFORM_ARGS+="-p qemu_riscv64 " + fi # Generate test list + ## Add common tests TEST_ARGS=" -T ${ZEPHYR_ROOT}/samples/hello_world -T ${ZEPHYR_ROOT}/samples/cpp/hello_world @@ -1660,6 +1813,17 @@ jobs: -T ${ZEPHYR_ROOT}/tests/lib/cpp " + + # FIXME: Skip testing for LLVM on Windows because there are known issues + # (see GitHub issue #831). + if [ "${{ matrix.toolchain }}" == "llvm" ] && + [ "${{ runner.os }}" == "Windows" ]; then + exit 0 + fi + + # Set toolchain variant + export ZEPHYR_TOOLCHAIN_VARIANT=zephyr-${{ matrix.toolchain }} + # Run tests with twister TWISTER="${ZEPHYR_ROOT}/scripts/twister" ${TWISTER} -v -N --force-color --inline-logs --retry-failed 3 \ @@ -1669,11 +1833,17 @@ jobs: ${TEST_ARGS} \ ${PLATFORM_ARGS} + - name: Setup debug session (post) + if: always() && needs.setup.outputs.debug == 'test-post' + uses: mxschmitt/action-tmate@v3 + with: + limit-access-to-actor: true + - name: Publish test results if: always() uses: actions/upload-artifact@v4 with: - name: test_${{ matrix.testenv.name }}_${{ matrix.subset }} + name: test_${{ matrix.testenv.name }}_${{ matrix.toolchain }}_${{ matrix.subset }} if-no-files-found: ignore path: test/twister-out/twister.xml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b4d902ea..d7dc4efe 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,19 +72,22 @@ jobs: uses: softprops/action-gh-release@v2 with: files: | - assets/toolchain_linux* + assets/toolchain_gnu_linux* + assets/toolchain_llvm_linux* - name: Upload release assets (macOS toolchains) uses: softprops/action-gh-release@v2 with: files: | - assets/toolchain_macos* + assets/toolchain_gnu_macos* + assets/toolchain_llvm_macos* - name: Upload release assets (Windows toolchains) uses: softprops/action-gh-release@v2 with: files: | - assets/toolchain_windows* + assets/toolchain_gnu_windows* + assets/toolchain_llvm_windows* - name: Upload release assets (Distribution bundles) uses: softprops/action-gh-release@v2 diff --git a/.gitmodules b/.gitmodules index 99b82d45..0291eeb2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,6 +13,9 @@ [submodule "picolibc"] path = picolibc url = https://github.com/zephyrproject-rtos/picolibc.git +[submodule "llvm"] + path = llvm + url = https://github.com/zephyrproject-rtos/llvm-project.git [submodule "crosskit-x86_64-apple-darwin"] path = crosskit/crosskit-x86_64-apple-darwin url = https://github.com/zephyrproject-rtos/crosskit-x86_64-apple-darwin.git diff --git a/cmake/Zephyr-sdkConfig.cmake b/cmake/Zephyr-sdkConfig.cmake index a5f41049..26c0481a 100644 --- a/cmake/Zephyr-sdkConfig.cmake +++ b/cmake/Zephyr-sdkConfig.cmake @@ -11,7 +11,10 @@ set(SDK_MAJOR_MINOR_MICRO ${SDK_VERSION}) get_filename_component(ZEPHYR_SDK_INSTALL_DIR ${CMAKE_CURRENT_LIST_DIR}/.. ABSOLUTE) set(ZEPHYR_SDK_INSTALL_DIR ${ZEPHYR_SDK_INSTALL_DIR}) -set(ZEPHYR_TOOLCHAIN_VARIANT zephyr) + +if(NOT DEFINED ZEPHYR_TOOLCHAIN_VARIANT) + set(ZEPHYR_TOOLCHAIN_VARIANT zephyr-gnu) +endif() # Those are CMake package parameters. set(Zephyr-sdk_FOUND True) diff --git a/cmake/zephyr/Kconfig b/cmake/zephyr/Kconfig index 8fa38372..63087602 100644 --- a/cmake/zephyr/Kconfig +++ b/cmake/zephyr/Kconfig @@ -13,7 +13,8 @@ config TOOLCHAIN_ZEPHYR_SUPPORTS_GNU_EXTENSIONS config PICOLIBC_SUPPORTED def_bool y - depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "zephyr" + depends on "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "zephyr-gnu" \ + || "$(ZEPHYR_TOOLCHAIN_VARIANT)" = "zephyr-llvm" help Zephyr SDK >=0.16 always supports Picolibc for C and C++ development. diff --git a/cmake/zephyr/generic.cmake b/cmake/zephyr/gnu/generic.cmake similarity index 88% rename from cmake/zephyr/generic.cmake rename to cmake/zephyr/gnu/generic.cmake index 781151d8..21f423fb 100644 --- a/cmake/zephyr/generic.cmake +++ b/cmake/zephyr/gnu/generic.cmake @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -set(TOOLCHAIN_HOME ${ZEPHYR_SDK_INSTALL_DIR}) +set(TOOLCHAIN_HOME ${ZEPHYR_SDK_INSTALL_DIR}/gnu) set(COMPILER gcc) set(LINKER ld) @@ -31,3 +31,4 @@ set(CROSS_COMPILE ${one_toolchain_root}/${CROSS_COMPILE_TARGET}/bin/${CROSS_COMP set(SYSROOT_DIR ${one_toolchain_root}/${SYSROOT_TARGET}/${SYSROOT_TARGET}) set(TOOLCHAIN_HAS_NEWLIB OFF CACHE BOOL "True if toolchain supports newlib") set(TOOLCHAIN_HAS_PICOLIBC ON CACHE BOOL "True if toolchain supports picolibc") +set(TOOLCHAIN_HAS_GLIBCXX ON CACHE BOOL "True if toolchain supports libstdc++") diff --git a/cmake/zephyr/target.cmake b/cmake/zephyr/gnu/target.cmake similarity index 87% rename from cmake/zephyr/target.cmake rename to cmake/zephyr/gnu/target.cmake index 7246f7a4..b080515f 100644 --- a/cmake/zephyr/target.cmake +++ b/cmake/zephyr/gnu/target.cmake @@ -26,8 +26,8 @@ set(CROSS_COMPILE_TARGET_sparc sparc-zephyr-elf) set(CROSS_COMPILE_TARGET ${CROSS_COMPILE_TARGET_${ARCH}}) set(SYSROOT_TARGET ${CROSS_COMPILE_TARGET}) -set(SYSROOT_DIR ${ZEPHYR_SDK_INSTALL_DIR}/${SYSROOT_TARGET}/${SYSROOT_TARGET}) -set(CROSS_COMPILE ${ZEPHYR_SDK_INSTALL_DIR}/${CROSS_COMPILE_TARGET}/bin/${CROSS_COMPILE_TARGET}-) +set(SYSROOT_DIR ${ZEPHYR_SDK_INSTALL_DIR}/gnu/${SYSROOT_TARGET}/${SYSROOT_TARGET}) +set(CROSS_COMPILE ${ZEPHYR_SDK_INSTALL_DIR}/gnu/${CROSS_COMPILE_TARGET}/bin/${CROSS_COMPILE_TARGET}-) if("${ARCH}" STREQUAL "x86") if(CONFIG_X86_64) diff --git a/cmake/zephyr/host-tools.cmake b/cmake/zephyr/host-tools.cmake index e8ba7d68..24084d0c 100644 --- a/cmake/zephyr/host-tools.cmake +++ b/cmake/zephyr/host-tools.cmake @@ -1,7 +1,7 @@ # SPDX-License-Identifier: Apache-2.0 cmake_host_system_information(RESULT TOOLCHAIN_ARCH QUERY OS_PLATFORM) -set(HOST_TOOLS_HOME ${ZEPHYR_SDK_INSTALL_DIR}/sysroots/${TOOLCHAIN_ARCH}-pokysdk-linux) +set(HOST_TOOLS_HOME ${ZEPHYR_SDK_INSTALL_DIR}/hosttools/sysroots/${TOOLCHAIN_ARCH}-pokysdk-linux) # Path used for searching by the find_*() functions, with appropriate # suffixes added. Ensures that the SDK's host tools will be found when diff --git a/cmake/zephyr/llvm/clang_compiler_rt.cfg b/cmake/zephyr/llvm/clang_compiler_rt.cfg new file mode 100644 index 00000000..cd0d01ef --- /dev/null +++ b/cmake/zephyr/llvm/clang_compiler_rt.cfg @@ -0,0 +1,4 @@ +# Copyright (c) 2023 The ChromiumOS Authors +# SPDX-License-Identifier: Apache-2.0 + +--rtlib=compiler-rt diff --git a/cmake/zephyr/llvm/generic.cmake b/cmake/zephyr/llvm/generic.cmake new file mode 100644 index 00000000..c9726c73 --- /dev/null +++ b/cmake/zephyr/llvm/generic.cmake @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: Apache-2.0 + +set(LLVM_TOOLCHAIN_PATH ${ZEPHYR_SDK_INSTALL_DIR}/llvm) + +set(TOOLCHAIN_HOME ${ZEPHYR_SDK_INSTALL_DIR}/llvm/bin) + +set(COMPILER clang) +set(LINKER lld) +set(BINTOOLS llvm) + +set(TOOLCHAIN_HAS_PICOLIBC ON CACHE BOOL "True if toolchain supports picolibc") +set(TOOLCHAIN_HAS_LIBCXX ON CACHE BOOL "True if toolchain supports libc++") diff --git a/cmake/zephyr/llvm/target.cmake b/cmake/zephyr/llvm/target.cmake new file mode 100644 index 00000000..07f51a02 --- /dev/null +++ b/cmake/zephyr/llvm/target.cmake @@ -0,0 +1,43 @@ +# SPDX-License-Identifier: Apache-2.0 + +if("${ARCH}" STREQUAL "arm") + if(DEFINED CONFIG_ARMV8_M_MAINLINE) + # ARMv8-M mainline is ARMv7-M with additional features from ARMv8-M. + set(triple armv8m.main-none-eabi) + elseif(DEFINED CONFIG_ARMV8_M_BASELINE) + # ARMv8-M baseline is ARMv6-M with additional features from ARMv8-M. + set(triple armv8m.base-none-eabi) + elseif(DEFINED CONFIG_ARMV7_M_ARMV8_M_MAINLINE) + # ARMV7_M_ARMV8_M_MAINLINE means that ARMv7-M or backward compatible ARMv8-M + # processor is used. + set(triple armv7m-none-eabi) + elseif(DEFINED CONFIG_ARMV6_M_ARMV8_M_BASELINE) + # ARMV6_M_ARMV8_M_BASELINE means that ARMv6-M or ARMv8-M supporting the + # Baseline implementation processor is used. + set(triple armv6m-none-eabi) + else() + # Default ARM target supported by all processors. + set(triple arm-none-eabi) + endif() +elseif("${ARCH}" STREQUAL "arm64") + set(triple aarch64-none-elf) +elseif("${ARCH}" STREQUAL "riscv") + if(CONFIG_64BIT) + set(triple riscv64-none-elf) + else() + set(triple riscv32-none-elf) + endif() +endif() + +if(DEFINED triple) + set(CMAKE_C_COMPILER_TARGET ${triple}) + set(CMAKE_ASM_COMPILER_TARGET ${triple}) + set(CMAKE_CXX_COMPILER_TARGET ${triple}) + + unset(triple) +endif() + +list(APPEND TOOLCHAIN_C_FLAGS --config + ${ZEPHYR_SDK_INSTALL_DIR}/cmake/zephyr/llvm/clang_compiler_rt.cfg) +list(APPEND TOOLCHAIN_LD_FLAGS --config + ${ZEPHYR_SDK_INSTALL_DIR}/cmake/zephyr/llvm/clang_compiler_rt.cfg) diff --git a/crosstool-ng b/crosstool-ng index 787dd4c9..53da3623 160000 --- a/crosstool-ng +++ b/crosstool-ng @@ -1 +1 @@ -Subproject commit 787dd4c9fda66eaddcc7dabe93cc48ebfa40090f +Subproject commit 53da3623f05d254d6f34ae2a349734479984fc5c diff --git a/gcc b/gcc index 45ac4a33..60300551 160000 --- a/gcc +++ b/gcc @@ -1 +1 @@ -Subproject commit 45ac4a338c2d24f4c9b7c543f7a66d6ec794237c +Subproject commit 6030055143f09163c9e0b9232f3abf7ea95ba4e3 diff --git a/gcc_arc b/gcc_arc index dca43c4a..f385c5c9 160000 --- a/gcc_arc +++ b/gcc_arc @@ -1 +1 @@ -Subproject commit dca43c4af7047bc03d723a2d57c99d738cbd7e03 +Subproject commit f385c5c9a1ff090b896dc604238ea198e12fef46 diff --git a/llvm b/llvm new file mode 160000 index 00000000..3dc6eb42 --- /dev/null +++ b/llvm @@ -0,0 +1 @@ +Subproject commit 3dc6eb42407bb419e36f061ad6b80d5ac3db71ec diff --git a/picolibc b/picolibc index 560946f2..c7cc2483 160000 --- a/picolibc +++ b/picolibc @@ -1 +1 @@ -Subproject commit 560946f26db075c296beea5b39d99e6de43c9010 +Subproject commit c7cc2483d591784bb2707f72b0784d92074f5347 diff --git a/release-notes.md b/release-notes.md index d4bf49a7..488dfa6b 100644 --- a/release-notes.md +++ b/release-notes.md @@ -1,5 +1,23 @@ # Notes / Changes in various releases +## Zephyr SDK 0.18.0-alpha2 + +- general: + + * Added Clang/LLVM 19.1.1 toolchain with Arm and RISC-V architecture support. + * Introduced Clang/LLVM toolchain distribution bundle + (`zephyr-sdk-VER_HOST_llvm`). + * Renamed existing "full" GNU toolchain distribution bundle to + `zephyr-sdk-VER_HOST_gnu`. + * Windows executables now link against UCRT, which supports Unicode. + +- cmake: + + * Restructured toolchain CMake script to support GNU and LLVM toolchains. + This requires Zephyr 4.1.0 or above (or the latest `collab-sdk-0.18-dev`). + * Zephyr SDK GNU toolchain now declares `TOOLCHAIN_HAS_GLIBCXX`. + * Zephyr SDK LLVM toolchain now declares `TOOLCHAIN_HAS_LIBCXX`. + ## Zephyr SDK 0.17.1-rc1 - general: diff --git a/scripts/llvm/CMakeLists.txt b/scripts/llvm/CMakeLists.txt new file mode 100644 index 00000000..f28a6bfa --- /dev/null +++ b/scripts/llvm/CMakeLists.txt @@ -0,0 +1,2435 @@ +# Copyright (c) 2022, Arm Limited and affiliates. +# Copyright (c) 2024 Zephyr Project members and individual contributors +# +# 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. + + +# How to use this file +# +# This file is used to build Zephyr SDK LLVM +# Recent versions of the following tools are pre-requisites: +# * A toolchain such as gcc & binutils +# * cmake +# * meson +# * ninja +# * python3 +# * make and qemu to run tests +# +# Commands to build: +# mkdir build +# cd build +# cmake -GNinja .. +# ninja +# ninja check-llvm-toolchain +# +# To install the toolchain run: +# cmake . --install-prefix /absolute/path/to/install/directory +# ninja install-llvm-toolchain +# +# +# This file is designed to be used in a way that will be familiar to +# LLVM developers. Targets like clang and check-all can be built as usual. +# In addition there are targets to build picolibc & runtimes variants. +# +# +# Cross-building from Linux to Windows MinGW is supported. +# Note that a build created this way includes GCC & MinGW DLLs which +# come under a different license. +# +# To enable cross-building run: +# cmake . -DLLVM_TOOLCHAIN_CROSS_BUILD_MINGW=ON -DCMAKE_INSTALL_PREFIX=$(pwd)/install-mingw +# +# If cross-building, there will be two toolchains built: +# 1. The "build" toolchain. This is used to build the libraries. +# 2. The "host" toolchain. This is the toolchain that will be packaged +# up into "Zephyr SDK LLVM". +# For "native" builds the "build" toolchain is also used as the "host" +# toolchain. +# +# The terminology can be pretty confusing when you've got +# toolchains building toolchains. There's a good explanation at +# https://docs.conan.io/en/latest/systems_cross_building/cross_building.html +# +# To build the "build" toolchain we add the llvm source as a +# subdirectory. This means you can build all its targets such +# as check-llvm directly. +# If cross-building, a "host" toolchain is built. It is built as a +# separate project. +# +# When libraries are built, they are always copied into the "build" +# toolchain. The primary reason for this is to minimise the number of +# if/else statements in the CMake code, but it has the nice side-effect +# that a cross-build is almost a superset of a native build. +# It is only at install time that one of either the "build" or "host" +# toolchain is copied to the install location. +# This makes it easy to switch back and forth between native and cross +# builds with: +# cmake . -DLLVM_TOOLCHAIN_CROSS_BUILD_MINGW= --install-prefix=... +# +# +# When building the toolchain repeatedly, the most time-consuming part +# can be building the libraries since each one is configured separately. +# To work around this, the variants that get built can be limited using +# the LLVM_TOOLCHAIN_LIBRARY_VARIANTS option e.g.: +# cmake . '-DLLVM_TOOLCHAIN_LIBRARY_VARIANTS=aarch64;armv6m_soft_nofp' + + +# CONFIGURE_HANDLED_BY_BUILD was introduced in CMake 3.20 and it +# greatly speeds up incremental builds. +cmake_minimum_required(VERSION 3.20) + +option( + LLVM_TOOLCHAIN_CROSS_BUILD_MINGW + "Cross-build for Windows. Using this option implies that you accept the GCC & MinGW licenses." +) +option( + PREBUILT_TARGET_LIBRARIES + "Target libraries are prebuilt so no need to build them" +) +set(TARGET_LIBRARIES_DIR + "lib/clang-runtimes" CACHE STRING + "Directory containing the target libraries." +) +set(LLVM_TOOLCHAIN_LIBRARY_VARIANTS + "" CACHE STRING + "Build only the specified library variants. If not specified then build all variants." +) +option( + LIBS_DEPEND_ON_TOOLS + "Automatically ensure tools like clang are up to date before building libraries. + Set this to OFF if you're working on the libraries and want to avoid rebuilding + the tools every time you update llvm-project." + ON +) +set( + LLVMPROJECT_SOURCE_DIR + "${CMAKE_CURRENT_SOURCE_DIR}/../../llvm" CACHE STRING + "The directory containing LLVM Project source code" +) +set( + PICOLIBC_SOURCE_DIR + "${CMAKE_CURRENT_SOURCE_DIR}/../../picolibc" CACHE STRING + "The directory containing Picolibc source code" +) +set( + NEWLIB_SOURCE_DIR + "${CMAKE_CURRENT_SOURCE_DIR}/../../newlib" CACHE STRING + "The directory containing Newlib source code" +) +set(LLVM_TOOLCHAIN_C_LIBRARY + "picolibc" CACHE STRING + "Which C library to use." +) +set_property(CACHE LLVM_TOOLCHAIN_C_LIBRARY + PROPERTY STRINGS picolibc newlib llvmlibc) + +# Previously, the LLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL option was +# called LLVM_TOOLCHAIN_NEWLIB_OVERLAY_INSTALL. Detect a setting of +# that name, in case it's in an existing CMakeCache.txt or command +# line, and use it to set the default for the more general option +# name. +if(LLVM_TOOLCHAIN_NEWLIB_OVERLAY_INSTALL) + set(overlay_install_default ON) +else() + set(overlay_install_default OFF) +endif() +option(LLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL + "Make cpack build an overlay package that can be unpacked over the main toolchain to install a secondary set of libraries based on newlib or llvm-libc." + ${overlay_install_default}) +if(LLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL) + if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL "picolibc") + message(FATAL_ERROR "LLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL is only permitted for C libraries other than the default picolibc") + endif() +endif() + +set(BUG_REPORT_URL "https://github.com/zephyrproject-rtos/sdk-ng/issues" CACHE STRING "") +set(LLVM_DISTRIBUTION_COMPONENTS + clang-resource-headers + clang + dsymutil + lld + llvm-ar + llvm-config + llvm-cov + llvm-cxxfilt + llvm-dwarfdump + llvm-nm + llvm-objcopy + llvm-objdump + llvm-profdata + llvm-ranlib + llvm-readelf + llvm-readobj + llvm-size + llvm-strings + llvm-strip + llvm-symbolizer + LTO + CACHE STRING "" +) +set(LLVM_TOOLCHAIN_DISTRIBUTION_COMPONENTS + llvm-toolchain-config-files + llvm-toolchain-docs + llvm-toolchain-libs + llvm-toolchain-samples + llvm-toolchain-third-party-licenses + CACHE STRING "Components defined by this CMakeLists that should be +installed by the install-llvm-toolchain target" +) +set(LLVM_ENABLE_PROJECTS clang;lld CACHE STRING "") +set(LLVM_TARGETS_TO_BUILD AArch64;ARM;RISCV CACHE STRING "") +set(LLVM_DEFAULT_TARGET_TRIPLE aarch64-linux-gnu CACHE STRING "") +set(LLVM_APPEND_VC_REV OFF CACHE BOOL "") +set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") +set(CLANG_DEFAULT_LINKER lld CACHE STRING "") + +# Default to a release build +# (CMAKE_BUILD_TYPE is a special CMake variable so if you want to set +# it then you have to FORCE it). +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release CACHE BOOL "" FORCE) +endif() + +find_package(Python3 REQUIRED COMPONENTS Interpreter) + +if(NOT CMAKE_C_COMPILER_LAUNCHER AND NOT CMAKE_CXX_COMPILER_LAUNCHER) + # If ccache is available then use it by default. + find_program(CCACHE_EXECUTABLE ccache) + if(CCACHE_EXECUTABLE) + set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE FILEPATH "" FORCE) + set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_EXECUTABLE}" CACHE FILEPATH "" FORCE) + endif() +endif() + +# If lld is available then use it by default. +find_program(LLD_EXECUTABLE lld) +if(LLD_EXECUTABLE) + set(LLVM_USE_LINKER lld CACHE STRING "") +endif() + +# A lot of files get installed which makes the install messages too +# noisy to be useful so default to disabling them. +set(CMAKE_INSTALL_MESSAGE NEVER CACHE STRING "") + +include(ExternalProject) +include(ProcessorCount) + +################################################################################################## +# We set all project properties later, this call is just to enable the +# CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT check +project(ZephyrSDKLLVM) +# We generally want to install to a local directory to see what the +# output will look like rather than install into the system, so change +# the default accordingly. +# See https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT.html +# Note that THIS CODE ONLY WORKS AFTER THE FIRST CALL TO PROJECT so it +# can't be moved after the add_subdirectory() command below as it will be too late - +# the llvm project will set it to the default system install directory. +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX + "${CMAKE_BINARY_DIR}/install" + CACHE PATH "" FORCE + ) +endif() +################################################################################################## + +# Whether to try to build C++ libraries. (We can't currently do this +# for all choices of C library.) +set(CXX_LIBS ON) + +if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL newlib) + install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/newlib.cfg + DESTINATION bin + COMPONENT llvm-toolchain-newlib-configs + ) +endif() + +install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/Omax.cfg + ${CMAKE_CURRENT_SOURCE_DIR}/OmaxLTO.cfg + DESTINATION bin + COMPONENT llvm-toolchain-config-files +) + +if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL llvmlibc) + install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/llvmlibc.cfg + DESTINATION bin + COMPONENT llvm-toolchain-llvmlibc-configs + ) + + # We aren't yet able to build C++ libraries to go with llvm-libc + set(CXX_LIBS OFF) + + # We need to build libc-hdrgen + ExternalProject_Add( + libc_hdrgen + SOURCE_DIR ${LLVMPROJECT_SOURCE_DIR}/llvm + DEPENDS ${lib_tool_dependencies} + CMAKE_ARGS + -DLLVM_ENABLE_RUNTIMES=libc + -DLLVM_LIBC_FULL_BUILD=ON + -DCMAKE_BUILD_TYPE=Debug + STEP_TARGETS build install + BUILD_COMMAND ${CMAKE_COMMAND} --build . --target libc-hdrgen + INSTALL_COMMAND ${CMAKE_COMMAND} -E true + # Always run the build command so that incremental builds are correct. + BUILD_ALWAYS 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 an empty check target, to simplify the logic below that expects to + # find one for every libc type. We have no current setup to run the LLVM + # libc test suite. + add_custom_target(check-llvmlibc) + + # LLVM libc lacks a configuration for AArch64, but the AArch32 one works + # fine. However, setting the configuration for both architectures to the + # arm config directory means the baremetal config.json is never loaded, + # as it resides in the directory above. To ensure both are used, copy + # them to the same location and point libc to that. + set(LIBC_CFG_DIR ${CMAKE_BINARY_DIR}/llvmlibc-config) + file(COPY + ${LLVMPROJECT_SOURCE_DIR}/libc/config/baremetal/config.json + ${LLVMPROJECT_SOURCE_DIR}/libc/config/baremetal/arm/. + DESTINATION + ${LIBC_CFG_DIR} + ) +endif() + +add_subdirectory( + ${LLVMPROJECT_SOURCE_DIR}/llvm llvm +) + +get_directory_property(LLVM_VERSION_MAJOR DIRECTORY ${LLVMPROJECT_SOURCE_DIR}/llvm DEFINITION LLVM_VERSION_MAJOR) +get_directory_property(LLVM_VERSION_MINOR DIRECTORY ${LLVMPROJECT_SOURCE_DIR}/llvm DEFINITION LLVM_VERSION_MINOR) +get_directory_property(LLVM_VERSION_PATCH DIRECTORY ${LLVMPROJECT_SOURCE_DIR}/llvm DEFINITION LLVM_VERSION_PATCH) + +project( + ZephyrSDKLLVM + VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH} + DESCRIPTION "Zephyr SDK LLVM" + HOMEPAGE_URL "https://github.com/zephyrproject-rtos/sdk-ng" +) + +# Set package name for shorter archive file name +set(SHORT_PACKAGE_NAME "zephyr-sdk-llvm") + +# Set package name and version. +if(DEFINED LLVM_TOOLCHAIN_PACKAGE_NAME) + set(PACKAGE_NAME ${LLVM_TOOLCHAIN_PACKAGE_NAME}) +else() + set(PACKAGE_NAME ${SHORT_PACKAGE_NAME}) +endif() +set(CPACK_PACKAGE_NAME ${PACKAGE_NAME}) +set(PACKAGE_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}") +if(DEFINED LLVM_TOOLCHAIN_VERSION_SUFFIX) + set(PACKAGE_VERSION "${PACKAGE_VERSION}-${LLVM_TOOLCHAIN_VERSION_SUFFIX}") +endif() + +# Restrict which LLVM components are installed. +if(LLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL) + set(CPACK_COMPONENTS_ALL + llvm-toolchain-libs + llvm-toolchain-${LLVM_TOOLCHAIN_C_LIBRARY}-configs + llvm-toolchain-third-party-licenses) +elseif(LLVM_TOOLCHAIN_CROSS_BUILD_MINGW) + set(CPACK_COMPONENTS_ALL ${LLVM_TOOLCHAIN_DISTRIBUTION_COMPONENTS} llvm-toolchain-mingw) +else() + set(CPACK_COMPONENTS_ALL ${LLVM_TOOLCHAIN_DISTRIBUTION_COMPONENTS} ${LLVM_DISTRIBUTION_COMPONENTS}) +endif() +# Enable limiting the installed components in TGZ and ZIP packages. +set(CPACK_ARCHIVE_COMPONENT_INSTALL TRUE) +# Don't create a separate archive for each component. +set(CPACK_COMPONENTS_GROUPING ALL_COMPONENTS_IN_ONE) +# When extracting the files put them in an ArmCompiler-.../ directory. +# Exception: the overlay packages do not do this, because they have +# to be able to unpack over the top of an existing installation on all +# platforms, and each platform has a different top-level directory name. +if(LLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL) + set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY FALSE) +else() + set(CPACK_COMPONENT_INCLUDE_TOPLEVEL_DIRECTORY TRUE) +endif() +# Compress package in parallel. +set(CPACK_THREADS 0 CACHE STRING "") + +# set processor_name +string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} processor_name) +if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + # If we're compiling on OSX we need to understand what targets we're + # building for. + string(FIND "${CMAKE_OSX_ARCHITECTURES}" "x86_64" x86_result) + string(FIND "${CMAKE_OSX_ARCHITECTURES}" "arm64" arm64_result) + + if((NOT ${x86_result} EQUAL -1) AND (NOT ${arm64_result} EQUAL -1)) + set(processor_name "universal") + elseif(NOT ${x86_result} EQUAL -1) + set(processor_name "x86_64") + elseif(NOT ${arm64_result} EQUAL -1) + set(processor_name "arm64") + # CMAKE_OSX_ARCHITECTURES wasn't set or malformed + # if it was malformed, we'll catch that later in the process + # otherwise processor_name is already the system processor name + endif() +else() + string(REGEX MATCH "amd64|x64|x86" x86_match ${processor_name}) + if(x86_match) + set(processor_name "x86_64") + else() + set(processor_name "AArch64") + endif() +endif() + +if(LLVM_TOOLCHAIN_CROSS_BUILD_MINGW) + set(CPACK_SYSTEM_NAME "Windows-${processor_name}") +else() + set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}-${processor_name}") +endif() + +set(CPACK_PACKAGE_VERSION ${PACKAGE_VERSION}) + +if(LLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL) + set(PACKAGE_FILE_NAME ${PACKAGE_NAME}-${LLVM_TOOLCHAIN_C_LIBRARY}-overlay-${PACKAGE_VERSION}) +else() + set(PACKAGE_FILE_NAME ${PACKAGE_NAME}-${PACKAGE_VERSION}-${CPACK_SYSTEM_NAME}) +endif() +set(CPACK_PACKAGE_FILE_NAME ${PACKAGE_FILE_NAME}) + +# Including CPack again after llvm CMakeLists.txt included it +# resets CPACK_PACKAGE_VERSION to the default MAJOR.MINOR.PATCH format. +include(CPack) + +# Ensure LLVM tool symlinks are installed. +list(APPEND CMAKE_MODULE_PATH ${LLVMPROJECT_SOURCE_DIR}/llvm/cmake/modules) +llvm_install_symlink(LLVM llvm-ranlib llvm-ar ALWAYS_GENERATE) +llvm_install_symlink(LLVM llvm-readelf llvm-readobj ALWAYS_GENERATE) +llvm_install_symlink(LLVM llvm-strip llvm-objcopy ALWAYS_GENERATE) + +if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL picolibc) + # For building picolibc use Meson. + # Although picolibc has support for building with CMake, the Meson code + # is more mature and works better with LLVM. + find_program(MESON_EXECUTABLE meson REQUIRED) +endif() + +include(cmake/to_meson_list.cmake) + +# Groups all the targets that comprise the toolchain. +add_custom_target(llvm-toolchain ALL) + +# Groups all the runtime targets +add_custom_target(llvm-toolchain-runtimes) + +# Groups all C++ runtime libraries tests +add_custom_target(check-llvm-toolchain-runtimes) +add_custom_target(check-compiler-rt) +add_custom_target(check-cxxabi) +add_custom_target(check-unwind) +add_custom_target(check-cxx) + +add_dependencies( + check-llvm-toolchain-runtimes + check-cxxabi + check-unwind + check-cxx +) + +if(NOT LLVM_TOOLCHAIN_CROSS_BUILD_MINGW) + add_dependencies( + llvm-toolchain + ${LLVM_DISTRIBUTION_COMPONENTS} + ) +endif() + +add_dependencies( + llvm-toolchain + llvm-toolchain-runtimes +) + +foreach(variant ${LLVM_TOOLCHAIN_LIBRARY_VARIANTS}) + set(enable_${variant} TRUE) +endforeach() + +if(LIBS_DEPEND_ON_TOOLS) + set(lib_tool_dependencies + clang + lld + llvm-ar + llvm-config + llvm-nm + llvm-ranlib + llvm-strip + ) +endif() + +set(picolibc_specific_runtimes_options + -DLIBCXXABI_ENABLE_THREADS=OFF + -DLIBCXX_TEST_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/test-support/llvm-libc++-picolibc.cfg.in + -DLIBCXXABI_TEST_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/test-support/llvm-libc++abi-picolibc.cfg.in + -DLIBCXX_ENABLE_MONOTONIC_CLOCK=OFF + -DLIBCXX_ENABLE_RANDOM_DEVICE=OFF + -DLIBCXX_ENABLE_THREADS=OFF + -DLIBCXX_ENABLE_WIDE_CHARACTERS=OFF + -DLIBUNWIND_ENABLE_THREADS=OFF + -DLIBUNWIND_TEST_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/test-support/llvm-libunwind-picolibc.cfg.in +) + +set(newlib_specific_runtimes_options + -DLIBCXXABI_ENABLE_THREADS=OFF + -DLIBCXX_ENABLE_THREADS=OFF + -DLIBCXX_ENABLE_MONOTONIC_CLOCK=OFF + -DLIBCXX_ENABLE_RANDOM_DEVICE=OFF + -DLIBCXX_ENABLE_WIDE_CHARACTERS=ON + -DLIBCXX_ENABLE_LOCALIZATION=OFF + -DLIBUNWIND_ENABLE_THREADS=OFF +) + +if(LLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL) + # If we're building a non-default libc with the intention of + # installing it as an overlay on the main package archive, then + # all of its includes, libraries and multilib.yaml go in a + # subdirectory of lib/clang-runtimes. Configuration files in the + # bin directory will make it easy to reset the sysroot to point at + # that subdir. + set(library_subdir "/${LLVM_TOOLCHAIN_C_LIBRARY}") +else() + set(library_subdir "") +endif() + +add_custom_target(check-picolibc) +# Set LLVM_DEFAULT_EXTERNAL_LIT to the directory of clang +# which was build in previous step. This path is not exported +# by add_subdirectory of llvm project +set(LLVM_DEFAULT_EXTERNAL_LIT "${LLVM_BINARY_DIR}/bin/llvm-lit") + +add_custom_target(check-newlib) # FIXME: put things in this + +function(get_test_executor_params target_triple qemu_machine qemu_cpu qemu_params) + if(target_triple MATCHES "^riscv32") + set(qemu_command "qemu-system-riscv32") + elseif(target_triple MATCHES "^riscv64") + set(qemu_command "qemu-system-riscv64") + elseif(target_triple MATCHES "^aarch64") + set(qemu_command "qemu-system-aarch64") + else() + set(qemu_command "qemu-system-arm") + endif() + + # Use colon as a separator because comma and semicolon are used for + # other purposes in CMake. + string(REPLACE " " ":" qemu_params_list "${qemu_params}") + + set( + test_executor_params + --qemu-command ${qemu_command} + --qemu-machine ${qemu_machine}) + if(qemu_cpu) + list(APPEND test_executor_params --qemu-cpu ${qemu_cpu}) + endif() + if(qemu_params_list) + list(APPEND test_executor_params "--qemu-params=${qemu_params_list}") + endif() + set(test_executor_params "${test_executor_params}" PARENT_SCOPE) +endfunction() + +function( + add_picolibc + directory + variant + target_triple + flags + build_type + test_executor_params + default_boot_flash_addr + default_boot_flash_size + default_flash_addr + default_flash_size + default_ram_addr + default_ram_size + default_stack_size +) + if(CMAKE_INSTALL_MESSAGE STREQUAL NEVER) + set(MESON_INSTALL_QUIET "--quiet") + endif() + + if(target_triple MATCHES "^riscv32") + set(cpu_family riscv32) + set(enable_long_double_test true) + elseif(target_triple MATCHES "^riscv64") + set(cpu_family riscv64) + set(enable_long_double_test true) + elseif(target_triple MATCHES "^aarch64") + set(cpu_family aarch64) + set(enable_long_double_test false) + else() + set(cpu_family arm) + set(enable_long_double_test true) + endif() + + if(build_type MATCHES "minsize") + set(newlib_nano_malloc "true") + else() + set(newlib_nano_malloc "false") + endif() + + ExternalProject_Add( + picolibc_${variant} + SOURCE_DIR ${PICOLIBC_SOURCE_DIR} + INSTALL_DIR "${LLVM_BINARY_DIR}/${directory}" + PREFIX picolibc/${variant} + DEPENDS ${lib_tool_dependencies} + CONFIGURE_COMMAND + ${MESON_EXECUTABLE} + setup + -Dincludedir=include + -Dlibdir=lib + -Dspecsdir=none + -Dmultilib=false + -Dtests-enable-stack-protector=false + -Dtest-long-double=${enable_long_double_test} + -Dnewlib-nano-malloc=${newlib_nano_malloc} + --prefix + --cross-file /meson-cross-build.txt + --buildtype=${build_type} + + BUILD_COMMAND ${MESON_EXECUTABLE} configure -Dtests=false + COMMAND ${MESON_EXECUTABLE} compile + INSTALL_COMMAND ${MESON_EXECUTABLE} install ${MESON_INSTALL_QUIET} + TEST_COMMAND + ${Python3_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/test-support/run-picolibc-tests.py + --meson-command ${MESON_EXECUTABLE} + --picolibc-build-dir + --picolibc-source-dir + --variant ${variant} + USES_TERMINAL_CONFIGURE FALSE + USES_TERMINAL_BUILD TRUE + USES_TERMINAL_TEST TRUE + LIST_SEPARATOR , + # Always run the build command so that incremental builds are correct. + BUILD_ALWAYS TRUE + CONFIGURE_HANDLED_BY_BUILD TRUE + TEST_EXCLUDE_FROM_MAIN TRUE + STEP_TARGETS install test + ) + + # Set meson_c_args to a comma-separated list of the clang path + # and flags e.g. 'path/to/clang', '--target=armv6m-none-eabi', + # '-march=armv6m' + separate_arguments(flags) + list(PREPEND flags "${LLVM_BINARY_DIR}/bin/clang${CMAKE_EXECUTABLE_SUFFIX}") + list(APPEND flags --sysroot "${LLVM_BINARY_DIR}/${directory}") + to_meson_list("${flags}" meson_c_args) + + set(test_executor_bin ${CMAKE_CURRENT_SOURCE_DIR}/test-support/picolibc-test-wrapper.py) + to_meson_list("${test_executor_params}" test_executor_params) + + ExternalProject_Get_Property(picolibc_${variant} BINARY_DIR) + configure_file(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/cmake/meson-cross-build.txt.in ${BINARY_DIR}/meson-cross-build.txt @ONLY) + + # Building picolibc tests requires compiler_rt to be installed. + # Building compiler_rt tests requires picolibc to be installed. + # To solve this compiler_rt relies on picolibc to be just installed, not on + # the full target, which would include tests. Picolibc tests, are enabled + # only in tests step, otherwise, they would be built before install. + ExternalProject_Add_StepDependencies(picolibc_${variant} test compiler_rt_${variant}-install) + + add_custom_target(check-picolibc-${variant}) + add_dependencies(check-picolibc-${variant} picolibc_${variant}-test) + add_dependencies(check-picolibc check-picolibc-${variant}) + add_dependencies(llvm-toolchain-runtimes picolibc_${variant}) +endfunction() + +function( + add_newlib + directory + variant + target_triple + flags + test_executor_params + default_boot_flash_addr + default_boot_flash_size + default_flash_addr + default_flash_size + default_ram_addr + default_ram_size + default_stack_size +) + if(target_triple MATCHES "^aarch64") + set(cpu_family aarch64) + else() + set(cpu_family arm) + endif() + + set(sysroot "${LLVM_BINARY_DIR}/${directory}") + + set(build_env + "CC_FOR_TARGET=${LLVM_BINARY_DIR}/bin/clang -target ${target_triple} -ffreestanding" + "CXX_FOR_TARGET=${LLVM_BINARY_DIR}/bin/clang++ -target ${target_triple} -ffreestanding" + "AR_FOR_TARGET=${LLVM_BINARY_DIR}/bin/llvm-ar" + "AS_FOR_TARGET=${LLVM_BINARY_DIR}/bin/llvm-as" + "NM_FOR_TARGET=${LLVM_BINARY_DIR}/bin/llvm-nm" + "OBJDUMP_FOR_TARGET=${LLVM_BINARY_DIR}/bin/llvm-objdump" + "RANLIB_FOR_TARGET=${LLVM_BINARY_DIR}/bin/llvm-ranlib" + "READELF_FOR_TARGET=${LLVM_BINARY_DIR}/bin/llvm-readelf" + "STRIP_FOR_TARGET=${LLVM_BINARY_DIR}/bin/llvm-strip" + "CFLAGS_FOR_TARGET=${flags} -Wno-error=implicit-function-declaration -D__USES_INITFINI__ -UHAVE_INIT_FINI__ -U_HAVE_INIT_FINI__ -UHAVE_INIT_FINI --sysroot ${sysroot}" + "CCASFLAGS=${flags} -Wno-error=implicit-function-declaration -D__USES_INITFINI__ -UHAVE_INIT_FINI__ -U_HAVE_INIT_FINI__ -UHAVE_INIT_FINI --sysroot ${sysroot}" + ) + + set(make_flags) + ProcessorCount(nproc) + if(NOT nproc EQUAL 0) + set(make_flags -j${nproc}) + endif() + + ExternalProject_Add( + newlib_${variant} + SOURCE_DIR ${NEWLIB_SOURCE_DIR} + INSTALL_DIR "${LLVM_BINARY_DIR}/${directory}" + PREFIX newlib/${variant} + DEPENDS ${lib_tool_dependencies} + CONFIGURE_COMMAND + ${CMAKE_COMMAND} -E env ${build_env} + /configure + --target=${target_triple} + --prefix "${sysroot}" + --exec_prefix /tmpinstall + --enable-newlib-io-long-long + --enable-newlib-register-fini + --disable-newlib-supplied-syscalls + --enable-newlib-io-c99-formats + --disable-nls + --enable-lite-exit + --disable-multilib + --enable-newlib-retargetable-locking + BUILD_COMMAND + ${CMAKE_COMMAND} -E env ${build_env} + make ${make_flags} + && + "${LLVM_BINARY_DIR}/bin/llvm-ar" rcs + /${target_triple}/libgloss/${cpu_family}/libcrt0-rdimon.a + /${target_triple}/libgloss/${cpu_family}/rdimon-crt0.o + && + "${LLVM_BINARY_DIR}/bin/llvm-ar" rcs + /${target_triple}/libgloss/${cpu_family}/libcrt0-nosys.a + /${target_triple}/libgloss/${cpu_family}/crt0.o + INSTALL_COMMAND + make install + && + ${CMAKE_COMMAND} -E copy_directory + /tmpinstall/${target_triple} + ${sysroot} + && + ${CMAKE_COMMAND} -E copy + /${target_triple}/libgloss/${cpu_family}/libcrt0-rdimon.a + ${sysroot}/lib + && + ${CMAKE_COMMAND} -E copy + /${target_triple}/libgloss/${cpu_family}/libcrt0-nosys.a + ${sysroot}/lib + # FIXME: TEST_COMMAND? + USES_TERMINAL_CONFIGURE FALSE + USES_TERMINAL_BUILD TRUE + # Always run the build command so that incremental builds are correct. + BUILD_ALWAYS TRUE + CONFIGURE_HANDLED_BY_BUILD TRUE + TEST_EXCLUDE_FROM_MAIN TRUE + STEP_TARGETS install # FIXME: test? + ) + + add_dependencies( + llvm-toolchain-runtimes + newlib_${variant} + ) +endfunction() + +function( + add_llvmlibc + directory + variant + target_triple + flags + test_executor_params + default_boot_flash_addr + default_boot_flash_size + default_flash_addr + default_flash_size + default_ram_addr + default_ram_size + default_stack_size +) + get_runtimes_flags("${directory}" "${flags}") + + set(runtimes_flags "${runtimes_flags} -Wno-error=atomic-alignment") + + set(common_cmake_args + -DCMAKE_AR=${LLVM_BINARY_DIR}/bin/llvm-ar${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_ASM_COMPILER=${LLVM_BINARY_DIR}/bin/clang${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_ASM_COMPILER_TARGET=${target_triple} + -DCMAKE_ASM_FLAGS=${runtimes_flags} + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_CXX_COMPILER=${LLVM_BINARY_DIR}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_CXX_COMPILER_TARGET=${target_triple} + -DCMAKE_CXX_FLAGS=${runtimes_flags} + -DCMAKE_C_COMPILER=${LLVM_BINARY_DIR}/bin/clang${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_C_COMPILER_TARGET=${target_triple} + -DCMAKE_C_FLAGS=${runtimes_flags} + -DCMAKE_INSTALL_MESSAGE=${CMAKE_INSTALL_MESSAGE} + -DCMAKE_INSTALL_PREFIX= + -DCMAKE_NM=${LLVM_BINARY_DIR}/bin/llvm-nm${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_RANLIB=${LLVM_BINARY_DIR}/bin/llvm-ranlib${CMAKE_EXECUTABLE_SUFFIX} + # Let CMake know we're cross-compiling + -DCMAKE_SYSTEM_NAME=Generic + -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY + ) + + ExternalProject_Add( + llvmlibc_${variant} + SOURCE_DIR ${LLVMPROJECT_SOURCE_DIR}/runtimes + PREFIX llvmlibc/${variant} + INSTALL_DIR llvmlibc/${variant}/install + DEPENDS ${lib_tool_dependencies} ${libc_target} libc_hdrgen + CMAKE_ARGS + ${common_cmake_args} + -DLIBC_TARGET_TRIPLE=${target_triple} + -DLIBC_HDRGEN_EXE=${LIBC_HDRGEN} + -DLIBC_CONFIG_PATH=${LIBC_CFG_DIR} + -DLIBC_CONF_TIME_64BIT=ON + -DLIBC_NAMESPACE=__llvm_libc_${LLVM_VERSION_MAJOR}_${LLVM_VERSION_MINOR}_${LLVM_VERSION_PATCH} # The default namespace generated for release candidates is invalid + -DLLVM_CMAKE_DIR=${LLVM_BINARY_DIR}/lib/cmake/llvm + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON + -DLLVM_ENABLE_RUNTIMES=libc + -DLLVM_INCLUDE_TESTS=OFF # llvmlibc's tests require C++, so can't be built until llvmlibc can support libc++ + -DLLVM_LIBC_FULL_BUILD=ON + STEP_TARGETS build install + USES_TERMINAL_CONFIGURE FALSE + USES_TERMINAL_BUILD TRUE + USES_TERMINAL_INSTALL TRUE + USES_TERMINAL_TEST TRUE + LIST_SEPARATOR , + # Always run the build command so that incremental builds are correct. + BUILD_ALWAYS TRUE + CONFIGURE_HANDLED_BY_BUILD TRUE + INSTALL_COMMAND ${CMAKE_COMMAND} --install . + # Copy llvm-libc lib directory, moving libraries out of their + # target-specific subdirectory. + COMMAND + ${CMAKE_COMMAND} + -E copy_directory + /lib/${target_triple} + "${LLVM_BINARY_DIR}/${directory}/lib" + # And copy the include directory, which is already arranged right. + COMMAND + ${CMAKE_COMMAND} + -E copy_directory + /include + "${LLVM_BINARY_DIR}/${directory}/include" + ) + + ExternalProject_Add( + llvmlibc-support_${variant} + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/llvmlibc-support + PREFIX llvmlibc-support/${variant} + INSTALL_DIR "${LLVM_BINARY_DIR}/${directory}" + DEPENDS ${lib_tool_dependencies} llvmlibc_${variant}-install + CMAKE_ARGS ${common_cmake_args} + STEP_TARGETS build install + USES_TERMINAL_CONFIGURE FALSE + USES_TERMINAL_BUILD TRUE + USES_TERMINAL_INSTALL TRUE + USES_TERMINAL_TEST TRUE + LIST_SEPARATOR , + # Always run the build command so that incremental builds are correct. + BUILD_ALWAYS TRUE + CONFIGURE_HANDLED_BY_BUILD TRUE + ) + + add_dependencies( + llvm-toolchain-runtimes + llvmlibc_${variant} + llvmlibc-support_${variant} + ) +endfunction() + +macro( + add_libc + directory + variant + target_triple + flags + picolibc_build_type + test_executor_params + default_boot_flash_addr + default_boot_flash_size + default_flash_addr + default_flash_size + default_ram_addr + default_ram_size + default_stack_size +) + # It would be nice to just pass ${ARGN} to both the underlying functions, + # but that has the side effect of expanding any list arguments (e.g. + # test_executor_params) into lots of separate words - the same bug that + # $* has in POSIX sh. We want the analogue of "$@" here, but I don't know + # of one for cmake. + if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL picolibc) + add_picolibc( + "${directory}" + "${variant}" + "${target_triple}" + "${flags}" + "${picolibc_build_type}" + "${test_executor_params}" + "${default_boot_flash_addr}" + "${default_boot_flash_size}" + "${default_flash_addr}" + "${default_flash_size}" + "${default_ram_addr}" + "${default_ram_size}" + "${default_stack_size}" + ) + elseif(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL newlib) + add_newlib( + "${directory}" + "${variant}" + "${target_triple}" + "${flags}" + "${test_executor_params}" + "${default_boot_flash_addr}" + "${default_boot_flash_size}" + "${default_flash_addr}" + "${default_flash_size}" + "${default_ram_addr}" + "${default_ram_size}" + "${default_stack_size}" + ) + elseif(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL llvmlibc) + add_llvmlibc( + "${directory}" + "${variant}" + "${target_triple}" + "${flags}" + "${test_executor_params}" + "${default_boot_flash_addr}" + "${default_boot_flash_size}" + "${default_flash_addr}" + "${default_flash_size}" + "${default_ram_addr}" + "${default_ram_size}" + "${default_stack_size}" + ) + endif() +endmacro() + +function(get_runtimes_flags directory flags) + set(runtimes_flags "${flags} -ffunction-sections -fdata-sections -fno-ident --sysroot ${LLVM_BINARY_DIR}/${directory}" PARENT_SCOPE) +endfunction() + +function( + add_compiler_rt + directory + variant + target_triple + flags + test_executor + libc_target +) + # We can't always put the exact target + # architecture in the triple, because compiler-rt's cmake + # system doesn't recognize every possible Arm architecture + # version. So mostly we just say 'arm' and control the arch + # version via -march=armv7m (or whatever). + # Exceptions are architectures pre-armv7, which compiler-rt expects to + # see in the triple because that's where it looks to decide whether to + # use specific assembly sources. + if(NOT target_triple MATCHES "^(aarch64-none-elf|arm-none-eabi|armv[4-6]|riscv32-none-elf|riscv64-none-elf)") + message(FATAL_ERROR "\ +Target triple name \"${target_triple}\" not compatible with compiler-rt. +Use -march to specify the architecture.") + endif() + # Also, compiler-rt looks in the ABI component of the + # triple to decide whether to use the hard float ABI. + if(flags MATCHES "-mfloat-abi=hard" AND NOT target_triple MATCHES "-eabihf$") + message(FATAL_ERROR "\ +Hard-float library with target triple \"${target_triple}\" must end \"-eabihf\"") + endif() + string(REPLACE "-none-" "-unknown-none-" normalized_target_triple ${target_triple}) + + get_runtimes_flags("${directory}" "${flags}") + + set(compiler_rt_test_flags "${runtimes_flags} -fno-exceptions -fno-rtti -lcrt0-semihost -lsemihost -T picolibcpp.ld") + if(variant STREQUAL "armv6m_soft_nofp") + set(compiler_rt_test_flags "${compiler_rt_test_flags} -fomit-frame-pointer") + endif() + + ExternalProject_Add( + compiler_rt_${variant} + SOURCE_DIR ${LLVMPROJECT_SOURCE_DIR}/compiler-rt + PREFIX compiler-rt/${variant} + INSTALL_DIR compiler-rt/${variant}/install + DEPENDS ${lib_tool_dependencies} ${libc_target} + CMAKE_ARGS + -DCMAKE_AR=${LLVM_BINARY_DIR}/bin/llvm-ar${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_ASM_COMPILER_TARGET=${target_triple} + -DCMAKE_ASM_FLAGS=${runtimes_flags} + -DCMAKE_BUILD_TYPE=Release + -DCMAKE_CXX_COMPILER=${LLVM_BINARY_DIR}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_CXX_COMPILER_TARGET=${target_triple} + -DCMAKE_CXX_FLAGS=${runtimes_flags} + -DCMAKE_C_COMPILER=${LLVM_BINARY_DIR}/bin/clang${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_C_COMPILER_TARGET=${target_triple} + -DCMAKE_C_FLAGS=${runtimes_flags} + -DCMAKE_INSTALL_MESSAGE=${CMAKE_INSTALL_MESSAGE} + -DCMAKE_INSTALL_PREFIX= + -DCMAKE_NM=${LLVM_BINARY_DIR}/bin/llvm-nm${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_RANLIB=${LLVM_BINARY_DIR}/bin/llvm-ranlib${CMAKE_EXECUTABLE_SUFFIX} + # Let CMake know we're cross-compiling + -DCMAKE_SYSTEM_NAME=Generic + -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY + -DCOMPILER_RT_BAREMETAL_BUILD=ON + -DCOMPILER_RT_BUILD_LIBFUZZER=OFF + -DCOMPILER_RT_BUILD_PROFILE=OFF + -DCOMPILER_RT_BUILD_SANITIZERS=OFF + -DCOMPILER_RT_BUILD_XRAY=OFF + -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON + -DCOMPILER_RT_INCLUDE_TESTS=ON + -DCOMPILER_RT_EMULATOR=${test_executor} + -DCOMPILER_RT_TEST_COMPILER=${LLVM_BINARY_DIR}/bin/clang + -DCOMPILER_RT_TEST_COMPILER_CFLAGS=${compiler_rt_test_flags} + -DLLVM_LIT_ARGS=${LLVM_LIT_ARGS} + -DLLVM_CMAKE_DIR=${LLVM_BINARY_DIR}/lib/cmake/llvm + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON + STEP_TARGETS build install + USES_TERMINAL_CONFIGURE FALSE + USES_TERMINAL_BUILD TRUE + USES_TERMINAL_INSTALL TRUE + USES_TERMINAL_TEST TRUE + LIST_SEPARATOR , + # Always run the build command so that incremental builds are correct. + BUILD_ALWAYS TRUE + CONFIGURE_HANDLED_BY_BUILD TRUE + INSTALL_COMMAND ${CMAKE_COMMAND} --install . + # Copy compiler-rt lib directory, moving libraries out of their + # target-specific subdirectory. + COMMAND + ${CMAKE_COMMAND} + -E copy_directory + /lib/${normalized_target_triple} + "${LLVM_BINARY_DIR}/${directory}/lib" + ) + + add_dependencies( + llvm-toolchain-runtimes + compiler_rt_${variant} + ) +endfunction() + +function( + add_libcxx_libcxxabi_libunwind + directory + variant + target_triple + flags + test_executor + libc_target + extra_cmake_options + enable_exceptions + enable_rtti +) + get_runtimes_flags("${directory}" "${flags}") + set(target_name "libcxx_libcxxabi_libunwind_${variant}") + set(prefix "libcxx_libcxxabi_libunwind/${variant}") + set(instal_dir "${LLVM_BINARY_DIR}/${directory}") + if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL picolibc) + list( + APPEND extra_cmake_options + -DLIBCXXABI_ENABLE_EXCEPTIONS=${enable_exceptions} + -DLIBCXXABI_ENABLE_STATIC_UNWINDER=${enable_exceptions} + -DLIBCXX_ENABLE_EXCEPTIONS=${enable_exceptions} + -DLIBCXX_ENABLE_RTTI=${enable_rtti} + ) + endif() + + ExternalProject_Add( + ${target_name} + SOURCE_DIR ${LLVMPROJECT_SOURCE_DIR}/runtimes + INSTALL_DIR ${instal_dir} + PREFIX ${prefix} + DEPENDS ${lib_tool_dependencies} compiler_rt_${variant} ${libc_target} + CMAKE_ARGS + -DCMAKE_AR=${LLVM_BINARY_DIR}/bin/llvm-ar${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_ASM_FLAGS=${runtimes_flags} + -DCMAKE_BUILD_TYPE=MinSizeRel + -DCMAKE_CXX_COMPILER=${LLVM_BINARY_DIR}/bin/clang++${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_CXX_COMPILER_TARGET=${target_triple} + -DCMAKE_CXX_FLAGS=${runtimes_flags} + -DCMAKE_C_COMPILER=${LLVM_BINARY_DIR}/bin/clang${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_C_COMPILER_TARGET=${target_triple} + -DCMAKE_C_FLAGS=${runtimes_flags} + -DCMAKE_INSTALL_MESSAGE=${CMAKE_INSTALL_MESSAGE} + -DCMAKE_INSTALL_PREFIX=${instal_dir} + -DCMAKE_NM=${LLVM_BINARY_DIR}/bin/llvm-nm${CMAKE_EXECUTABLE_SUFFIX} + -DCMAKE_RANLIB=${LLVM_BINARY_DIR}/bin/llvm-ranlib${CMAKE_EXECUTABLE_SUFFIX} + # Let CMake know we're cross-compiling + -DCMAKE_SYSTEM_NAME=Generic + -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY + -DLIBC_LINKER_SCRIPT=picolibcpp.ld + -DLIBCXXABI_BAREMETAL=ON + -DLIBCXXABI_ENABLE_ASSERTIONS=OFF + -DLIBCXXABI_ENABLE_SHARED=OFF + -DLIBCXXABI_ENABLE_STATIC=ON + -DLIBCXXABI_LIBCXX_INCLUDES="${LLVM_BINARY_DIR}/${directory}/include/c++/v1" + -DLIBCXXABI_USE_COMPILER_RT=ON + -DLIBCXXABI_USE_LLVM_UNWINDER=ON + -DLIBCXXABI_TEST_PARAMS=executor=${test_executor} + -DLIBCXXABI_ADDITIONAL_COMPILE_FLAGS=-D_POSIX_C_SOURCE=200809L$-D_XOPEN_SOURCE=700$-D_GNU_SOURCE + -DLIBCXX_ABI_UNSTABLE=ON + -DLIBCXX_CXX_ABI=libcxxabi + -DLIBCXX_ENABLE_FILESYSTEM=OFF + -DLIBCXX_ENABLE_SHARED=OFF + -DLIBCXX_ENABLE_STATIC=ON + -DLIBCXX_INCLUDE_BENCHMARKS=OFF + -DLIBCXX_TEST_PARAMS=executor=${test_executor} + -DLIBCXX_ADDITIONAL_COMPILE_FLAGS=-D_POSIX_C_SOURCE=200809L$-D_XOPEN_SOURCE=700$-D_GNU_SOURCE + -DLIBUNWIND_ENABLE_SHARED=OFF + -DLIBUNWIND_ENABLE_STATIC=ON + -DLIBUNWIND_IS_BAREMETAL=ON + -DLIBUNWIND_REMEMBER_HEAP_ALLOC=ON + -DLIBUNWIND_USE_COMPILER_RT=ON + -DLIBUNWIND_TEST_PARAMS=executor=${test_executor} + -DLLVM_LIT_ARGS=${LLVM_LIT_ARGS} + -DLLVM_ENABLE_RUNTIMES=libcxxabi,libcxx,libunwind + -DRUNTIME_TEST_ARCH_FLAGS=${flags} + -DRUNTIME_VARIANT_NAME=${variant} + ${extra_cmake_options} + STEP_TARGETS build + USES_TERMINAL_CONFIGURE FALSE + USES_TERMINAL_BUILD TRUE + USES_TERMINAL_INSTALL TRUE + USES_TERMINAL_TEST TRUE + LIST_SEPARATOR , + # Always run the build command so that incremental builds are correct. + BUILD_ALWAYS TRUE + CONFIGURE_HANDLED_BY_BUILD TRUE + ) + + add_dependencies( + llvm-toolchain-runtimes + ${target_name} + ) +endfunction() + +function(add_compiler_rt_tests variant) + ExternalProject_Add_Step( + compiler_rt_${variant} + check-compiler-rt + COMMAND "${CMAKE_COMMAND}" --build --target check-compiler-rt + USES_TERMINAL TRUE + EXCLUDE_FROM_MAIN TRUE + ALWAYS TRUE + ) + ExternalProject_Add_StepTargets(compiler_rt_${variant} check-compiler-rt) + ExternalProject_Add_StepDependencies( + compiler_rt_${variant} + check-compiler-rt + compiler_rt_${variant}-build + ) + add_custom_target(check-compiler-rt-${variant}) + add_dependencies(check-compiler-rt-${variant} compiler_rt_${variant}-check-compiler-rt) + add_dependencies(check-compiler-rt check-compiler-rt-${variant}) + add_dependencies(check-llvm-toolchain-runtimes-${variant} check-compiler-rt-${variant}) +endfunction() + +function(add_libcxx_libcxxabi_libunwind_tests variant) + set(target_name "libcxx_libcxxabi_libunwind_${variant}") + set(variant_with_extensions "${variant}") + foreach(check_target check-cxxabi check-unwind check-cxx) + ExternalProject_Add_Step( + ${target_name} + ${check_target} + COMMAND "${CMAKE_COMMAND}" --build --target ${check_target} + USES_TERMINAL TRUE + EXCLUDE_FROM_MAIN TRUE + ALWAYS TRUE + ) + ExternalProject_Add_StepTargets(${target_name} ${check_target}) + ExternalProject_Add_StepDependencies( + ${target_name} + ${check_target} + ${target_name}-build + ) + add_custom_target(${check_target}-${variant_with_extensions}) + add_dependencies(${check_target}-${variant_with_extensions} ${target_name}-${check_target}) + add_dependencies(${check_target} ${target_name}-${check_target}) + add_dependencies(check-llvm-toolchain-runtimes-${variant} ${check_target}-${variant_with_extensions}) + endforeach() +endfunction() + +function(get_compiler_rt_target_triple target_arch flags) + if(target_arch MATCHES "^rv32") + set(target_triple "riscv32-none-elf") + elseif(target_arch MATCHES "^rv64") + set(target_triple "riscv64-none-elf") + elseif(target_arch MATCHES "^aarch64") + set(target_triple "aarch64-none-elf") + else() + # Choose the target triple so that compiler-rt will do the + # right thing. We can't always put the exact target + # architecture in the triple, because compiler-rt's cmake + # system doesn't recognize every possible Arm architecture + # version. So mostly we just say 'arm' and control the arch + # version via -march=armv7m (or whatever). + # Exceptions are architectures pre-armv7, which compiler-rt expects to + # see in the triple because that's where it looks to decide whether to + # use specific assembly sources. + if(target_arch MATCHES "^armv[4-6]") + set(target_triple "${target_arch}-none-eabi") + else() + set(target_triple "arm-none-eabi") + endif() + if(flags MATCHES "-mfloat-abi=hard") + # Also, compiler-rt looks in the ABI component of the + # triple to decide whether to use the hard float ABI. + set(target_triple "${target_triple}hf") + endif() + endif() + set(target_triple "${target_triple}" PARENT_SCOPE) +endfunction() + +function(add_library_variant target_arch) + set( + one_value_args + SUFFIX + COMPILE_FLAGS + MULTILIB_FLAGS + PICOLIBC_BUILD_TYPE + QEMU_MACHINE + QEMU_CPU + QEMU_PARAMS + BOOT_FLASH_ADDRESS + BOOT_FLASH_SIZE + FLASH_ADDRESS + FLASH_SIZE + RAM_ADDRESS + RAM_SIZE + STACK_SIZE + ENABLE_EXCEPTIONS + ENABLE_RTTI + ) + cmake_parse_arguments(VARIANT "" "${one_value_args}" "" ${ARGN}) + + if(VARIANT_SUFFIX) + set(variant "${target_arch}_${VARIANT_SUFFIX}") + else() + set(variant "${target_arch}") + endif() + + if(NOT VARIANT_ENABLE_EXCEPTIONS) + set(VARIANT_MULTILIB_FLAGS "${VARIANT_MULTILIB_FLAGS} -fno-exceptions") + endif() + + if(NOT VARIANT_ENABLE_RTTI) + set(VARIANT_MULTILIB_FLAGS "${VARIANT_MULTILIB_FLAGS} -fno-rtti") + endif() + + if(LLVM_TOOLCHAIN_LIBRARY_VARIANTS) + if(NOT enable_${variant}) + message("Disabling library variant ${variant}") + return() + else() + message("Enabling library variant ${variant}") + endif() + endif() + + if(target_arch MATCHES "^rv32") + set(parent_dir_name riscv32-none-elf) + elseif(target_arch MATCHES "^rv64") + set(parent_dir_name riscv64-none-elf) + elseif(target_arch MATCHES "^aarch64") + set(parent_dir_name aarch64-none-elf) + else() + set(parent_dir_name arm-none-eabi) + endif() + + get_compiler_rt_target_triple("${target_arch}" "${VARIANT_COMPILE_FLAGS}") + + set(directory "${TARGET_LIBRARIES_DIR}${library_subdir}/${parent_dir_name}/${variant}") + set(VARIANT_COMPILE_FLAGS "--target=${target_triple} ${VARIANT_COMPILE_FLAGS}") + get_test_executor_params( + "${target_triple}" + "${VARIANT_QEMU_MACHINE}" + "${VARIANT_QEMU_CPU}" + "${VARIANT_QEMU_PARAMS}" + ) + set( + lit_test_executor + ${CMAKE_CURRENT_SOURCE_DIR}/test-support/lit-exec-qemu.py + ${test_executor_params} + ) + list(JOIN lit_test_executor " " lit_test_executor) + if(NOT PREBUILT_TARGET_LIBRARIES) + add_libc( + "${directory}" + "${variant}" + "${target_triple}" + "${VARIANT_COMPILE_FLAGS}" + "${VARIANT_PICOLIBC_BUILD_TYPE}" + "${test_executor_params}" + "${VARIANT_BOOT_FLASH_ADDRESS}" + "${VARIANT_BOOT_FLASH_SIZE}" + "${VARIANT_FLASH_ADDRESS}" + "${VARIANT_FLASH_SIZE}" + "${VARIANT_RAM_ADDRESS}" + "${VARIANT_RAM_SIZE}" + "${VARIANT_STACK_SIZE}" + ) + add_compiler_rt( + "${directory}" + "${variant}" + "${target_triple}" + "${VARIANT_COMPILE_FLAGS}" + "${lit_test_executor}" + "${LLVM_TOOLCHAIN_C_LIBRARY}_${variant}-install" + ) + if(CXX_LIBS) + add_libcxx_libcxxabi_libunwind( + "${directory}" + "${variant}" + "${target_triple}" + "${VARIANT_COMPILE_FLAGS}" + "${lit_test_executor}" + "${LLVM_TOOLCHAIN_C_LIBRARY}_${variant}-install" + "${${LLVM_TOOLCHAIN_C_LIBRARY}_specific_runtimes_options}" + ${VARIANT_ENABLE_EXCEPTIONS} + ${VARIANT_ENABLE_RTTI} + ) + endif() + if(VARIANT_COMPILE_FLAGS MATCHES "-march=armv8") + message("C++ runtime libraries tests disabled for ${variant}") + else() + add_custom_target(check-llvm-toolchain-runtimes-${variant}) + add_dependencies(check-llvm-toolchain-runtimes check-llvm-toolchain-runtimes-${variant}) + add_compiler_rt_tests("${variant}") + if(CXX_LIBS) + add_libcxx_libcxxabi_libunwind_tests("${variant}") + endif() + endif() + endif() + + 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") + + install( + DIRECTORY "${LLVM_BINARY_DIR}/${directory}/" + DESTINATION "${directory}" + COMPONENT llvm-toolchain-libs + ) + set(multilib_yaml_content "${multilib_yaml_content}" PARENT_SCOPE) +endfunction() + +function(add_library_variants_for_cpu target_arch) + set( + one_value_args + SUFFIX + COMPILE_FLAGS + MULTILIB_FLAGS + PICOLIBC_BUILD_TYPE + QEMU_MACHINE + QEMU_CPU + QEMU_PARAMS + BOOT_FLASH_ADDRESS + BOOT_FLASH_SIZE + FLASH_ADDRESS + FLASH_SIZE + RAM_ADDRESS + RAM_SIZE + STACK_SIZE + ) + cmake_parse_arguments(VARIANT "" "${one_value_args}" "" ${ARGN}) + + # Variant with no exceptions needs to come later in multilib.yaml to + # take priority. + foreach(enable_exceptions_and_rtti IN ITEMS ON OFF) + set(SUFFIXES) + if(VARIANT_SUFFIX) + list(APPEND SUFFIXES ${VARIANT_SUFFIX}) + endif() + if(enable_exceptions_and_rtti) + list(APPEND SUFFIXES "exn") + list(APPEND SUFFIXES "rtti") + endif() + list(JOIN SUFFIXES "_" COMBINED_SUFFIX) + + add_library_variant( + "${target_arch}" + SUFFIX "${COMBINED_SUFFIX}" + COMPILE_FLAGS "${VARIANT_COMPILE_FLAGS}" + MULTILIB_FLAGS "${VARIANT_MULTILIB_FLAGS}" + PICOLIBC_BUILD_TYPE "${VARIANT_PICOLIBC_BUILD_TYPE}" + QEMU_MACHINE "${VARIANT_QEMU_MACHINE}" + QEMU_CPU "${VARIANT_QEMU_CPU}" + QEMU_PARAMS "${VARIANT_QEMU_PARAMS}" + BOOT_FLASH_ADDRESS "${VARIANT_BOOT_FLASH_ADDRESS}" + BOOT_FLASH_SIZE "${VARIANT_BOOT_FLASH_SIZE}" + FLASH_ADDRESS "${VARIANT_FLASH_ADDRESS}" + FLASH_SIZE "${VARIANT_FLASH_SIZE}" + RAM_ADDRESS "${VARIANT_RAM_ADDRESS}" + RAM_SIZE "${VARIANT_RAM_SIZE}" + STACK_SIZE "${VARIANT_STACK_SIZE}" + ENABLE_EXCEPTIONS "${enable_exceptions_and_rtti}" + ENABLE_RTTI "${enable_exceptions_and_rtti}" + ) + endforeach() + + set(multilib_yaml_content "${multilib_yaml_content}" PARENT_SCOPE) +endfunction() + +set(multilib_yaml_content "") + +# Define which library variants to build and which flags to use. +# For most variants, the "flash" memory is placed in address range, where +# simulated boards have RAM. This is because code for some tests does not fit +# the real flash. +add_library_variants_for_cpu( + aarch64a + COMPILE_FLAGS "-march=armv8-a" + MULTILIB_FLAGS "--target=aarch64-unknown-none-elf" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "virt" + QEMU_CPU "cortex-a57" + BOOT_FLASH_ADDRESS 0x40000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x40001000 + FLASH_SIZE 0xfff000 + RAM_ADDRESS 0x41000000 + RAM_SIZE 0x1000000 + STACK_SIZE 8K +) +# For AArch32, clang uses different defaults for FPU selection than GCC, both +# when "+fp" or "+fp.dp" are used and when no FPU specifier is provided in +# "-march=". Using "-mfpu=" explicitly. +add_library_variants_for_cpu( + armv4t + COMPILE_FLAGS "-march=armv4t -mfpu=none" + MULTILIB_FLAGS "--target=armv4t-unknown-none-eabi -mfpu=none" + PICOLIBC_BUILD_TYPE "minsize" + QEMU_MACHINE "none" + QEMU_CPU "ti925t" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv5te + COMPILE_FLAGS "-march=armv5te -mfpu=none" + MULTILIB_FLAGS "--target=armv5e-unknown-none-eabi -mfpu=none" + PICOLIBC_BUILD_TYPE "minsize" + QEMU_MACHINE "none" + QEMU_CPU "arm926" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv6m + SUFFIX soft_nofp + COMPILE_FLAGS "-mfloat-abi=soft -march=armv6m -mfpu=none" + MULTILIB_FLAGS "--target=thumbv6m-unknown-none-eabi -mfpu=none" + PICOLIBC_BUILD_TYPE "minsize" + QEMU_MACHINE "mps2-an385" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x21000000 + FLASH_SIZE 0x600000 + RAM_ADDRESS 0x21600000 + RAM_SIZE 0xa00000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv7a + SUFFIX soft_nofp + COMPILE_FLAGS "-mfloat-abi=soft -march=armv7a -mfpu=none" + MULTILIB_FLAGS "--target=armv7-unknown-none-eabi -mfpu=none" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "cortex-a7" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv7a + SUFFIX hard_vfpv3_d16 + COMPILE_FLAGS "-mfloat-abi=hard -march=armv7a -mfpu=vfpv3-d16" + MULTILIB_FLAGS "--target=armv7-unknown-none-eabihf -mfpu=vfpv3-d16" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "cortex-a8" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv7a + SUFFIX soft_vfpv3_d16 + COMPILE_FLAGS "-mfloat-abi=softfp -march=armv7a -mfpu=vfpv3-d16" + MULTILIB_FLAGS "--target=armv7-unknown-none-eabi -mfpu=vfpv3-d16" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "cortex-a8" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv7r + SUFFIX soft_nofp + COMPILE_FLAGS "-mfloat-abi=soft -march=armv7r -mfpu=none" + MULTILIB_FLAGS "--target=armv7r-unknown-none-eabi -mfpu=none" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "cortex-r5f" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv7r + SUFFIX hard_vfpv3xd + COMPILE_FLAGS "-mfloat-abi=hard -march=armv7r -mfpu=vfpv3xd" + MULTILIB_FLAGS "--target=armv7r-unknown-none-eabihf -mfpu=vfpv3xd" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "cortex-r5f" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv7r + SUFFIX hard_vfpv3_d16 + COMPILE_FLAGS "-mfloat-abi=hard -march=armv7r -mfpu=vfpv3-d16" + MULTILIB_FLAGS "--target=armv7r-unknown-none-eabihf -mfpu=vfpv3-d16" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "cortex-r5f" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv7r + SUFFIX soft_vfpv3_d16 + COMPILE_FLAGS "-mfloat-abi=softfp -march=armv7r -mfpu=vfpv3-d16" + MULTILIB_FLAGS "--target=armv7r-unknown-none-eabi -mfpu=vfpv3-d16" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "cortex-r5f" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv7m + SUFFIX soft_fpv4_sp_d16 + COMPILE_FLAGS "-mfloat-abi=softfp -march=armv7m -mfpu=fpv4-sp-d16" + MULTILIB_FLAGS "--target=thumbv7m-unknown-none-eabi -mfpu=fpv4-sp-d16" + PICOLIBC_BUILD_TYPE "minsize" + QEMU_MACHINE "mps2-an386" + QEMU_CPU "cortex-m4" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x21000000 + FLASH_SIZE 0x600000 + RAM_ADDRESS 0x21600000 + RAM_SIZE 0xa00000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv7m + SUFFIX hard_fpv4_sp_d16 + COMPILE_FLAGS "-mfloat-abi=hard -march=armv7m -mfpu=fpv4-sp-d16" + MULTILIB_FLAGS "--target=thumbv7m-unknown-none-eabihf -mfpu=fpv4-sp-d16" + PICOLIBC_BUILD_TYPE "minsize" + QEMU_MACHINE "mps2-an386" + QEMU_CPU "cortex-m4" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x21000000 + FLASH_SIZE 0x600000 + RAM_ADDRESS 0x21600000 + RAM_SIZE 0xa00000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv7m + SUFFIX hard_fpv5_d16 + COMPILE_FLAGS "-mfloat-abi=hard -march=armv7m -mfpu=fpv5-d16" + MULTILIB_FLAGS "--target=thumbv7m-unknown-none-eabihf -mfpu=fpv5-d16" + PICOLIBC_BUILD_TYPE "minsize" + QEMU_MACHINE "mps2-an500" + QEMU_CPU "cortex-m7" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x60000000 + FLASH_SIZE 0x600000 + RAM_ADDRESS 0x60600000 + RAM_SIZE 0xa00000 + STACK_SIZE 4K +) +# When no -mfpu=none is specified, the compiler internally adds all other +# possible fpu settings before searching for matching variants. So for the +# no-fpu variant to win, it has to be in multilab.yaml after all other +# fpu variants. The order of variants in multilab.yaml depends on the order +# of the add_library_variant calls. So the add_library_variant that adds +# the soft_nofp for armv7m is placed after all other armv7m variants. +add_library_variants_for_cpu( + armv7m + SUFFIX soft_nofp + COMPILE_FLAGS "-mfloat-abi=soft -march=armv7m -mfpu=none" + MULTILIB_FLAGS "--target=thumbv7m-unknown-none-eabi -mfpu=none" + PICOLIBC_BUILD_TYPE "minsize" + QEMU_MACHINE "mps2-an386" + QEMU_CPU "cortex-m4" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x21000000 + FLASH_SIZE 0x600000 + RAM_ADDRESS 0x21600000 + RAM_SIZE 0xa00000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv8m.main + SUFFIX soft_nofp + COMPILE_FLAGS "-mfloat-abi=soft -march=armv8m.main -mfpu=none" + MULTILIB_FLAGS "--target=thumbv8m.main-unknown-none-eabi -mfpu=none" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "mps2-an505" + QEMU_CPU "cortex-m33" + BOOT_FLASH_ADDRESS 0x10000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x80000000 + FLASH_SIZE 0x600000 + RAM_ADDRESS 0x80600000 + RAM_SIZE 0xa00000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv8m.main + SUFFIX hard_fp + COMPILE_FLAGS "-mfloat-abi=hard -march=armv8m.main -mfpu=fpv5-sp-d16" + MULTILIB_FLAGS "--target=thumbv8m.main-unknown-none-eabihf -mfpu=fpv5-sp-d16" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "mps2-an505" + QEMU_CPU "cortex-m33" + BOOT_FLASH_ADDRESS 0x10000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x80000000 + FLASH_SIZE 0x600000 + RAM_ADDRESS 0x80600000 + RAM_SIZE 0xa00000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv8.1m.main + SUFFIX soft_nofp_nomve + COMPILE_FLAGS "-mfloat-abi=soft -march=armv8.1m.main+nomve -mfpu=none" + MULTILIB_FLAGS "--target=thumbv8.1m.main-unknown-none-eabi -mfpu=none" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "mps3-an547" + QEMU_CPU "cortex-m55" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 512K + FLASH_ADDRESS 0x60000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x61000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv8.1m.main + SUFFIX hard_fp_nomve + COMPILE_FLAGS "-mfloat-abi=hard -march=armv8.1m.main+nomve -mfpu=fp-armv8-fullfp16-sp-d16" + MULTILIB_FLAGS "--target=thumbv8.1m.main-unknown-none-eabihf -march=thumbv8.1m.main+fp16 -mfpu=fp-armv8-fullfp16-sp-d16" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "mps3-an547" + QEMU_CPU "cortex-m55" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 512K + FLASH_ADDRESS 0x60000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x61000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv8.1m.main + SUFFIX hard_fpdp_nomve + COMPILE_FLAGS "-mfloat-abi=hard -march=armv8.1m.main+nomve -mfpu=fp-armv8-fullfp16-d16" + MULTILIB_FLAGS "--target=thumbv8.1m.main-unknown-none-eabihf -march=thumbv8.1m.main+fp16 -mfpu=fp-armv8-fullfp16-d16" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "mps3-an547" + QEMU_CPU "cortex-m55" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 512K + FLASH_ADDRESS 0x60000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x61000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + armv8.1m.main + SUFFIX hard_nofp_mve + COMPILE_FLAGS "-mfloat-abi=hard -march=armv8.1m.main+mve -mfpu=none" + MULTILIB_FLAGS "--target=thumbv8.1m.main-unknown-none-eabihf -march=thumbv8.1m.main+mve -mfpu=none" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "mps3-an547" + QEMU_CPU "cortex-m55" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 512K + FLASH_ADDRESS 0x60000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x61000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +# RISC-V multilibs +## RV32I +add_library_variants_for_cpu( + rv32i_zicsr_zifencei_ilp32 + COMPILE_FLAGS "-march=rv32i_zicsr_zifencei -mabi=ilp32" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32i2p1_zicsr2p0_zifencei2p0 -mabi=ilp32" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32im_zicsr_zifencei_ilp32 + COMPILE_FLAGS "-march=rv32im_zicsr_zifencei -mabi=ilp32" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=ilp32" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32im_zicsr_zifencei_zba_zbb_zbc_zbs_ilp32 + COMPILE_FLAGS "-march=rv32im_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=ilp32" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 -mabi=ilp32" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32imac_zicsr_zifencei_ilp32 + COMPILE_FLAGS "-march=rv32imac_zicsr_zifencei -mabi=ilp32" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32i2p1_m2p0_a2p1_c2p0_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=ilp32" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32imafc_zicsr_zifencei_ilp32f + COMPILE_FLAGS "-march=rv32imafc_zicsr_zifencei -mabi=ilp32f" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32i2p1_m2p0_a2p1_f2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=ilp32f" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32imfc_zicsr_zifencei_ilp32f + COMPILE_FLAGS "-march=rv32imfc_zicsr_zifencei -mabi=ilp32f" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32i2p1_m2p0_f2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=ilp32f" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32imafd_zicsr_zifencei_ilp32d + COMPILE_FLAGS "-march=rv32imafd_zicsr_zifencei -mabi=ilp32d" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32i2p1_m2p0_a2p1_f2p2_d2p2_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=ilp32d" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32if_zicsr_zifencei_ilp32f + COMPILE_FLAGS "-march=rv32if_zicsr_zifencei -mabi=ilp32f" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32i2p1_f2p2_zicsr2p0_zifencei2p0 -mabi=ilp32f" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +## RV32E +add_library_variants_for_cpu( + rv32e_zicsr_zifencei_ilp32e + COMPILE_FLAGS "-march=rv32e_zicsr_zifencei -mabi=ilp32e" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32e2p0_zicsr2p0_zifencei2p0 -mabi=ilp32e" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32em_zicsr_zifencei_ilp32e + COMPILE_FLAGS "-march=rv32em_zicsr_zifencei -mabi=ilp32e" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32e2p0_m2p0_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=ilp32e" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32emc_zicsr_zifencei_ilp32e + COMPILE_FLAGS "-march=rv32emc_zicsr_zifencei -mabi=ilp32e" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32e2p0_m2p0_c2p0_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=ilp32e" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32emc_zicsr_zifencei_zba_zbb_zbc_zbs_ilp32e + COMPILE_FLAGS "-march=rv32emc_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=ilp32e" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32e2p0_m2p0_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 -mabi=ilp32e" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32emc_zicsr_ilp32e + COMPILE_FLAGS "-march=rv32emc_zicsr -mabi=ilp32e" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32e2p0_m2p0_c2p0_zicsr2p0_zmmul1p0 -mabi=ilp32e" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv32emc_zicsr_zba_zbb_zbc_zbs_ilp32e + COMPILE_FLAGS "-march=rv32emc_zicsr_zba_zbb_zbc_zbs -mabi=ilp32e" + MULTILIB_FLAGS "--target=riscv32-unknown-none-elf -march=rv32e2p0_m2p0_c2p0_zicsr2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 -mabi=ilp32e" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv32" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +## RV64I +add_library_variants_for_cpu( + rv64i_zicsr_zifencei_lp64 + COMPILE_FLAGS "-march=rv64i_zicsr_zifencei -mabi=lp64 -mcmodel=medany" + MULTILIB_FLAGS "--target=riscv64-unknown-none-elf -march=rv64i2p1_zicsr2p0_zifencei2p0 -mabi=lp64" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv64" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv64im_zicsr_zifencei_lp64 + COMPILE_FLAGS "-march=rv64im_zicsr_zifencei -mabi=lp64 -mcmodel=medany" + MULTILIB_FLAGS "--target=riscv64-unknown-none-elf -march=rv64i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=lp64" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv64" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv64im_zicsr_zifencei_zba_zbb_zbc_zbs_lp64 + COMPILE_FLAGS "-march=rv64im_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=lp64 -mcmodel=medany" + MULTILIB_FLAGS "--target=riscv64-unknown-none-elf -march=rv64i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 -mabi=lp64" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv64" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv64imac_zicsr_zifencei_lp64 + COMPILE_FLAGS "-march=rv64imac_zicsr_zifencei -mabi=lp64 -mcmodel=medany" + MULTILIB_FLAGS "--target=riscv64-unknown-none-elf -march=rv64i2p1_m2p0_a2p1_c2p0_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=lp64" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv64" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv64imac_zicsr_zifencei_zba_zbb_zbc_zbs_lp64 + COMPILE_FLAGS "-march=rv64imac_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=lp64 -mcmodel=medany" + MULTILIB_FLAGS "--target=riscv64-unknown-none-elf -march=rv64i2p1_m2p0_a2p1_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 -mabi=lp64" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv64" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv64imafdc_zicsr_zifencei_lp64d + COMPILE_FLAGS "-march=rv64imafdc_zicsr_zifencei -mabi=lp64d -mcmodel=medany" + MULTILIB_FLAGS "--target=riscv64-unknown-none-elf -march=rv64i2p1_m2p0_a2p1_f2p2_d2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=lp64d" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv64" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv64imafd_zicsr_zifencei_lp64d + COMPILE_FLAGS "-march=rv64imafd_zicsr_zifencei -mabi=lp64d -mcmodel=medany" + MULTILIB_FLAGS "--target=riscv64-unknown-none-elf -march=rv64i2p1_m2p0_a2p1_f2p2_d2p2_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=lp64d" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv64" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv64imfc_zicsr_zifencei_lp64f + COMPILE_FLAGS "-march=rv64imfc_zicsr_zifencei -mabi=lp64f -mcmodel=medany" + MULTILIB_FLAGS "--target=riscv64-unknown-none-elf -march=rv64i2p1_m2p0_f2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0 -mabi=lp64f" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv64" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) +add_library_variants_for_cpu( + rv64imfc_zicsr_zifencei_zba_zbb_zbc_zbs_lp64f + COMPILE_FLAGS "-march=rv64imfc_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=lp64f -mcmodel=medany" + MULTILIB_FLAGS "--target=riscv64-unknown-none-elf -march=rv64i2p1_m2p0_f2p2_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 -mabi=lp64f" + PICOLIBC_BUILD_TYPE "release" + QEMU_MACHINE "none" + QEMU_CPU "rv64" + QEMU_PARAMS "-m 1G" + BOOT_FLASH_ADDRESS 0x00000000 + BOOT_FLASH_SIZE 0x1000 + FLASH_ADDRESS 0x20000000 + FLASH_SIZE 0x1000000 + RAM_ADDRESS 0x21000000 + RAM_SIZE 0x1000000 + STACK_SIZE 4K +) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/multilib.yaml.in + ${CMAKE_CURRENT_BINARY_DIR}/multilib-without-fpus.yaml + @ONLY +) + +set(multilib_yaml_depends + "${CMAKE_CURRENT_SOURCE_DIR}/multilib-fpus.py" + "${CMAKE_CURRENT_BINARY_DIR}/multilib-without-fpus.yaml" +) +if(LIBS_DEPEND_ON_TOOLS) + list(APPEND multilib_yaml_depends clang) +endif() + +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/llvm/${TARGET_LIBRARIES_DIR}${library_subdir}/multilib.yaml + COMMAND ${CMAKE_COMMAND} -E copy + ${CMAKE_CURRENT_BINARY_DIR}/multilib-without-fpus.yaml + ${CMAKE_CURRENT_BINARY_DIR}/llvm/${TARGET_LIBRARIES_DIR}${library_subdir}/multilib.yaml + COMMAND ${Python3_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/multilib-fpus.py" + "--clang=${LLVM_BINARY_DIR}/bin/clang${CMAKE_EXECUTABLE_SUFFIX}" + "--llvm-source=${LLVMPROJECT_SOURCE_DIR}" + >> "${CMAKE_CURRENT_BINARY_DIR}/llvm/${TARGET_LIBRARIES_DIR}${library_subdir}/multilib.yaml" + DEPENDS ${multilib_yaml_depends} +) +add_custom_target(multilib_yaml ALL DEPENDS + ${CMAKE_CURRENT_BINARY_DIR}/llvm/${TARGET_LIBRARIES_DIR}${library_subdir}/multilib.yaml) +add_dependencies(llvm-toolchain-runtimes multilib_yaml) + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/llvm/${TARGET_LIBRARIES_DIR}${library_subdir}/multilib.yaml + DESTINATION ${TARGET_LIBRARIES_DIR}${library_subdir} + COMPONENT llvm-toolchain-libs +) + +if(LLVM_TOOLCHAIN_CROSS_BUILD_MINGW) + set(mingw_runtime_dlls + "\n - MinGW runtime DLLs: third-party-licenses/COPYING.MinGW-w64-runtime.txt, third-party-licenses/COPYING3.GCC, third-party-licenses/COPYING.RUNTIME" + ) +endif() +configure_file(cmake/THIRD-PARTY-LICENSES.txt.in THIRD-PARTY-LICENSES.txt) + +if(NOT LLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL) + set(third_party_license_summary_install_dir .) + set(third_party_license_files_install_dir third-party-licenses) +else() + # If we're building an overlay archive, put all the license files + # one level down in third-party-licenses/, so that + # COPYING.NEWLIB doesn't collide with the file of the same name + # from picolibc, and the LLVM license files are also duplicated + # (in case the overlay archive is used with a non-matching version + # of the main toolchain). + set(third_party_license_summary_install_dir third-party-licenses/${LLVM_TOOLCHAIN_C_LIBRARY}) + set(third_party_license_files_install_dir third-party-licenses/${LLVM_TOOLCHAIN_C_LIBRARY}) +endif() + +install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/THIRD-PARTY-LICENSES.txt + DESTINATION ${third_party_license_summary_install_dir} + COMPONENT llvm-toolchain-third-party-licenses +) + +set(third_party_license_files + ${LLVMPROJECT_SOURCE_DIR}/llvm/LICENSE.TXT LLVM-LICENSE.txt + ${LLVMPROJECT_SOURCE_DIR}/clang/LICENSE.TXT CLANG-LICENSE.txt + ${LLVMPROJECT_SOURCE_DIR}/lld/LICENSE.TXT LLD-LICENSE.txt + ${LLVMPROJECT_SOURCE_DIR}/compiler-rt/LICENSE.TXT COMPILER-RT-LICENSE.txt + ${LLVMPROJECT_SOURCE_DIR}/libcxx/LICENSE.TXT LIBCXX-LICENSE.txt + ${LLVMPROJECT_SOURCE_DIR}/libcxxabi/LICENSE.TXT LIBCXXABI-LICENSE.txt + ${LLVMPROJECT_SOURCE_DIR}/libunwind/LICENSE.TXT LIBUNWIND-LICENSE.txt +) +if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL picolibc) + list(APPEND third_party_license_files + ${PICOLIBC_SOURCE_DIR}/COPYING.NEWLIB COPYING.NEWLIB + ${PICOLIBC_SOURCE_DIR}/COPYING.picolibc COPYING.picolibc + ) +endif() +if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL newlib) + list(APPEND third_party_license_files + ${NEWLIB_SOURCE_DIR}/COPYING.NEWLIB COPYING.NEWLIB + ${NEWLIB_SOURCE_DIR}/COPYING.LIBGLOSS COPYING.LIBGLOSS + ) +endif() +if(LLVM_TOOLCHAIN_C_LIBRARY STREQUAL llvmlibc) + list(APPEND third_party_license_files + ${LLVMPROJECT_SOURCE_DIR}/libc/LICENSE.TXT LIBC-LICENSE.TXT + ) +endif() + +while(third_party_license_files) + list(POP_FRONT third_party_license_files source_file destination_name) + install( + FILES ${source_file} + DESTINATION ${third_party_license_files_install_dir} + COMPONENT llvm-toolchain-third-party-licenses + RENAME ${destination_name} + ) +endwhile() + +# LLVM-style install +# To use it: +# ninja install-llvm-toolchain +add_custom_target( + install-llvm-toolchain +) +set(LLVM_TOOLCHAIN_DISTRIBUTION_COMPONENTS_ALL ${LLVM_TOOLCHAIN_DISTRIBUTION_COMPONENTS}) +if(LLVM_TOOLCHAIN_CROSS_BUILD_MINGW) + list(APPEND LLVM_TOOLCHAIN_DISTRIBUTION_COMPONENTS_ALL llvm-toolchain-mingw) +endif() +foreach(component ${LLVM_TOOLCHAIN_DISTRIBUTION_COMPONENTS_ALL}) + add_custom_target( + install-${component} + COMMAND + "${CMAKE_COMMAND}" + --install ${CMAKE_BINARY_DIR} + --component ${component} + USES_TERMINAL + ) + add_dependencies( + install-${component} + llvm-toolchain + ) + add_dependencies( + install-llvm-toolchain + install-${component} + ) +endforeach() +if(LLVM_TOOLCHAIN_CROSS_BUILD_MINGW) + # No further action needed to install because the LLVM distributables + # are copied as part of the llvm-toolchain-mingw component. +else() + # Also run install-distribution to install the LLVM + # binaries. + add_dependencies( + install-llvm-toolchain + install-distribution + ) +endif() + + +# package-llvm-toolchain - target to create package +if(LLVM_TOOLCHAIN_CROSS_BUILD_MINGW OR WIN32) + set(cpack_generator ZIP) + set(package_filename_extension ".zip") +elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" + AND NOT LLVM_TOOLCHAIN_LIBRARY_OVERLAY_INSTALL) + set(cpack_generator DragNDrop) + set(package_filename_extension ".dmg") +else() + set(cpack_generator TXZ) + set(package_filename_extension ".tar.xz") +endif() +set(package_filepath ${CMAKE_BINARY_DIR}/${PACKAGE_FILE_NAME}${package_filename_extension}) +set(unpack_directory ${CMAKE_CURRENT_BINARY_DIR}/unpack/${PACKAGE_FILE_NAME}) +add_custom_command( + OUTPUT ${package_filepath} + COMMAND "${CMAKE_COMMAND}" -E rm -f ${package_filepath} + COMMAND cpack -G ${cpack_generator} + DEPENDS llvm-toolchain + USES_TERMINAL + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) +add_custom_target( + package-llvm-toolchain + DEPENDS ${package_filepath} +) +add_custom_target( + clear-unpack-directory + COMMAND "${CMAKE_COMMAND}" -E rm -rf unpack + COMMAND "${CMAKE_COMMAND}" -E make_directory unpack +) +add_custom_target( + unpack-llvm-toolchain + COMMAND "${CMAKE_COMMAND}" -E tar x ${package_filepath} + DEPENDS ${package_filepath} + USES_TERMINAL + WORKING_DIRECTORY unpack +) +add_dependencies( + unpack-llvm-toolchain + clear-unpack-directory +) + + +add_custom_target(check-llvm-toolchain) +add_dependencies(check-llvm-toolchain check-${LLVM_TOOLCHAIN_C_LIBRARY}) +add_dependencies(check-llvm-toolchain check-compiler-rt) +add_subdirectory(test) +add_dependencies(check-llvm-toolchain check-llvm-toolchain-lit) +add_subdirectory(packagetest) + +if(LLVM_TOOLCHAIN_CROSS_BUILD_MINGW) + find_program(MINGW_C_EXECUTABLE x86_64-w64-mingw32-gcc REQUIRED) + find_program(MINGW_CXX_EXECUTABLE x86_64-w64-mingw32-g++ REQUIRED) + cmake_path(SET MINGW_SYSROOT NORMALIZE "${MINGW_C_EXECUTABLE}/../../x86_64-w64-mingw32") + + string(REPLACE ";" "," LLVM_ENABLE_PROJECTS_comma "${LLVM_ENABLE_PROJECTS}") + string(REPLACE ";" "," LLVM_DISTRIBUTION_COMPONENTS_comma "${LLVM_DISTRIBUTION_COMPONENTS}") + string(REPLACE ";" "," LLVM_TARGETS_TO_BUILD_comma "${LLVM_TARGETS_TO_BUILD}") + ExternalProject_Add( + mingw-llvm + SOURCE_DIR ${LLVMPROJECT_SOURCE_DIR}/llvm + PREFIX mingw-llvm + INSTALL_DIR mingw-llvm/install + DEPENDS clang-tblgen llvm-config llvm-tblgen + CMAKE_ARGS + -DBUG_REPORT_URL=${BUG_REPORT_URL} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_CROSSCOMPILING=ON + -DCMAKE_C_COMPILER=${MINGW_C_EXECUTABLE} + -DCMAKE_CXX_COMPILER=${MINGW_CXX_EXECUTABLE} + -DCMAKE_FIND_ROOT_PATH=${MINGW_SYSROOT} + -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER + -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY + -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY + -DCMAKE_INSTALL_PREFIX= + -DCMAKE_SYSTEM_NAME=Windows + -DCLANG_TABLEGEN=${LLVM_BINARY_DIR}/bin/clang-tblgen${CMAKE_EXECUTABLE_SUFFIX} + -DLLVM_CMAKE_DIR=${LLVM_BINARY_DIR}/lib/cmake/llvm + -DLLVM_DISTRIBUTION_COMPONENTS=${LLVM_DISTRIBUTION_COMPONENTS_comma} + -DLLVM_ENABLE_PROJECTS=${LLVM_ENABLE_PROJECTS_comma} + -DLLVM_TABLEGEN=${LLVM_BINARY_DIR}/bin/llvm-tblgen${CMAKE_EXECUTABLE_SUFFIX} + -DLLVM_TARGETS_TO_BUILD=${LLVM_TARGETS_TO_BUILD_comma} + -DLLVM_DEFAULT_TARGET_TRIPLE=${LLVM_DEFAULT_TARGET_TRIPLE} + -DLLVM_APPEND_VC_REV=${LLVM_APPEND_VC_REV} + BUILD_COMMAND "" # Let the install command build whatever it needs + INSTALL_COMMAND "${CMAKE_COMMAND}" --build --target install-distribution + USES_TERMINAL_CONFIGURE TRUE + USES_TERMINAL_BUILD TRUE + USES_TERMINAL_INSTALL TRUE + LIST_SEPARATOR , + # Always run the build command so that incremental builds are correct. + BUILD_ALWAYS TRUE + CONFIGURE_HANDLED_BY_BUILD TRUE + ) + ExternalProject_Get_Property(mingw-llvm INSTALL_DIR) + # Handle symlinks such as clang++. + # CPack supports putting symlinks in zip files but to Windows they + # just look like a file containing text like "clang". + # Convert the required symlinks to regular files and remove the + # remaining ones. + add_custom_command( + TARGET mingw-llvm + POST_BUILD + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/cmake/handle-windows-symlinks.sh + WORKING_DIRECTORY ${INSTALL_DIR} + ) + + install( + DIRECTORY ${INSTALL_DIR}/ + DESTINATION . + COMPONENT llvm-toolchain-mingw + ) + + # Copy MinGW licenses + install( + DIRECTORY mingw-licenses/ + DESTINATION third-party-licenses + COMPONENT llvm-toolchain-third-party-licenses + ) + + # Copy MinGW runtime DLLs + foreach(mingw_runtime_dll + libwinpthread-1.dll # POSIX thread API implementation + libgcc_s_seh-1.dll # GCC runtime + libstdc++-6.dll # C++ Standard Library + ) + execute_process( + COMMAND ${MINGW_C_EXECUTABLE} -print-file-name=${mingw_runtime_dll} + OUTPUT_VARIABLE mingw_runtime_dll + OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND_ERROR_IS_FATAL ANY + ) + install( + FILES ${mingw_runtime_dll} + TYPE BIN + COMPONENT llvm-toolchain-mingw + ) + endforeach() + + add_dependencies( + llvm-toolchain + mingw-llvm + ) +endif() + +add_custom_target(check-all-llvm-toolchain) + +add_dependencies( + check-all-llvm-toolchain + check-all + check-llvm-toolchain + check-llvm-toolchain-runtimes +) diff --git a/scripts/llvm/Omax.cfg b/scripts/llvm/Omax.cfg new file mode 100644 index 00000000..c100f0f1 --- /dev/null +++ b/scripts/llvm/Omax.cfg @@ -0,0 +1 @@ +--sysroot /../lib/clang-runtimes/newlib diff --git a/scripts/llvm/OmaxLTO.cfg b/scripts/llvm/OmaxLTO.cfg new file mode 100644 index 00000000..5c029b91 --- /dev/null +++ b/scripts/llvm/OmaxLTO.cfg @@ -0,0 +1,3 @@ +-flto=full \ +-fvirtual-function-elimination \ +-fwhole-program-vtables diff --git a/scripts/llvm/cmake/THIRD-PARTY-LICENSES.txt.in b/scripts/llvm/cmake/THIRD-PARTY-LICENSES.txt.in new file mode 100644 index 00000000..ddfb89f4 --- /dev/null +++ b/scripts/llvm/cmake/THIRD-PARTY-LICENSES.txt.in @@ -0,0 +1,12 @@ +This product embeds and uses the following pieces of software which have +additional or alternate licenses: + - LLVM: third-party-licenses/LLVM-LICENSE.txt + - Clang: third-party-licenses/CLANG-LICENSE.txt + - lld: third-party-licenses/LLD-LICENSE.txt + - compiler-rt: third-party-licenses/COMPILER-RT-LICENSE.txt + - libc++: third-party-licenses/LIBCXX-LICENSE.txt + - libc++abi: third-party-licenses/LIBCXXABI-LICENSE.txt + - libunwind: third-party-licenses/LIBUNWIND-LICENSE.txt + - Picolibc: third-party-licenses/COPYING.NEWLIB, third-party-licenses/COPYING.picolibc${mingw_runtime_dlls} + +Picolibc licenses refer to its source files. Sources are identified in VERSION.txt. diff --git a/scripts/llvm/cmake/handle-windows-symlinks.sh b/scripts/llvm/cmake/handle-windows-symlinks.sh new file mode 100755 index 00000000..82ed3290 --- /dev/null +++ b/scripts/llvm/cmake/handle-windows-symlinks.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Exit immediately if a command exits with a non-zero status. +set -e + +# Handle symlinks such as clang++ when cross-building to Windows. +# CPack supports putting symlinks in zip files but to Windows they +# just look like a file containing text like "clang". + +# 1. Convert required symlinks to regular files. +for name in \ + clang++ \ + clang-cpp \ + ld.lld \ + llvm-ranlib \ + llvm-readelf \ + llvm-strip +do + ln -f $(realpath -m "bin/${name}.exe") bin/${name}.exe +done + +# 2. Remove remaining symlinks +find -type l -exec rm {} + diff --git a/scripts/llvm/cmake/meson-cross-build.txt.in b/scripts/llvm/cmake/meson-cross-build.txt.in new file mode 100644 index 00000000..c619118a --- /dev/null +++ b/scripts/llvm/cmake/meson-cross-build.txt.in @@ -0,0 +1,31 @@ +[binaries] +c = [@meson_c_args@, '-nostdlib'] +ar = '@LLVM_BINARY_DIR@/bin/llvm-ar@CMAKE_EXECUTABLE_SUFFIX@' +strip = '@LLVM_BINARY_DIR@/bin/llvm-strip@CMAKE_EXECUTABLE_SUFFIX@' +# only needed to run tests +# setting stdin to /dev/null prevents qemu from fiddling with the echo bit of +# the parent terminal +exe_wrapper = [ + 'sh', + '-c', + 'test -z "$PICOLIBC_TEST" || @test_executor_bin@ "$@" < /dev/null', + '@test_executor_bin@', + @test_executor_params@] + +[host_machine] +system = 'none' +cpu_family = '@cpu_family@' +cpu = '@cpu_family@' +endian = 'little' + +[properties] +skip_sanity_check = true +libgcc ='-lclang_rt.builtins' +separate_boot_flash = true +default_boot_flash_addr = '@default_boot_flash_addr@' +default_boot_flash_size = '@default_boot_flash_size@' +default_flash_addr = '@default_flash_addr@' +default_flash_size = '@default_flash_size@' +default_ram_addr = '@default_ram_addr@' +default_ram_size = '@default_ram_size@' +default_stack_size = '@default_stack_size@' diff --git a/scripts/llvm/cmake/multilib.yaml.in b/scripts/llvm/cmake/multilib.yaml.in new file mode 100644 index 00000000..197a83f8 --- /dev/null +++ b/scripts/llvm/cmake/multilib.yaml.in @@ -0,0 +1,277 @@ +# +# Copyright (c) 2023, Arm Limited and affiliates. +# Copyright (c) 2024 Stephanos Ioannidis +# +# 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. +# + +# If you're reading this file under the name 'multilib.yaml.in' in the +# Zephyr SDK source tree, then it's not valid YAML in its own right: it's a +# template that CMakeLists.txt will expand into a real 'multilib.yaml' +# containing a list of library variants and the flags that will select them. +# +# If you're reading it under the name 'multilib.yaml' in the build or +# install directory, then that substitution has been done. +# +# Comments in this file mostly make more sense from the +# multilib.yaml.in point of view. + +MultilibVersion: '1.0' + +# Make an exclusive group for library variants, to make sure we don't +# accidentally include two or more variants at once. +# +# Even if they all match the command-line options, putting two sets of +# include directories on the include path can cause build failure, +# because of the #include_next used in the libc++ headers. The first +# libc++ stdio.h (for example) will #include_next , which +# will find the second libc++ version. That won't do anything at all, +# because it has the same include-guard macro as the first, and so +# nothing will ever include the _libc_ stdio.h, which was what the +# #include_next was really looking for. +Groups: +- Name: stdlibs + Type: Exclusive + +# The list of library variants is substituted in by CMakeLists.txt, so +# that it can respect the LLVM_TOOLCHAIN_LIBRARY_VARIANTS setting and +# only include the set of libraries actually included in this build. + +Variants: +@multilib_yaml_content@ + +Mappings: + +# Map higher architecture versions to subsets of them, so that a +# compatible library can be found even for architectures we don't have +# specific variants for. + +# v8-M Baseline is a superset of v6-M +- Match: --target=thumbv8m\.base-unknown-none-eabi + Flags: + - --target=thumbv6m-unknown-none-eabi + +# v8.2-M Mainline is a superset of v8.1-M Mainline, in both hard and +# soft float variants. +# +# Also, v8.1-M Mainline is also a superset of v8-M Mainline, which in +# turn is a superset of v7E-M, and then of plain v7-M. We have +# libraries for all those architecture versions, but not for every +# combination of them with FPUs, so in some cases it might be +# necessary to fall back to a lower architecture in order to provide +# the needed FPU support. +- Match: --target=thumbv8\.[2-9]m\.main-unknown-none-eabi + Flags: + - --target=thumbv8.1m.main-unknown-none-eabi + - --target=thumbv8m.main-unknown-none-eabi + - --target=thumbv7em-unknown-none-eabi + - --target=thumbv7m-unknown-none-eabi +- Match: --target=thumbv8\.[2-9]m\.main-unknown-none-eabihf + Flags: + - --target=thumbv8.1m.main-unknown-none-eabihf + - --target=thumbv8m.main-unknown-none-eabihf + - --target=thumbv7em-unknown-none-eabihf + - --target=thumbv7m-unknown-none-eabihf +- Match: --target=thumbv8\.1m\.main-unknown-none-eabi + Flags: + - --target=thumbv8m.main-unknown-none-eabi + - --target=thumbv7em-unknown-none-eabi + - --target=thumbv7m-unknown-none-eabi +- Match: --target=thumbv8\.1m\.main-unknown-none-eabihf + Flags: + - --target=thumbv8m.main-unknown-none-eabihf + - --target=thumbv7em-unknown-none-eabihf + - --target=thumbv7m-unknown-none-eabihf +- Match: --target=thumbv8m\.main-unknown-none-eabi + Flags: + - --target=thumbv7em-unknown-none-eabi + - --target=thumbv7m-unknown-none-eabi +- Match: --target=thumbv8m\.main-unknown-none-eabihf + Flags: + - --target=thumbv7em-unknown-none-eabihf + - --target=thumbv7m-unknown-none-eabihf +- Match: --target=thumbv7em-unknown-none-eabi + Flags: + - --target=thumbv7m-unknown-none-eabi +- Match: --target=thumbv7em-unknown-none-eabihf + Flags: + - --target=thumbv7m-unknown-none-eabihf + +# v7-A and v7-R include the ISA in the triple, but that doesn't matter for +# library selection, so canonicalise Thumb triples to ARM ones. +- Match: --target=thumbv7r-unknown-none-eabi + Flags: + - --target=armv7r-unknown-none-eabi +- Match: --target=thumbv7r-unknown-none-eabihf + Flags: + - --target=armv7r-unknown-none-eabihf +- Match: --target=thumbv7-unknown-none-eabi + Flags: + - --target=armv7-unknown-none-eabi +- Match: --target=thumbv7-unknown-none-eabihf + Flags: + - --target=armv7-unknown-none-eabihf +- Match: --target=thumbv4t-unknown-none-eabi + Flags: + - --target=armv4t-unknown-none-eabi +- Match: --target=thumbv4t-unknown-none-eabihf + Flags: + - --target=armv4t-unknown-none-eabihf +- Match: --target=thumbv5e-unknown-none-eabi + Flags: + - --target=armv5e-unknown-none-eabi +- Match: --target=thumbv5e-unknown-none-eabihf + Flags: + - --target=armv5e-unknown-none-eabihf + +# armv7ve is a GCC name for v7-A with the virtualisation extension, for library +# selection we treat it the same as v7-A. +- Match: --target=(arm|thumb)v7ve-unknown-none-eabi + Flags: + - --target=armv7-unknown-none-eabi +- Match: --target=(arm|thumb)v7ve-unknown-none-eabihf + Flags: + - --target=armv7-unknown-none-eabihf + +# Higher versions of the architecture such as v8-A and v9-A are a superset of +# v7-A. +- Match: --target=(arm|thumb)v(8|8\.[1-9]|9|9\.[1-9])a-unknown-none-eabi + Flags: + - --target=armv7-unknown-none-eabi +- Match: --target=(arm|thumb)v(8|8\.[1-9]|9|9\.[1-9])a-unknown-none-eabihf + Flags: + - --target=armv7-unknown-none-eabihf +- Match: --target=(arm|thumb)v(8|8\.[1-9]|9|9\.[1-9])r-unknown-none-eabi + Flags: + - --target=armv7r-unknown-none-eabi +- Match: --target=(arm|thumb)v(8|8\.[1-9]|9|9\.[1-9])r-unknown-none-eabihf + Flags: + - --target=armv7r-unknown-none-eabihf + +# -march extensions +- Match: -march=thumbv8\.[1-9]m\.main(\+[^\+]+)*\+fp16(\+[^\+]+)* + Flags: + - -march=thumbv8.1m.main+fp16 +- Match: -march=thumbv8\.[1-9]m\.main(\+[^\+]+)*\+mve(\+[^\+]+)* + Flags: + - -march=thumbv8.1m.main+mve +- Match: -march=thumbv8\.[1-9]m\.main(\+[^\+]+)*\+mve\.fp(\+[^\+]+)* + Flags: + - -march=thumbv8.1m.main+mve.fp +- Match: -march=thumbv8\.[1-9]m\.main(\+[^\+]+)*\+lob(\+[^\+]+)* + Flags: + - -march=thumbv8.1m.main+lob + +# RV32I alternate mappings +## march.rv32i_zicsr_zifencei/mabi.ilp32=march.rv32ia_zicsr_zifencei/mabi.ilp32 +- Match: -march=rv32i([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_zicsr2p0_zifencei2p0 +## march.rv32i_zicsr_zifencei/mabi.ilp32=march.rv32iac_zicsr_zifencei/mabi.ilp32 +- Match: -march=rv32i([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_zicsr2p0_zifencei2p0 +## march.rv32i_zicsr_zifencei/mabi.ilp32=march.rv32iafc_zicsr_zifencei/mabi.ilp32 +- Match: -march=rv32i([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_f([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_zicsr2p0_zifencei2p0 +## march.rv32i_zicsr_zifencei/mabi.ilp32=march.rv32ic_zicsr_zifencei/mabi.ilp32 +- Match: -march=rv32i([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_zicsr2p0_zifencei2p0 +## march.rv32im_zicsr_zifencei/mabi.ilp32=march.rv32ima_zicsr_zifencei/mabi.ilp32 +- Match: -march=rv32i([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0 +## march.rv32im_zicsr_zifencei/mabi.ilp32=march.rv32imc_zicsr_zifencei/mabi.ilp32 +- Match: -march=rv32i([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0 +## march.rv32im_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.ilp32=march.rv32ima_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.ilp32 +- Match: -march=rv32i([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+)_zba([0-9]+p[0-9]+)_zbb([0-9]+p[0-9]+)_zbc([0-9]+p[0-9]+)_zbs([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 +## march.rv32im_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.ilp32=march.rv32imac_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.ilp32 +- Match: -march=rv32i([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+)_zba([0-9]+p[0-9]+)_zbb([0-9]+p[0-9]+)_zbc([0-9]+p[0-9]+)_zbs([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 +## march.rv32im_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.ilp32=march.rv32imc_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.ilp32 +- Match: -march=rv32i([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+)_zba([0-9]+p[0-9]+)_zbb([0-9]+p[0-9]+)_zbc([0-9]+p[0-9]+)_zbs([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 +## march.rv32imafd_zicsr_zifencei/mabi.ilp32d=march.rv32imafdc_zicsr_zifencei/mabi.ilp32d +- Match: -march=rv32i([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_f([0-9]+p[0-9]+)_d([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_m2p0_a2p1_f2p2_d2p2_zicsr2p0_zifencei2p0_zmmul1p0 +## march.rv32if_zicsr_zifencei/mabi.ilp32f=march.rv32iafc_zicsr_zifencei/mabi.ilp32f +- Match: -march=rv32i([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_f([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv32i2p1_f2p2_zicsr2p0_zifencei2p0 + +# RV32E alternate mappings +## march.rv32e_zicsr_zifencei/mabi.ilp32e=march.rv32ea_zicsr_zifencei/mabi.ilp32e +- Match: -march=rv32e([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv32e2p0_zicsr2p0_zifencei2p0 +## march.rv32e_zicsr_zifencei/mabi.ilp32e=march.rv32eac_zicsr_zifencei/mabi.ilp32e +- Match: -march=rv32e([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv32e2p0_zicsr2p0_zifencei2p0 +## march.rv32e_zicsr_zifencei/mabi.ilp32e=march.rv32ec_zicsr_zifencei/mabi.ilp32e +- Match: -march=rv32e([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv32e2p0_zicsr2p0_zifencei2p0 +## march.rv32em_zicsr_zifencei/mabi.ilp32e=march.rv32ema_zicsr_zifencei/mabi.ilp32e +- Match: -march=rv32e([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+) + Flags: + - -march=rv32e2p0_m2p0_zicsr2p0_zifencei2p0_zmmul1p0 +## march.rv32emc_zicsr_zifencei/mabi.ilp32e=march.rv32emac_zicsr_zifencei/mabi.ilp32e +- Match: -march=rv32e([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+) + Flags: + - -march=rv32e2p0_m2p0_c2p0_zicsr2p0_zifencei2p0_zmmul1p0 +## march.rv32emc_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.ilp32e=march.rv32emac_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.ilp32e +- Match: -march=rv32e([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+)_zba([0-9]+p[0-9]+)_zbb([0-9]+p[0-9]+)_zbc([0-9]+p[0-9]+)_zbs([0-9]+p[0-9]+) + Flags: + - -march=rv32e2p0_m2p0_c2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 + +# RV64I alternate mappings +## march.rv64i_zicsr_zifencei/mabi.lp64/mcmodel.medany=march.rv64ia_zicsr_zifencei/mabi.lp64/mcmodel.medany +- Match: -march=rv64i([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv64i2p1_zicsr2p0_zifencei2p0 +## march.rv64i_zicsr_zifencei/mabi.lp64/mcmodel.medany=march.rv64iac_zicsr_zifencei/mabi.lp64/mcmodel.medany +- Match: -march=rv64i([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv64i2p1_zicsr2p0_zifencei2p0 +## march.rv64i_zicsr_zifencei/mabi.lp64/mcmodel.medany=march.rv64ic_zicsr_zifencei/mabi.lp64/mcmodel.medany +- Match: -march=rv64i([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+) + Flags: + - -march=rv64i2p1_zicsr2p0_zifencei2p0 +## march.rv64im_zicsr_zifencei/mabi.lp64/mcmodel.medany=march.rv64ima_zicsr_zifencei/mabi.lp64/mcmodel.medany +- Match: -march=rv64i([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+) + Flags: + - -march=rv64i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0 +## march.rv64im_zicsr_zifencei/mabi.lp64/mcmodel.medany=march.rv64imc_zicsr_zifencei/mabi.lp64/mcmodel.medany +- Match: -march=rv64i([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+) + Flags: + - -march=rv64i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0 +## march.rv64im_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.lp64/mcmodel.medany=march.rv64ima_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.lp64/mcmodel.medany +- Match: -march=rv64i([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_a([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+)_zba([0-9]+p[0-9]+)_zbb([0-9]+p[0-9]+)_zbc([0-9]+p[0-9]+)_zbs([0-9]+p[0-9]+) + Flags: + - -march=rv64i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 +## march.rv64im_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.lp64/mcmodel.medany=march.rv64imc_zicsr_zifencei_zba_zbb_zbc_zbs/mabi.lp64/mcmodel.medany +- Match: -march=rv64i([0-9]+p[0-9]+)_m([0-9]+p[0-9]+)_c([0-9]+p[0-9]+)_zicsr([0-9]+p[0-9]+)_zifencei([0-9]+p[0-9]+)_zmmul([0-9]+p[0-9]+)_zba([0-9]+p[0-9]+)_zbb([0-9]+p[0-9]+)_zbc([0-9]+p[0-9]+)_zbs([0-9]+p[0-9]+) + Flags: + - -march=rv64i2p1_m2p0_zicsr2p0_zifencei2p0_zmmul1p0_zba1p0_zbb1p0_zbc1p0_zbs1p0 diff --git a/scripts/llvm/cmake/to_meson_list.cmake b/scripts/llvm/cmake/to_meson_list.cmake new file mode 100644 index 00000000..8a42db85 --- /dev/null +++ b/scripts/llvm/cmake/to_meson_list.cmake @@ -0,0 +1,9 @@ +# Converts a cmake list to a string, which can be interpreted as list content in +# meson configuration file. +# The delimiting brackets are not included. +# Example output: "'foo', 'bar', 'baz'" + +function(to_meson_list input_list out_var) + list(JOIN input_list "', '" input_list) + set(${out_var} "'${input_list}'" PARENT_SCOPE) +endfunction() diff --git a/scripts/llvm/llvmlibc-support/CMakeLists.txt b/scripts/llvm/llvmlibc-support/CMakeLists.txt new file mode 100644 index 00000000..0e61b37f --- /dev/null +++ b/scripts/llvm/llvmlibc-support/CMakeLists.txt @@ -0,0 +1,46 @@ +# +# Copyright (c) 2022, 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. +# + +# This directory builds two additional library files to go with llvm-libc: +# +# libcrt0.a contains an implementation of the _start() default entry point, +# which sets up the stack and does any necessary initialization before +# calling main(). +# +# libsemihost.a implements llvm-libc's porting function API such as +# __llvm_libc_stdio_write, in terms of the Arm semihosting system. +# +# To use LLVM libc in a semihosting context, include both of these +# libraries. To use it in a different context, you will need to +# reimplement the same functions that libsemihost.a provides, but +# libcrt0.a might still be useful. + +cmake_minimum_required(VERSION 3.20.0) +project(llvmlibc-support LANGUAGES C ASM) + +add_library(semihost STATIC + init.c + exit.c + stdio_read.c + stdio_write.c +) + +add_library(crt0 STATIC + crt0.c +) + +install(TARGETS semihost crt0) diff --git a/scripts/llvm/llvmlibc-support/crt0.c b/scripts/llvm/llvmlibc-support/crt0.c new file mode 100644 index 00000000..b2f11693 --- /dev/null +++ b/scripts/llvm/llvmlibc-support/crt0.c @@ -0,0 +1,34 @@ +// +// Copyright (c) 2022, 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. +// + +#include +#include + +#include "platform.h" + +int main(int, char **); + +__attribute__((used)) static void c_startup(void) { + _platform_init(); + _Exit(main(0, NULL)); +} + +extern long __stack[]; +__attribute__((naked)) void _start(void) { + __asm__("mov sp, %0" : : "r"(__stack)); + __asm__("b c_startup"); +} diff --git a/scripts/llvm/llvmlibc-support/exit.c b/scripts/llvm/llvmlibc-support/exit.c new file mode 100644 index 00000000..f6c8e810 --- /dev/null +++ b/scripts/llvm/llvmlibc-support/exit.c @@ -0,0 +1,34 @@ +// +// Copyright (c) 2022, 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. +// + +#include + +#include "semihost.h" + +void __llvm_libc_exit(int status) { + +#if defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE + size_t block[2]; + block[0] = ADP_Stopped_ApplicationExit; + block[1] = status; + semihosting_call(SYS_EXIT, block); +#else + semihosting_call(SYS_EXIT, (const void *)ADP_Stopped_ApplicationExit); +#endif + + __builtin_unreachable(); /* semihosting call doesn't return */ +} diff --git a/scripts/llvm/llvmlibc-support/init.c b/scripts/llvm/llvmlibc-support/init.c new file mode 100644 index 00000000..bbe8d3c8 --- /dev/null +++ b/scripts/llvm/llvmlibc-support/init.c @@ -0,0 +1,39 @@ +// +// Copyright (c) 2022, 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. +// + +#include + +#include "platform.h" +#include "semihost.h" + +struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie; +struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie; +struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie; + +static void stdio_open(struct __llvm_libc_stdio_cookie *cookie, int mode) { + size_t args[3]; + args[0] = (size_t) ":tt"; + args[1] = (size_t)mode; + args[2] = (size_t)3; /* name length */ + cookie->handle = semihosting_call(SYS_OPEN, args); +} + +void _platform_init(void) { + stdio_open(&__llvm_libc_stdin_cookie, OPENMODE_R); + stdio_open(&__llvm_libc_stdout_cookie, OPENMODE_W); + stdio_open(&__llvm_libc_stderr_cookie, OPENMODE_W); +} diff --git a/scripts/llvm/llvmlibc-support/platform.h b/scripts/llvm/llvmlibc-support/platform.h new file mode 100644 index 00000000..668c3304 --- /dev/null +++ b/scripts/llvm/llvmlibc-support/platform.h @@ -0,0 +1,34 @@ +// +// Copyright (c) 2022, 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. +// + +// This header file defines the interface between libcrt0.a, which defines +// the program entry point, and libsemihost.a, which implements the +// LLVM-libc porting functions in terms of semihosting. If you replace +// libsemihost.a with something else, this header file shows how to make +// that work with libcrt0.a. + +#ifndef LLVMET_LLVMLIBC_SUPPORT_PLATFORM_H +#define LLVMET_LLVMLIBC_SUPPORT_PLATFORM_H + +// libcrt0.a will call this function after the stack pointer is +// initialized. If any setup specific to the libc porting layer is +// needed, this is where to do it. For example, in semihosting, the +// standard I/O handles must be opened via the SYS_OPEN operation, and +// this function is where libsemihost.a does it. +void _platform_init(void); + +#endif // LLVMET_LLVMLIBC_SUPPORT_PLATFORM_H diff --git a/scripts/llvm/llvmlibc-support/semihost.h b/scripts/llvm/llvmlibc-support/semihost.h new file mode 100644 index 00000000..71c80949 --- /dev/null +++ b/scripts/llvm/llvmlibc-support/semihost.h @@ -0,0 +1,117 @@ +// +// Copyright (c) 2022, 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. +// + +// This header file provides internal definitions for libsemihost.a, +// including an inline function to make a semihosting call, and a lot +// of constant definitions. + +#ifndef LLVMET_LLVMLIBC_SUPPORT_SEMIHOST_H +#define LLVMET_LLVMLIBC_SUPPORT_SEMIHOST_H + +#include + +#if __ARM_64BIT_STATE +# define ARG_REG_0 "x0" +# define ARG_REG_1 "x1" +#else +# define ARG_REG_0 "r0" +# define ARG_REG_1 "r1" +#endif + +#if __ARM_64BIT_STATE // A64 +# define SEMIHOST_INSTRUCTION "hlt #0xf000" +#elif defined(__thumb__) // T32 +# if defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' +# define SEMIHOST_INSTRUCTION "bkpt #0xAB" +# elif defined(HLT_SEMIHOSTING) +# define SEMIHOST_INSTRUCTION ".inst.n 0xbabc" // hlt #60 +# else +# define SEMIHOST_INSTRUCTION "svc 0xab" +# endif +#else // A32 +# if defined(HLT_SEMIHOSTING) +# define SEMIHOST_INSTRUCTION ".inst 0xe10f0070" // hlt #0xf000 +# else +# define SEMIHOST_INSTRUCTION "svc 0x123456" +# endif +#endif + +__attribute__((always_inline)) +static long semihosting_call(long val, const void *ptr) { + register long v __asm__(ARG_REG_0) = val; + register const void *p __asm__(ARG_REG_1) = ptr; + __asm__ __volatile__(SEMIHOST_INSTRUCTION + : "+r"(v), "+r"(p) + : + : "memory", "cc"); + return v; +} + +#define SYS_CLOCK 0x10 +#define SYS_CLOSE 0x02 +#define SYS_ELAPSED 0x30 +#define SYS_ERRNO 0x13 +#define SYS_EXIT 0x18 +#define SYS_EXIT_EXTENDED 0x20 +#define SYS_FLEN 0x0c +#define SYS_GET_CMDLINE 0x15 +#define SYS_HEAPINFO 0x16 +#define SYS_ISERROR 0x08 +#define SYS_ISTTY 0x09 +#define SYS_OPEN 0x01 +#define SYS_READ 0x06 +#define SYS_READC 0x07 +#define SYS_REMOVE 0x0e +#define SYS_RENAME 0x0f +#define SYS_SEEK 0x0a +#define SYS_SYSTEM 0x12 +#define SYS_TICKFREQ 0x31 +#define SYS_TIME 0x11 +#define SYS_TMPNAM 0x0d +#define SYS_WRITE0 0x04 +#define SYS_WRITE 0x05 +#define SYS_WRITEC 0x03 + +#define ADP_Stopped_BranchThroughZero 0x20000 +#define ADP_Stopped_UndefinedInstr 0x20001 +#define ADP_Stopped_SoftwareInterrupt 0x20002 +#define ADP_Stopped_PrefetchAbort 0x20003 +#define ADP_Stopped_DataAbort 0x20004 +#define ADP_Stopped_AddressException 0x20005 +#define ADP_Stopped_IRQ 0x20006 +#define ADP_Stopped_FIQ 0x20007 +#define ADP_Stopped_BreakPoint 0x20020 +#define ADP_Stopped_WatchPoint 0x20021 +#define ADP_Stopped_StepComplete 0x20022 +#define ADP_Stopped_RunTimeErrorUnknown 0x20023 +#define ADP_Stopped_InternalError 0x20024 +#define ADP_Stopped_UserInterruption 0x20025 +#define ADP_Stopped_ApplicationExit 0x20026 +#define ADP_Stopped_StackOverflow 0x20027 +#define ADP_Stopped_DivisionByZero 0x20028 +#define ADP_Stopped_OSSpecific 0x20029 + +/* SYS_OPEN modes must be one of R,W,A, plus an optional B and optional PLUS */ +#define OPENMODE_R 0 +#define OPENMODE_W 4 +#define OPENMODE_A 8 +#define OPENMODE_B 1 +#define OPENMODE_PLUS 2 + +struct __llvm_libc_stdio_cookie { int handle; }; + +#endif // LLVMET_LLVMLIBC_SUPPORT_SEMIHOST_H diff --git a/scripts/llvm/llvmlibc-support/stdio_read.c b/scripts/llvm/llvmlibc-support/stdio_read.c new file mode 100644 index 00000000..aa2c00fe --- /dev/null +++ b/scripts/llvm/llvmlibc-support/stdio_read.c @@ -0,0 +1,33 @@ +// +// Copyright (c) 2022, 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. +// + +#include + +#include "semihost.h" + +ssize_t __llvm_libc_stdio_read(struct __llvm_libc_stdio_cookie *cookie, + const char *buf, size_t size) { + size_t args[4]; + args[0] = (size_t)cookie->handle; + args[1] = (size_t)buf; + args[2] = (size_t)size; + args[3] = 0; + ssize_t retval = semihosting_call(SYS_READ, args); + if (retval >= 0) + retval = size - retval; + return retval; +} diff --git a/scripts/llvm/llvmlibc-support/stdio_write.c b/scripts/llvm/llvmlibc-support/stdio_write.c new file mode 100644 index 00000000..9b7741fd --- /dev/null +++ b/scripts/llvm/llvmlibc-support/stdio_write.c @@ -0,0 +1,32 @@ +// +// Copyright (c) 2022, 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. +// + +#include + +#include "semihost.h" + +ssize_t __llvm_libc_stdio_write(struct __llvm_libc_stdio_cookie *cookie, + const char *buf, size_t size) { + size_t args[4]; + args[0] = (size_t)cookie->handle; + args[1] = (size_t)buf; + args[2] = (size_t)size; + ssize_t retval = semihosting_call(SYS_WRITE, args); + if (retval >= 0) + retval = size - retval; + return retval; +} diff --git a/scripts/llvm/llvmlibc.cfg b/scripts/llvm/llvmlibc.cfg new file mode 100644 index 00000000..14aba3bf --- /dev/null +++ b/scripts/llvm/llvmlibc.cfg @@ -0,0 +1 @@ +--sysroot /../lib/clang-runtimes/llvmlibc diff --git a/scripts/llvm/mingw-licenses/COPYING.MinGW-w64-runtime.txt b/scripts/llvm/mingw-licenses/COPYING.MinGW-w64-runtime.txt new file mode 100644 index 00000000..ca6a077e --- /dev/null +++ b/scripts/llvm/mingw-licenses/COPYING.MinGW-w64-runtime.txt @@ -0,0 +1,240 @@ +MinGW-w64 runtime licensing +*************************** + +This program or library was built using MinGW-w64 and statically +linked against the MinGW-w64 runtime. Some parts of the runtime +are under licenses which require that the copyright and license +notices are included when distributing the code in binary form. +These notices are listed below. + + +======================== +Overall copyright notice +======================== + +Copyright (c) 2009, 2010, 2011, 2012, 2013 by the mingw-w64 project + +This license has been certified as open source. It has also been designated +as GPL compatible by the Free Software Foundation (FSF). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions in source code must retain the accompanying copyright + notice, this list of conditions, and the following disclaimer. + 2. Redistributions in binary form must reproduce the accompanying + copyright notice, this list of conditions, and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + 3. Names of the copyright holders must not be used to endorse or promote + products derived from this software without prior written permission + from the copyright holders. + 4. The right to distribute this software or to use it for any purpose does + not give you the right to use Servicemarks (sm) or Trademarks (tm) of + the copyright holders. Use of them is covered by separate agreement + with the copyright holders. + 5. If any files are modified, you must cause the modified files to carry + prominent notices stating that you changed the files and the date of + any change. + +Disclaimer + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +======================================== +getopt, getopt_long, and getop_long_only +======================================== + +Copyright (c) 2002 Todd C. Miller + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Sponsored in part by the Defense Advanced Research Projects +Agency (DARPA) and Air Force Research Laboratory, Air Force +Materiel Command, USAF, under agreement number F39502-99-1-0512. + + * * * * * * * + +Copyright (c) 2000 The NetBSD Foundation, Inc. +All rights reserved. + +This code is derived from software contributed to The NetBSD Foundation +by Dieter Baron and Thomas Klausner. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + + +=============================================================== +gdtoa: Converting between IEEE floating point numbers and ASCII +=============================================================== + +The author of this software is David M. Gay. + +Copyright (C) 1997, 1998, 1999, 2000, 2001 by Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + + * * * * * * * + +The author of this software is David M. Gay. + +Copyright (C) 2005 by David M. Gay +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that the copyright notice and this permission notice and warranty +disclaimer appear in supporting documentation, and that the name of +the author or any of his current or former employers not be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. + +THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN +NO EVENT SHALL THE AUTHOR OR ANY OF HIS CURRENT OR FORMER EMPLOYERS BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + + * * * * * * * + +The author of this software is David M. Gay. + +Copyright (C) 2004 by David M. Gay. +All Rights Reserved +Based on material in the rest of /netlib/fp/gdota.tar.gz, +which is copyright (C) 1998, 2000 by Lucent Technologies. + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. + + +========================= +Parts of the math library +========================= + +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + +Developed at SunSoft, a Sun Microsystems, Inc. business. +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. + + * * * * * * * + +Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + +Developed at SunPro, a Sun Microsystems, Inc. business. +Permission to use, copy, modify, and distribute this +software is freely granted, provided that this notice +is preserved. + + * * * * * * * + +FIXME: Cephes math lib +Copyright (C) 1984-1998 Stephen L. Moshier + +It sounds vague, but as to be found at +, it gives an +impression that the author could be willing to give an explicit +permission to distribute those files e.g. under a BSD style license. So +probably there is no problem here, although it could be good to get a +permission from the author and then add a license into the Cephes files +in MinGW runtime. At least on follow-up it is marked that debian sees the +version a-like BSD one. As MinGW.org (where those cephes parts are coming +from) distributes them now over 6 years, it should be fine. + +=================================== +Headers and IDLs imported from Wine +=================================== + +Some header and IDL files were imported from the Wine project. These files +are prominent maked in source. Their copyright belongs to contributors and +they are distributed under LGPL license. + +Disclaimer + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. diff --git a/scripts/llvm/mingw-licenses/COPYING.RUNTIME b/scripts/llvm/mingw-licenses/COPYING.RUNTIME new file mode 100644 index 00000000..e1b3c69c --- /dev/null +++ b/scripts/llvm/mingw-licenses/COPYING.RUNTIME @@ -0,0 +1,73 @@ +GCC RUNTIME LIBRARY EXCEPTION + +Version 3.1, 31 March 2009 + +Copyright (C) 2009 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + +This GCC Runtime Library Exception ("Exception") is an additional +permission under section 7 of the GNU General Public License, version +3 ("GPLv3"). It applies to a given file (the "Runtime Library") that +bears a notice placed by the copyright holder of the file stating that +the file is governed by GPLv3 along with this Exception. + +When you use GCC to compile a program, GCC may combine portions of +certain GCC header files and runtime libraries with the compiled +program. The purpose of this Exception is to allow compilation of +non-GPL (including proprietary) programs to use, in this way, the +header files and runtime libraries covered by this Exception. + +0. Definitions. + +A file is an "Independent Module" if it either requires the Runtime +Library for execution after a Compilation Process, or makes use of an +interface provided by the Runtime Library, but is not otherwise based +on the Runtime Library. + +"GCC" means a version of the GNU Compiler Collection, with or without +modifications, governed by version 3 (or a specified later version) of +the GNU General Public License (GPL) with the option of using any +subsequent versions published by the FSF. + +"GPL-compatible Software" is software whose conditions of propagation, +modification and use would permit combination with GCC in accord with +the license of GCC. + +"Target Code" refers to output from any compiler for a real or virtual +target processor architecture, in executable form or suitable for +input to an assembler, loader, linker and/or execution +phase. Notwithstanding that, Target Code does not include data in any +format that is used as a compiler intermediate representation, or used +for producing a compiler intermediate representation. + +The "Compilation Process" transforms code entirely represented in +non-intermediate languages designed for human-written code, and/or in +Java Virtual Machine byte code, into Target Code. Thus, for example, +use of source code generators and preprocessors need not be considered +part of the Compilation Process, since the Compilation Process can be +understood as starting with the output of the generators or +preprocessors. + +A Compilation Process is "Eligible" if it is done using GCC, alone or +with other GPL-compatible software, or if it is done without using any +work based on GCC. For example, using non-GPL-compatible Software to +optimize any GCC intermediate representations would not qualify as an +Eligible Compilation Process. + +1. Grant of Additional Permission. + +You have permission to propagate a work of Target Code formed by +combining the Runtime Library with Independent Modules, even if such +propagation would otherwise violate the terms of GPLv3, provided that +all Target Code was generated by Eligible Compilation Processes. You +may then convey such a combination under terms of your choice, +consistent with the licensing of the Independent Modules. + +2. No Weakening of GCC Copyleft. + +The availability of this Exception does not imply any general +presumption that third-party software is unaffected by the copyleft +requirements of the license of GCC. + diff --git a/scripts/llvm/mingw-licenses/COPYING3.GCC b/scripts/llvm/mingw-licenses/COPYING3.GCC new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/scripts/llvm/mingw-licenses/COPYING3.GCC @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/scripts/llvm/multilib-fpus.py b/scripts/llvm/multilib-fpus.py new file mode 100755 index 00000000..992d4873 --- /dev/null +++ b/scripts/llvm/multilib-fpus.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python3 + +"""Auto-generate implications between -mfpu options for multilib.yaml.in. + +Each FPU name that clang knows about is mapped to all the FPU names +that clang considers to be a subset of it (determined by extracting +the cc1 command from `clang -###` for each one and looking at the set +of -target-feature options). + +An exception is that we don't consider any hardware FP configuration +to be compatible with -mfpu=none. It would work in most cases to +cross-call between code compiled for an FPU or no FPU, if you were +using the soft float ABI. But it wouldn't work in all cases: setjmp +needs to know whether to save FP registers in the jmp_buf, so a +non-FPU-aware setjmp would not behave correctly if linked into an +otherwise FPU-using application. Similarly for exception unwinding. So +we don't permit selecting an -mfpu=none library as a fallback for any +hard-FP library. + +However, it's fine for ABI purposes to mix code compiled for 16 and 32 +d-registers, because the extra 16 d-registers are caller-saved, so +setjmp and exceptions need not preserve them. Interrupt handlers would +have to preserve them, but our libraries don't define any. +""" + +import argparse +import json +import os +import shlex +import subprocess + + +def get_fpu_list(args): + """Extract the list of FPUs from ARMTargetParser.def. + + Strategy: the intended use of ARMTargetParser.def in the actual + LLVM build is to run it through the C preprocessor with whatever + #defines will generate the output you want. So the most reliable + way to get what _we_ want is to do exactly the same. + + The output format I've chosen is actually JSON, because that's + close enough to C-like syntax that you can generate it easily + using cpp features like stringification, and also convenient for + Python to consume afterwards. + """ + + command = [ + args.clang, + # For this purpose we're only interested in the calls to the + # ARM_FPU macro in the input file, and want the first and + # third argument of each of those. + # + # The first argument will be a string literal giving the FPU + # name, which we copy into the JSON output still as a string + # literal. + # + # The third argument indicates the general FPU category, which + # we need so as to exclude FPUVersion::NONE. That is not + # already a string literal, so we stringify it in the + # preprocessor to make it legal JSON. + "-DARM_FPU(name,kind,version,...)=[name,#version],", + "-E", # preprocess + "-P", # don't output linemarkers + "-xc", # treat input as C, even though no .c filename extension + os.path.join( + args.llvm_source, + "llvm", + "include", + "llvm", + "TargetParser", + "ARMTargetParser.def", + ), + ] + + raw_output = subprocess.check_output(command) + + # The output of the above is a collection of JSON arrays each + # containing two strings, and each followed by a comma. Turn it + # into a single legal JSON declaration by deleting the final comma + # and wrapping it in array brackets. + json_output = b"[" + raw_output.strip().rstrip(b",") + b"]" + + # Filter the list of 2-tuples to exclude the FPU names that aren't + # FPUs. + for name, fputype in json.loads(json_output): + assert fputype.startswith("FPUVersion::"), ( + f"FPU type value {fputype} not of the expected form!\n" + "Has ARMTargetParser.def been refactored?" + ) + + if fputype != "FPUVersion::NONE": + yield name + + +def get_target_features(args, fpu): + """Return the set of feature names for a given FPU. + + Strategy: run a clang compile command with that FPU, including + the -### argument to print all the subsidiary command lines, and + extract the list of "-target-feature" "+foo" options from the + clang -cc1 command line in the output. This shows what low-level + LLVM feature names are enabled by that FPU. + + It will also include the feature names enabled by the CPU or + architecture we specified. But since we only care about which + FPUs are subsets of which other ones, that doesn't affect the + output, as long as the architecture is the same for all the FPUs + we do this with. + """ + + command = [ + args.clang, + "--target=arm-none-eabi", + "-march=armv7a", + "-mfpu=" + fpu, + "-S", # tell clang to do as little as possible + "-xc", # interpret input as C + "-", # read from standard input (not that we'll get that far) + "-###", # print all the command lines rather than actually doing it + ] + + output = subprocess.check_output( + command, stderr=subprocess.STDOUT + ).decode() + + # Find the clang -cc1 command, and parse it into an argv list. + for line in output.splitlines(): + try: + words = shlex.split(line) + except ValueError: + # We expect that some of the output lines won't parse as + # valid shell syntax, because -### doesn't output *only* + # command lines. So this is fine; any line that doesn't + # parse is not the one we were looking for anyway. + continue + + if len(words) > 1 and words[1] == "-cc1": + # We've found the cc1 command. + break + else: + assert False, "no cc1 command found in output of: " + " ".join( + map(shlex.quote, command) + ) + + # Now we've found the clang command, go through it for + # -target-feature options. We only care about the ones that add + # rather than removing features, i.e. "-target-feature +foo" + # rather than "-target-feature -bar". + it = iter(words) + features = set() + for word in it: + if word == "-target-feature": + arg = next(it) + if arg.startswith("+"): + features.add(arg[1:]) + + assert len(features) > 0, ( + "This cc1 command contained no argument pairs of the form" + " '-target-feature +something':\n" + f"{line}\n" + "Has the clang -cc1 command-line syntax changed?" + ) + + return features + + +def main(): + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument( + "--clang", required=True, help="Path to clang executable." + ) + parser.add_argument( + "--llvm-source", + required=True, + help="Path to root of llvm-project source tree.", + ) + args = parser.parse_args() + + # Collect all the data: make the list of FPU names, and the set of + # features that LLVM maps each one to. + fpu_features = { + fpuname: get_target_features(args, fpuname) + for fpuname in get_fpu_list(args) + } + + # Now, for each FPU, find all the FPUs that are subsets of it + # (excluding itself). + sorted_fpus = list(sorted(fpu_features)) + for super_fpu in sorted_fpus: + subsets = [ + sub_fpu + for sub_fpu in sorted_fpus + if sub_fpu != super_fpu + and fpu_features[sub_fpu].issubset(fpu_features[super_fpu]) + ] + + # If this FPU has any subsets at all, write a multilib.yaml + # snippet that adds all the subset FPU flags if it sees the + # superset flag. + # + # The YAML is trivial enough that it's easier to do this by + # hand than to rely on everyone having python3-yaml available. + if len(subsets) > 0: + print("- Match: -mfpu=" + super_fpu) + print(" Flags:") + for sub_fpu in subsets: + print(" - -mfpu=" + sub_fpu) + + +if __name__ == "__main__": + main() diff --git a/scripts/llvm/newlib.cfg b/scripts/llvm/newlib.cfg new file mode 100644 index 00000000..c100f0f1 --- /dev/null +++ b/scripts/llvm/newlib.cfg @@ -0,0 +1 @@ +--sysroot /../lib/clang-runtimes/newlib diff --git a/scripts/llvm/packagetest/CMakeLists.txt b/scripts/llvm/packagetest/CMakeLists.txt new file mode 100644 index 00000000..7ee95ba8 --- /dev/null +++ b/scripts/llvm/packagetest/CMakeLists.txt @@ -0,0 +1,38 @@ +if(LLVM_ENABLE_BACKTRACES) + set(ENABLE_BACKTRACES 1) +endif() +llvm_canonicalize_cmake_booleans( + ENABLE_BACKTRACES +) + +# If samples are included in the package then use the packaged samples in +# post-package tests, otherwise use the samples from the source directory. +if(llvm-toolchain-samples IN_LIST LLVM_TOOLCHAIN_DISTRIBUTION_COMPONENTS) + set(samples_dir ${unpack_directory}/samples) +else() + set(samples_dir ${CMAKE_CURRENT_SOURCE_DIR}/../samples) +endif() + +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py + MAIN_CONFIG + ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py +) + +list(APPEND LLVM_TOOLCHAIN_PACKAGE_TEST_DEPS + unpack-llvm-toolchain + FileCheck + count + not +) + +add_lit_testsuite(check-package-llvm-toolchain + "Running Zephyr SDK LLVM package tests" + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${LLVM_TOOLCHAIN_PACKAGE_TEST_DEPS} +) + +add_lit_testsuites(package-llvm-toolchain ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${LLVM_TOOLCHAIN_PACKAGE_TEST_DEPS} +) diff --git a/scripts/llvm/packagetest/Inputs/microbit.ld b/scripts/llvm/packagetest/Inputs/microbit.ld new file mode 100644 index 00000000..d36c4f52 --- /dev/null +++ b/scripts/llvm/packagetest/Inputs/microbit.ld @@ -0,0 +1,9 @@ +__boot_flash = 0x00000000; /* fragment of the flash where interrupt vector goes */ +__boot_flash_size = 0x1000; /* length of flash fragment with interrupt vector */ +__flash = 0x00001000; /* starting address of the remaining flash */ +__flash_size = 0x3f000; /* length of the remaining flash */ +__ram = 0x20000000; /* starting address of RAM bank 0 */ +__ram_size = 0x4000; /* length of RAM bank 0 */ +__stack_size = 512; + +INCLUDE picolibcpp.ld diff --git a/scripts/llvm/packagetest/README.md b/scripts/llvm/packagetest/README.md new file mode 100644 index 00000000..3cfe7a99 --- /dev/null +++ b/scripts/llvm/packagetest/README.md @@ -0,0 +1,12 @@ +This directory contains LLVM lit tests to be run against Zephyr SDK LLVM that +has been extracted from a package in the same way that a user of the product +would. This is unlike the tests in the test directory, which run against tools +in the build directory. + +You can run the tests ensuring that all dependencies are built: + + ninja check-package-llvm-toolchain + +Or run the tests with lit directly: + + ${BUILD_DIR}/llvm/bin/llvm-lit -sv ${BUILD_DIR}/packagetest diff --git a/scripts/llvm/packagetest/baremetal-semihosting-aarch64.test b/scripts/llvm/packagetest/baremetal-semihosting-aarch64.test new file mode 100644 index 00000000..a9af3428 --- /dev/null +++ b/scripts/llvm/packagetest/baremetal-semihosting-aarch64.test @@ -0,0 +1,4 @@ +# RUN: make -C %samples_dir/src/baremetal-semihosting-aarch64 clean +# RUN: make -C %samples_dir/src/baremetal-semihosting-aarch64 run BIN_PATH=%unpack_directory/bin 2>&1 | FileCheck %s +# RUN: make -C %samples_dir/src/baremetal-semihosting-aarch64 clean +# CHECK: Hello World! diff --git a/scripts/llvm/packagetest/baremetal-semihosting.test b/scripts/llvm/packagetest/baremetal-semihosting.test new file mode 100644 index 00000000..f60c04b2 --- /dev/null +++ b/scripts/llvm/packagetest/baremetal-semihosting.test @@ -0,0 +1,4 @@ +# RUN: make -C %samples_dir/src/baremetal-semihosting clean +# RUN: make -C %samples_dir/src/baremetal-semihosting run BIN_PATH=%unpack_directory/bin 2>&1 | FileCheck %s +# RUN: make -C %samples_dir/src/baremetal-semihosting clean +# CHECK: Hello World! diff --git a/scripts/llvm/packagetest/baremetal-uart.test b/scripts/llvm/packagetest/baremetal-uart.test new file mode 100644 index 00000000..1aa5330c --- /dev/null +++ b/scripts/llvm/packagetest/baremetal-uart.test @@ -0,0 +1,5 @@ +# RUN: make -C %samples_dir/src/baremetal-uart clean +# The sample never terminates so we can't run it here, but we can at +# least make sure it builds. +# RUN: make -C %samples_dir/src/baremetal-uart build BIN_PATH=%unpack_directory/bin +# RUN: make -C %samples_dir/src/baremetal-uart clean diff --git a/scripts/llvm/packagetest/cpp-baremetal-semihosting-cfi.test b/scripts/llvm/packagetest/cpp-baremetal-semihosting-cfi.test new file mode 100644 index 00000000..2e4ce8b4 --- /dev/null +++ b/scripts/llvm/packagetest/cpp-baremetal-semihosting-cfi.test @@ -0,0 +1,10 @@ +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-cfi clean +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-cfi run BIN_PATH=%unpack_directory/bin 2>&1 | FileCheck %s +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-cfi clean +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-cfi build-no-cfi +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-cfi run BIN_PATH=%unpack_directory/bin 2>&1 | FileCheck %s --check-prefix=NOCFI +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-cfi clean +# CHECK-NOT: Bad +# CHECK: hardfault +# NOCFI: Bad +# NOCFI: C++ CFI sample diff --git a/scripts/llvm/packagetest/cpp-baremetal-semihosting-exceptions.test b/scripts/llvm/packagetest/cpp-baremetal-semihosting-exceptions.test new file mode 100644 index 00000000..1bf017d5 --- /dev/null +++ b/scripts/llvm/packagetest/cpp-baremetal-semihosting-exceptions.test @@ -0,0 +1,5 @@ +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-exceptions clean +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-exceptions run BIN_PATH=%unpack_directory/bin 2>&1 | FileCheck %s +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-exceptions clean +# CHECK: No exceptions. +# CHECK: Exception caught. diff --git a/scripts/llvm/packagetest/cpp-baremetal-semihosting-prof.test b/scripts/llvm/packagetest/cpp-baremetal-semihosting-prof.test new file mode 100644 index 00000000..99b074f3 --- /dev/null +++ b/scripts/llvm/packagetest/cpp-baremetal-semihosting-prof.test @@ -0,0 +1,4 @@ +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-prof clean +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-prof run BIN_PATH=%unpack_directory/bin 2>&1 | FileCheck %s +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-prof clean +# CHECK: 1 2 3 4 5 diff --git a/scripts/llvm/packagetest/cpp-baremetal-semihosting-ubsan.test b/scripts/llvm/packagetest/cpp-baremetal-semihosting-ubsan.test new file mode 100644 index 00000000..48e31ca4 --- /dev/null +++ b/scripts/llvm/packagetest/cpp-baremetal-semihosting-ubsan.test @@ -0,0 +1,5 @@ +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-ubsan clean +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-ubsan run BIN_PATH=%unpack_directory/bin 2>&1 | FileCheck %s +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting-ubsan clean +# CHECK: UBSAN: add-overflow (recovered) +# CHECK: C++ UBSan sample diff --git a/scripts/llvm/packagetest/cpp-baremetal-semihosting.test b/scripts/llvm/packagetest/cpp-baremetal-semihosting.test new file mode 100644 index 00000000..ade37945 --- /dev/null +++ b/scripts/llvm/packagetest/cpp-baremetal-semihosting.test @@ -0,0 +1,4 @@ +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting clean +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting run BIN_PATH=%unpack_directory/bin 2>&1 | FileCheck %s +# RUN: make -C %samples_dir/src/cpp-baremetal-semihosting clean +# CHECK: 1 2 3 4 5 diff --git a/scripts/llvm/packagetest/hello.c b/scripts/llvm/packagetest/hello.c new file mode 100644 index 00000000..b0bb0ee7 --- /dev/null +++ b/scripts/llvm/packagetest/hello.c @@ -0,0 +1,9 @@ +// RUN: %clang --target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m -mfpu=none -lcrt0-semihost -lsemihost -T %S/Inputs/microbit.ld %s -o %t.out +// RUN: qemu-system-arm -M microbit -semihosting -nographic -device loader,file=%t.out 2>&1 | FileCheck %s + +#include + +int main(void) { + printf("Hello World!\n"); // CHECK: Hello World! + return 0; +} diff --git a/scripts/llvm/packagetest/hello.cpp b/scripts/llvm/packagetest/hello.cpp new file mode 100644 index 00000000..65b7572e --- /dev/null +++ b/scripts/llvm/packagetest/hello.cpp @@ -0,0 +1,99 @@ +// RUN: %clangxx --target=armv6m-none-eabi -mfloat-abi=soft -march=armv6m -mfpu=none -lcrt0-semihost -lsemihost -fno-exceptions -fno-rtti -T %S/Inputs/microbit.ld %s -o %t.out +// RUN: qemu-system-arm -M microbit -semihosting -nographic -device loader,file=%t.out 2>&1 | FileCheck %s + +// Include as many C++17 headers as possible. +// Unsupported headers are commented out. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +//#include +#include +#include +//#include // removed in C++20 +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(void) { + std::string str = "Hello World!"; + std::cout << str << std::endl; // CHECK: Hello World! + return 0; +} diff --git a/scripts/llvm/packagetest/lit.cfg.py b/scripts/llvm/packagetest/lit.cfg.py new file mode 100644 index 00000000..12d72dda --- /dev/null +++ b/scripts/llvm/packagetest/lit.cfg.py @@ -0,0 +1,47 @@ +# -*- Python -*- + +import os +import sys + +import lit.formats + +from lit.llvm import llvm_config +from lit.llvm.subst import FindTool, ToolSubst + +# Configuration file for the 'lit' test runner. + +config.name = 'package' +config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) +config.suffixes = ['.c', '.cpp', '.test'] +config.excludes = ['CMakeLists.txt', 'README.md'] +config.test_source_root = os.path.dirname(__file__) + + +# Copy-pasted from use_default_substitutions in +# llvm-project/llvm/utils/lit/lit/llvm/config.py +# FileCheck is not packaged so we need to get it from a different directory. +tool_patterns = [ + ToolSubst("FileCheck", unresolved="fatal"), + # Handle these specially as they are strings searched for during + # testing. + ToolSubst( + r"\| \bcount\b", + command=FindTool("count"), + verbatim=True, + unresolved="fatal", + ), + ToolSubst( + r"\| \bnot\b", + command=FindTool("not"), + verbatim=True, + unresolved="fatal", + ), +] +llvm_config.config.substitutions.append(("%python", '"%s"' % (sys.executable))) +llvm_config.add_tool_substitutions(tool_patterns, [os.path.join(config.llvm_obj_root, "bin")]) +llvm_config.add_err_msg_substitutions() +llvm_config.use_clang() +llvm_config.config.substitutions.append(("%samples_dir", '"%s"' % config.samples_dir)) +llvm_config.config.substitutions.append(("%unpack_directory", '"%s"' % config.unpack_directory)) + +config.environment["CLANG_NO_DEFAULT_CONFIG"] = "1" diff --git a/scripts/llvm/packagetest/lit.site.cfg.py.in b/scripts/llvm/packagetest/lit.site.cfg.py.in new file mode 100644 index 00000000..371f46b6 --- /dev/null +++ b/scripts/llvm/packagetest/lit.site.cfg.py.in @@ -0,0 +1,21 @@ +@LIT_SITE_CFG_IN_HEADER@ + +config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.llvm_obj_root = "@LLVM_BINARY_DIR@" +config.unpack_directory = lit_config.substitute("@unpack_directory@") +config.samples_dir = lit_config.substitute("@samples_dir@") +config.llvm_tools_dir = lit_config.substitute("@unpack_directory@/bin") +config.llvm_libs_dir = lit_config.substitute("@unpack_directory@/lib") +config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" +config.enable_backtrace = @ENABLE_BACKTRACES@ +config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@" +config.host_triple = "@LLVM_HOST_TRIPLE@" +config.target_triple = "@LLVM_DEFAULT_TARGET_TRIPLE@" +config.python_executable = "@Python3_EXECUTABLE@" +config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" + +import lit.llvm +lit.llvm.initialize(lit_config, config) + +# Let the main config do the real work. +lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg.py") diff --git a/scripts/llvm/test-support/lit-exec-qemu.py b/scripts/llvm/test-support/lit-exec-qemu.py new file mode 100755 index 00000000..a98bc980 --- /dev/null +++ b/scripts/llvm/test-support/lit-exec-qemu.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2023, Arm Limited and affiliates. + +# This script is a bridge between lit-based tests of LLVM C++ runtime libraries +# (libc++abi, libunwind, libc++) and QEMU. It must handle the same command-line +# arguments as llvm-project/libcxx/utils/run.py. + +from run_qemu import run_qemu +import argparse +import pathlib +import sys + + +def main(): + parser = argparse.ArgumentParser( + description="Run a single test using qemu" + ) + parser.add_argument( + "--qemu-command", required=True, help="qemu-system- path" + ) + parser.add_argument( + "--qemu-machine", + required=True, + help="name of the machine to pass to QEMU", + ) + parser.add_argument( + "--qemu-cpu", required=False, help="name of the cpu to pass to QEMU" + ) + parser.add_argument( + "--qemu-params", + required=False, + help='list of arguments to pass to qemu, separated with ":"', + ) + parser.add_argument( + "--timeout", + type=int, + default=900, + help="timeout, in seconds (default: 900)", + ) + parser.add_argument( + "--execdir", + type=pathlib.Path, + default=pathlib.Path.cwd(), + help="directory to run the program from", + ) + parser.add_argument( + "--codesign_identity", + type=str, + help="ignored, used for compatibility with libc++ tests", + ) + parser.add_argument( + "--env", + type=str, + nargs="*", + help="ignored, used for compatibility with libc++ tests", + ) + parser.add_argument( + "--verbose", + action="store_true", + help="Print verbose output. This may affect test result, as the output " + "will be added to the output of the test.", + ) + parser.add_argument("image", help="image file to execute") + parser.add_argument( + "arguments", + nargs=argparse.REMAINDER, + default=[], + help="optional arguments for the image", + ) + args = parser.parse_args() + ret_code = run_qemu( + args.qemu_command, + args.qemu_machine, + args.qemu_cpu, + args.qemu_params.split(":") if args.qemu_params else [], + args.image, + [args.image] + args.arguments, + args.timeout, + args.execdir, + args.verbose, + ) + sys.exit(ret_code) + + +if __name__ == "__main__": + main() diff --git a/scripts/llvm/test-support/llvm-libc++-picolibc.cfg.in b/scripts/llvm/test-support/llvm-libc++-picolibc.cfg.in new file mode 100644 index 00000000..2c00fd89 --- /dev/null +++ b/scripts/llvm/test-support/llvm-libc++-picolibc.cfg.in @@ -0,0 +1,49 @@ +# This testing configuration handles running the test suite against LLVM's libc++ +# using a static library. + +lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') + +config.name = 'libc++-@RUNTIME_VARIANT_NAME@' + +config.substitutions.append(('%{libc-include}', '@CMAKE_INSTALL_PREFIX@/include')) +config.substitutions.append(('%{libc-lib}', '@CMAKE_INSTALL_PREFIX@/lib')) +config.substitutions.append(('%{libc-linker-script}', '@LIBC_LINKER_SCRIPT@')) + +config.substitutions.append(('%{flags}', '@RUNTIME_TEST_ARCH_FLAGS@')) +config.substitutions.append(('%{compile_flags}', + '-nostdinc++ -I %{include-dir} -I %{target-include-dir} -I %{libcxx-dir}/test/support' + ' -isystem %{libc-include}' + + # Disable warnings in cxx_atomic_impl.h: + # "large atomic operation may incur significant performance penalty; the + # access size (4 bytes) exceeds the max lock-free size (0 bytes)" + ' -Wno-atomic-alignment' + + # Various libc++ headers check for the definition of _NEWLIB_VERSION + # which for picolibc is defined in picolibc.h. + ' -include picolibc.h' +)) +config.substitutions.append(('%{link_flags}', + ' -nostdlib++ -L %{lib-dir}' + ' -lc++ -lc++abi' + ' -nostdlib -L %{libc-lib}' + ' -lc -lm -lclang_rt.builtins -lsemihost -lcrt0-semihost' + ' -T %{libc-linker-script}' +)) +config.substitutions.append(('%{exec}', + '%{executor} --execdir %T -- ' +)) + +# Long tests are prohibitively slow when run via emulation. +config.long_tests = False +config.large_tests = False + +import os, site +site.addsitedir(os.path.join('@LIBCXX_SOURCE_DIR@', 'utils')) +import libcxx.test.params, libcxx.test.config +libcxx.test.config.configure( + libcxx.test.params.DEFAULT_PARAMETERS, + libcxx.test.features.DEFAULT_FEATURES, + config, + lit_config +) diff --git a/scripts/llvm/test-support/llvm-libc++abi-picolibc.cfg.in b/scripts/llvm/test-support/llvm-libc++abi-picolibc.cfg.in new file mode 100644 index 00000000..bfe0eb2e --- /dev/null +++ b/scripts/llvm/test-support/llvm-libc++abi-picolibc.cfg.in @@ -0,0 +1,37 @@ +# This testing configuration handles running the test suite against LLVM's libc++abi +# using a static library. + +lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') + +config.name = 'libc++abi-@RUNTIME_VARIANT_NAME@' + +config.substitutions.append(('%{libc-include}', '@CMAKE_INSTALL_PREFIX@/include')) +config.substitutions.append(('%{libc-lib}', '@CMAKE_INSTALL_PREFIX@/lib')) +config.substitutions.append(('%{libc-linker-script}', '@LIBC_LINKER_SCRIPT@')) + +config.substitutions.append(('%{flags}', '@RUNTIME_TEST_ARCH_FLAGS@')) +config.substitutions.append(('%{compile_flags}', + '-nostdinc++ -I %{include} -I %{cxx-include} -I %{cxx-target-include} %{maybe-include-libunwind} ' + ' -I %{libcxx}/test/support -I %{libcxx}/src -D_LIBCPP_ENABLE_CXX17_REMOVED_UNEXPECTED_FUNCTIONS' + ' -isystem %{libc-include}' +)) +config.substitutions.append(('%{link_flags}', + ' -nostdlib++ -L %{lib}' + ' -lc++ -lc++abi' + ' -nostdlib -L %{libc-lib}' + ' -lc -lm -lclang_rt.builtins -lsemihost -lcrt0-semihost' + ' -T %{libc-linker-script}' +)) +config.substitutions.append(('%{exec}', + '%{executor} --execdir %T -- ' +)) + +import os, site +site.addsitedir(os.path.join('@LIBCXXABI_LIBCXX_PATH@', 'utils')) +import libcxx.test.params, libcxx.test.config +libcxx.test.config.configure( + libcxx.test.params.DEFAULT_PARAMETERS, + libcxx.test.features.DEFAULT_FEATURES, + config, + lit_config +) diff --git a/scripts/llvm/test-support/llvm-libunwind-picolibc.cfg.in b/scripts/llvm/test-support/llvm-libunwind-picolibc.cfg.in new file mode 100644 index 00000000..d0f00a35 --- /dev/null +++ b/scripts/llvm/test-support/llvm-libunwind-picolibc.cfg.in @@ -0,0 +1,50 @@ +# +# Configuration file for running the libunwind tests against the static library. +# + +lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') + +config.name = 'libunwind-@RUNTIME_VARIANT_NAME@' + +config.substitutions.append(('%{libc-include}', '@CMAKE_INSTALL_PREFIX@/include')) +config.substitutions.append(('%{libc-lib}', '@CMAKE_INSTALL_PREFIX@/lib')) +config.substitutions.append(('%{libc-linker-script}', '@LIBC_LINKER_SCRIPT@')) + +compile_flags = [] + +if @LIBUNWIND_ENABLE_CET@: + compile_flags.append('-fcf-protection=full') + +# Stack unwinding tests need unwinding tables and these are not generated by default on all targets. +compile_flags.append('-funwind-tables') + +local_sysroot = '@CMAKE_OSX_SYSROOT@' or '@CMAKE_SYSROOT@' +config.substitutions.append(('%{flags}', + '@RUNTIME_TEST_ARCH_FLAGS@' + + (' -isysroot {}'.format(local_sysroot) if local_sysroot else '') +)) +config.substitutions.append(('%{compile_flags}', + '-nostdinc++ -I %{include} ' + ' -isystem %{libc-include} ' + + ' '.join(compile_flags) +)) +config.substitutions.append(('%{link_flags}', + ' -nostdlib++ -L %{lib}' + ' -lc++ -lc++abi -lunwind' + ' -nostdlib -L %{libc-lib}' + ' -lc -lm -lclang_rt.builtins -lsemihost -lcrt0-semihost' + ' -T %{libc-linker-script}' +)) +config.substitutions.append(('%{exec}', + '%{executor} --execdir %T -- ' +)) + +import os, site +site.addsitedir(os.path.join('@LIBUNWIND_LIBCXX_PATH@', 'utils')) +import libcxx.test.params, libcxx.test.config +libcxx.test.config.configure( + libcxx.test.params.DEFAULT_PARAMETERS, + libcxx.test.features.DEFAULT_FEATURES, + config, + lit_config +) diff --git a/scripts/llvm/test-support/picolibc-test-wrapper.py b/scripts/llvm/test-support/picolibc-test-wrapper.py new file mode 100755 index 00000000..046b7c42 --- /dev/null +++ b/scripts/llvm/test-support/picolibc-test-wrapper.py @@ -0,0 +1,138 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2023, Arm Limited and affiliates. + +# This is a wrapper script to run picolibc tests with QEMU. + +from run_qemu import run_qemu +import argparse +import pathlib +import sys + +# https://mesonbuild.com/Unit-tests.html#skipped-tests-and-hard-errors +EXIT_CODE_SKIP = 77 + +disabled_tests = [ + # compiler-rt does not properly support floating point exceptions and + # rounding modes for computations on types implemented in software + # https://github.com/picolibc/picolibc/pull/500 + # https://github.com/zephyrproject-rtos/sdk-ng/issues/838 + "picolibc_armv7m_soft_fpv4_sp_d16-build/test/math_errhandling", + "picolibc_armv7m_hard_fpv4_sp_d16-build/test/math_errhandling", + "picolibc_armv7r_hard_vfpv3xd-build/test/math_errhandling", + "picolibc_armv7r_hard_vfpv3xd_exn_rtti-build/test/math_errhandling", + "picolibc_armv8.1m.main_hard_fp_nomve-build/test/math_errhandling", + "picolibc_armv7m_soft_fpv4_sp_d16_exn_rtti-build/test/math_errhandling", + "picolibc_armv7m_hard_fpv4_sp_d16_exn_rtti-build/test/math_errhandling", + "picolibc_armv8.1m.main_hard_fp_nomve_exn_rtti-build/test/math_errhandling", + "picolibc_armv8.1m.main_hard_nofp_mve-build/test/fenv", + "picolibc_armv8.1m.main_hard_nofp_mve-build/test/math_errhandling", + "picolibc_armv8m.main_hard_fp-build/test/math_errhandling", + "picolibc_armv8.1m.main_hard_nofp_mve_exn_rtti-build/test/fenv", + "picolibc_armv8.1m.main_hard_nofp_mve_exn_rtti-build/test/math_errhandling", + "picolibc_armv8m.main_hard_fp_exn_rtti-build/test/math_errhandling", + "picolibc_rv32imafc_zicsr_zifencei_ilp32f-build/test/rounding-mode", + "picolibc_rv32imafc_zicsr_zifencei_ilp32f-build/test/math_errhandling", + "picolibc_rv32imafc_zicsr_zifencei_ilp32f-build/test/test-fma", + "picolibc_rv32imafc_zicsr_zifencei_ilp32f_exn_rtti-build/test/rounding-mode", + "picolibc_rv32imafc_zicsr_zifencei_ilp32f_exn_rtti-build/test/math_errhandling", + "picolibc_rv32imafc_zicsr_zifencei_ilp32f_exn_rtti-build/test/test-fma", + "picolibc_rv32imfc_zicsr_zifencei_ilp32f-build/test/rounding-mode", + "picolibc_rv32imfc_zicsr_zifencei_ilp32f-build/test/math_errhandling", + "picolibc_rv32imfc_zicsr_zifencei_ilp32f-build/test/test-fma", + "picolibc_rv32imfc_zicsr_zifencei_ilp32f_exn_rtti-build/test/rounding-mode", + "picolibc_rv32imfc_zicsr_zifencei_ilp32f_exn_rtti-build/test/math_errhandling", + "picolibc_rv32imfc_zicsr_zifencei_ilp32f_exn_rtti-build/test/test-fma", + "picolibc_rv32imafd_zicsr_zifencei_ilp32d-build/test/math_errhandling", + "picolibc_rv32imafd_zicsr_zifencei_ilp32d-build/test/test-fma", + "picolibc_rv32imafd_zicsr_zifencei_ilp32d_exn_rtti-build/test/math_errhandling", + "picolibc_rv32imafd_zicsr_zifencei_ilp32d_exn_rtti-build/test/test-fma", + "picolibc_rv32if_zicsr_zifencei_ilp32f-build/test/rounding-mode", + "picolibc_rv32if_zicsr_zifencei_ilp32f-build/test/math_errhandling", + "picolibc_rv32if_zicsr_zifencei_ilp32f-build/test/test-fma", + "picolibc_rv32if_zicsr_zifencei_ilp32f_exn_rtti-build/test/rounding-mode", + "picolibc_rv32if_zicsr_zifencei_ilp32f_exn_rtti-build/test/math_errhandling", + "picolibc_rv32if_zicsr_zifencei_ilp32f_exn_rtti-build/test/test-fma", + "picolibc_rv64imafdc_zicsr_zifencei_lp64d-build/test/math_errhandling", + "picolibc_rv64imafdc_zicsr_zifencei_lp64d-build/test/test-fma", + "picolibc_rv64imafdc_zicsr_zifencei_lp64d_exn_rtti-build/test/math_errhandling", + "picolibc_rv64imafdc_zicsr_zifencei_lp64d_exn_rtti-build/test/test-fma", + "picolibc_rv64imafd_zicsr_zifencei_lp64d-build/test/math_errhandling", + "picolibc_rv64imafd_zicsr_zifencei_lp64d-build/test/test-fma", + "picolibc_rv64imafd_zicsr_zifencei_lp64d_exn_rtti-build/test/math_errhandling", + "picolibc_rv64imafd_zicsr_zifencei_lp64d_exn_rtti-build/test/test-fma", + "picolibc_rv64imfc_zicsr_zifencei_lp64f-build/test/rounding-mode", + "picolibc_rv64imfc_zicsr_zifencei_lp64f-build/test/math_errhandling", + "picolibc_rv64imfc_zicsr_zifencei_lp64f-build/test/test-fma", + "picolibc_rv64imfc_zicsr_zifencei_lp64f_exn_rtti-build/test/rounding-mode", + "picolibc_rv64imfc_zicsr_zifencei_lp64f_exn_rtti-build/test/math_errhandling", + "picolibc_rv64imfc_zicsr_zifencei_lp64f_exn_rtti-build/test/test-fma", + "picolibc_rv64imfc_zicsr_zifencei_zba_zbb_zbc_zbs_lp64f-build/test/rounding-mode", + "picolibc_rv64imfc_zicsr_zifencei_zba_zbb_zbc_zbs_lp64f-build/test/math_errhandling", + "picolibc_rv64imfc_zicsr_zifencei_zba_zbb_zbc_zbs_lp64f-build/test/test-fma", + "picolibc_rv64imfc_zicsr_zifencei_zba_zbb_zbc_zbs_lp64f_exn_rtti-build/test/rounding-mode", + "picolibc_rv64imfc_zicsr_zifencei_zba_zbb_zbc_zbs_lp64f_exn_rtti-build/test/math_errhandling", + "picolibc_rv64imfc_zicsr_zifencei_zba_zbb_zbc_zbs_lp64f_exn_rtti-build/test/test-fma", +] + + +def is_disabled(image): + return any([image.endswith(t) for t in disabled_tests]) + + +def run(args): + if is_disabled(args.image): + return EXIT_CODE_SKIP + return run_qemu( + args.qemu_command, + args.qemu_machine, + args.qemu_cpu, + args.qemu_params.split(":") if args.qemu_params else [], + args.image, + ["program-name"] + args.arguments, + None, + pathlib.Path.cwd(), + args.verbose, + ) + + +def main(): + parser = argparse.ArgumentParser( + description="Run a single test using qemu" + ) + parser.add_argument( + "--qemu-command", required=True, help="qemu-system- path" + ) + parser.add_argument( + "--qemu-machine", + required=True, + help="name of the machine to pass to QEMU", + ) + parser.add_argument( + "--qemu-cpu", required=False, help="name of the cpu to pass to QEMU" + ) + parser.add_argument( + "--qemu-params", + required=False, + help='list of arguments to pass to qemu, separated with ":"', + ) + parser.add_argument( + "--verbose", + action="store_true", + help="Print verbose output. This may affect test result, as the output " + "will be added to the output of the test.", + ) + parser.add_argument("image", help="image file to execute") + parser.add_argument( + "arguments", + nargs=argparse.REMAINDER, + default=[], + help="optional arguments for the image", + ) + args = parser.parse_args() + ret_code = run(args) + sys.exit(ret_code) + + +if __name__ == "__main__": + main() diff --git a/scripts/llvm/test-support/run-picolibc-tests.py b/scripts/llvm/test-support/run-picolibc-tests.py new file mode 100755 index 00000000..8aa3b245 --- /dev/null +++ b/scripts/llvm/test-support/run-picolibc-tests.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2024, Arm Limited and affiliates. + +# This is a helper script to run the picolibc tests. +# +# This is just a glue code for cmake the script, not intended to be run +# manually. If you want to run the tests manually, using meson directly will +# provide you more options and is better documented: +# cd PICOLIBC_BUILD_DIR +# meson setup . PICOLIBC_SOURCE_DIR -Dtests=true --reconfigure +# meson test +# +# The tests for picolibc cannot be enabled at first invocation of meson, +# because compiler_rt is built after picolibc is built. If picolibc would be +# configured with tests enabled at before compiler_rt is built, the +# picolibc build would fail. This is why this script enables the tests just +# before picolibc is tested. +# +# Picolibc always puts all the test results into "picolibc" testsuite in the +# junit xml file. We have multiple variants of picolibc and so we add a +# classname to every test the tests are run. This has to be done even when the +# tests fail, while still returnning non-zero exit value, so that cmake detects +# failure. This would be hard to do from within the cmake script. + +import argparse +import sys +import re +import os.path +import subprocess + +help = "usage: run-picolibc-tests.py PICOLIBC_SOURCE_DIR PICOLIBC_BUILD_DIR" + + +def replace_classname(build_dir, classname): + xml_file_name = os.path.join(build_dir, "meson-logs", "testlog.junit.xml") + + with open(xml_file_name, "r") as f: + xml_file_data = f.read() + + xml_file_data = re.sub( + 'classname="picolibc"', + f'classname="picolibc.{classname}"', + xml_file_data, + ) + + with open(xml_file_name, "w") as f: + f.write(xml_file_data) + + +def run_tests(meson_command, source_dir, build_dir, variant): + + # meson<0.64.0 does not properly apply new configuration after + # "meson configure -Dtests=false" + # use "meson setup --reconfigure" as a workaround + subprocess.run( + [ + meson_command, + "setup", + ".", + source_dir, + "-Dtests=true", + "--reconfigure", + ], + cwd=build_dir, + check=True, + ) + + returncode = subprocess.run( + [meson_command, "test"], + cwd=build_dir, + ).returncode + + subprocess.run( + [meson_command, "configure", "-Dtests=false"], + cwd=build_dir, + check=True, + ) + + replace_classname(build_dir, variant) + + return returncode + + +def main(): + parser = argparse.ArgumentParser(description="Run picolibc tests") + parser.add_argument( + "--meson-command", required=True, default="meson", help="meson path" + ) + parser.add_argument( + "--picolibc-source-dir", + required=True, + help="path to picolibc sources", + ) + parser.add_argument( + "--picolibc-build-dir", + required=True, + help="path to picolibc build", + ) + parser.add_argument( + "--variant", + required=True, + help="name of the variant to be appended to the testsuite name", + ) + args = parser.parse_args() + ret_code = run_tests( + args.meson_command, + args.picolibc_source_dir, + args.picolibc_build_dir, + args.variant, + ) + sys.exit(ret_code) + + +if __name__ == "__main__": + main() diff --git a/scripts/llvm/test-support/run_qemu.py b/scripts/llvm/test-support/run_qemu.py new file mode 100755 index 00000000..0f72d890 --- /dev/null +++ b/scripts/llvm/test-support/run_qemu.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2023, Arm Limited and affiliates. + +import subprocess +import sys + + +def run_qemu( + qemu_command, + qemu_machine, + qemu_cpu, + qemu_extra_params, + image, + arguments, + timeout, + working_directory, + verbose, +): + """Execute the program using QEMU and return the subprocess return code.""" + qemu_params = ["-M", qemu_machine] + if qemu_cpu: + qemu_params += ["-cpu", qemu_cpu] + qemu_params += qemu_extra_params + + # Setup semihosting with chardev bound to stdio. + # This is needed to test semihosting functionality in picolibc. + qemu_params += ["-chardev", "stdio,mux=on,id=stdio0"] + semihosting_config = ["enable=on", "chardev=stdio0"] + [ + "arg=" + arg.replace(",", ",,") for arg in arguments + ] + qemu_params += ["-semihosting-config", ",".join(semihosting_config)] + + # Disable features we don't need and which could slow down the test or + # interfere with semihosting. + qemu_params += ["-monitor", "none", "-serial", "none", "-nographic"] + + # Load the image to machine's memory and set the PC. + # "virt" machine cannot be used with load, as QEMU will try to put + # device tree blob at start of RAM conflicting with our code + # https://www.qemu.org/docs/master/system/arm/virt.html#hardware-configuration-information-for-bare-metal-programming + if qemu_machine == "virt": + qemu_params += ["-kernel", image] + else: + qemu_params += ["-device", f"loader,file={image},cpu-num=0"] + + command = [qemu_command] + qemu_params + + if verbose: + print("running: {}".format(" ".join(command))) + + result = subprocess.run( + command, + stdout=subprocess.PIPE, + stderr=sys.stderr, + timeout=timeout, + cwd=working_directory, + check=False, + ) + sys.stdout.buffer.write(result.stdout) + return result.returncode diff --git a/scripts/llvm/test/CMakeLists.txt b/scripts/llvm/test/CMakeLists.txt new file mode 100644 index 00000000..36af7dad --- /dev/null +++ b/scripts/llvm/test/CMakeLists.txt @@ -0,0 +1,30 @@ +if(LLVM_ENABLE_BACKTRACES) + set(ENABLE_BACKTRACES 1) +endif() +llvm_canonicalize_cmake_booleans( + ENABLE_BACKTRACES +) + +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.py.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg.py + MAIN_CONFIG + ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py +) + +list(APPEND LLVM_TOOLCHAIN_TEST_DEPS + llvm-toolchain + FileCheck + count + not +) + +add_lit_testsuite(check-llvm-toolchain-lit + "Running Zephyr SDK LLVM regression tests" + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${LLVM_TOOLCHAIN_TEST_DEPS} +) + +add_lit_testsuites(llvm-toolchain-lit ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${LLVM_TOOLCHAIN_TEST_DEPS} +) diff --git a/scripts/llvm/test/lit.cfg.py b/scripts/llvm/test/lit.cfg.py new file mode 100644 index 00000000..7f840e47 --- /dev/null +++ b/scripts/llvm/test/lit.cfg.py @@ -0,0 +1,20 @@ +# -*- Python -*- + +import os + +import lit.formats + +from lit.llvm import llvm_config + +# Configuration file for the 'lit' test runner. + +config.name = 'Zephyr SDK LLVM' +config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell) +config.suffixes = ['.c', '.cpp', '.test'] +config.excludes = ['CMakeLists.txt'] +config.test_source_root = os.path.dirname(__file__) + +llvm_config.use_default_substitutions() +llvm_config.use_clang() + +config.environment["CLANG_NO_DEFAULT_CONFIG"] = "1" diff --git a/scripts/llvm/test/lit.site.cfg.py.in b/scripts/llvm/test/lit.site.cfg.py.in new file mode 100644 index 00000000..ab0a1e1f --- /dev/null +++ b/scripts/llvm/test/lit.site.cfg.py.in @@ -0,0 +1,19 @@ +@LIT_SITE_CFG_IN_HEADER@ + +config.llvm_src_root = "@LLVM_SOURCE_DIR@" +config.llvm_obj_root = "@LLVM_BINARY_DIR@" +config.llvm_tools_dir = lit_config.substitute("@LLVM_BINARY_DIR@/bin") +config.llvm_libs_dir = lit_config.substitute("@LLVM_BINARY_DIR@/lib") +config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@" +config.enable_backtrace = @ENABLE_BACKTRACES@ +config.errc_messages = "@LLVM_LIT_ERRC_MESSAGES@" +config.host_triple = "@LLVM_HOST_TRIPLE@" +config.target_triple = "@LLVM_DEFAULT_TARGET_TRIPLE@" +config.python_executable = "@Python3_EXECUTABLE@" +config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" + +import lit.llvm +lit.llvm.initialize(lit_config, config) + +# Let the main config do the real work. +lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg.py") diff --git a/scripts/llvm/test/multilib/aarch64.test b/scripts/llvm/test/multilib/aarch64.test new file mode 100644 index 00000000..f062fc2a --- /dev/null +++ b/scripts/llvm/test/multilib/aarch64.test @@ -0,0 +1,3 @@ +# RUN: %clang -print-multi-directory --target=aarch64-none-elf | FileCheck %s +# CHECK: aarch64-none-elf/aarch64a_exn_rtti{{$}} +# CHECK-EMPTY: diff --git a/scripts/llvm/test/multilib/armv4t.test b/scripts/llvm/test/multilib/armv4t.test new file mode 100644 index 00000000..9d1020b9 --- /dev/null +++ b/scripts/llvm/test/multilib/armv4t.test @@ -0,0 +1,3 @@ +# RUN: %clang -print-multi-directory --target=arm-none-eabi -mfpu=none | FileCheck %s +# CHECK: arm-none-eabi/armv4t_exn_rtti{{$}} +# CHECK-EMPTY: diff --git a/scripts/llvm/test/multilib/armv5e.test b/scripts/llvm/test/multilib/armv5e.test new file mode 100644 index 00000000..8525f0b0 --- /dev/null +++ b/scripts/llvm/test/multilib/armv5e.test @@ -0,0 +1,3 @@ +# RUN: %clang -print-multi-directory --target=armv5e-none-eabi -mfpu=none | FileCheck %s +# CHECK: arm-none-eabi/armv5te_exn_rtti{{$}} +# CHECK-EMPTY: diff --git a/scripts/llvm/test/multilib/armv6m.test b/scripts/llvm/test/multilib/armv6m.test new file mode 100644 index 00000000..e9f86699 --- /dev/null +++ b/scripts/llvm/test/multilib/armv6m.test @@ -0,0 +1,3 @@ +# RUN: %clang -print-multi-directory --target=armv6m-none-eabi -mfpu=none | FileCheck %s +# CHECK: arm-none-eabi/armv6m_soft_nofp_exn_rtti{{$}} +# CHECK-EMPTY: diff --git a/scripts/llvm/test/multilib/armv7a.test b/scripts/llvm/test/multilib/armv7a.test new file mode 100644 index 00000000..3d246b8c --- /dev/null +++ b/scripts/llvm/test/multilib/armv7a.test @@ -0,0 +1,43 @@ +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=none | FileCheck %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=none -marm | FileCheck %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=none -mthumb| FileCheck %s +# RUN: %clang -print-multi-directory --target=armv7ve-none-eabi -mfpu=none | FileCheck %s +# RUN: %clang -print-multi-directory --target=armv7ve-none-eabi -mfpu=none -marm | FileCheck %s +# RUN: %clang -print-multi-directory --target=armv7ve-none-eabi -mfpu=none -mthumb| FileCheck %s +# CHECK: arm-none-eabi/armv7a_soft_nofp_exn_rtti{{$}} +# CHECK-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=vfpv3-d16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=neon-vfpv3 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=vfpv3 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=vfpv3-d16-fp16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=vfpv3-fp16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=vfpv4-d16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=vfpv4 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=neon-fp16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=neon-vfpv4 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=vfpv3-d16 -marm | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabihf -mfpu=vfpv3-d16 -mthumb | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7ve-none-eabihf -mfpu=vfpv3-d16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7ve-none-eabihf -mfpu=vfpv3-d16 -mthumb | FileCheck --check-prefix=VFPV3 %s +# VFPV3: arm-none-eabi/armv7a_hard_vfpv3_d16_exn_rtti{{$}} +# VFPV3-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=vfpv3-d16 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=neon-vfpv3 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=vfpv3 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=vfpv3-d16-fp16 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=vfpv3-fp16 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=vfpv4-d16 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=vfpv4 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=neon-fp16 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=neon-vfpv4 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=vfpv3-d16 -marm -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=vfpv3-d16 -mthumb -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# SOFT-VFPV3: arm-none-eabi/armv7a_soft_vfpv3_d16_exn_rtti{{$}} +# SOFT-VFPV3-EMPTY: + +# We have no valid variant for this configuration, yet. +# RUN: %clang -print-multi-directory --target=armv7a-none-eabi -mfpu=vfpv3xd 2>&1 | FileCheck --check-prefix=NOT-FOUND %s + +# NOT-FOUND: warning: no multilib found matching flags diff --git a/scripts/llvm/test/multilib/armv7m.test b/scripts/llvm/test/multilib/armv7m.test new file mode 100644 index 00000000..6d98aaad --- /dev/null +++ b/scripts/llvm/test/multilib/armv7m.test @@ -0,0 +1,28 @@ +# RUN: %clang -print-multi-directory --target=armv7m-none-eabi -mfpu=none | FileCheck %s --check-prefix=NONE +# RUN: %clang -print-multi-directory --target=armv7m-none-eabi -mfpu=none -mfloat-abi=softfp | FileCheck %s --check-prefix=NONE +# RUN: %clang -print-multi-directory --target=armv7em-none-eabi -mfpu=none -mfloat-abi=softfp | FileCheck %s --check-prefix=NONE +# NONE: arm-none-eabi/armv7m_soft_nofp_exn_rtti{{$}} +# NONE-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv7m-none-eabi -mfpu=fpv4-sp-d16 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-FPV4 %s +# RUN: %clang -print-multi-directory --target=armv7m-none-eabi -mfpu=fpv5-d16 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-FPV4 %s +# RUN: %clang -print-multi-directory --target=armv7em-none-eabi -mfpu=fpv4-sp-d16 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-FPV4 %s +# RUN: %clang -print-multi-directory --target=armv7em-none-eabi -mfpu=fpv5-d16 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-FPV4 %s +# SOFT-FPV4: arm-none-eabi/armv7m_soft_fpv4_sp_d16_exn_rtti{{$}} +# SOFT-FPV4-EMPTY: +# +# RUN: %clang -print-multi-directory --target=armv7m-none-eabihf -mfpu=fpv4-sp-d16 | FileCheck --check-prefix=FPV4 %s +# RUN: %clang -print-multi-directory --target=armv7em-none-eabihf -mfpu=fpv4-sp-d16 | FileCheck --check-prefix=FPV4 %s +# FPV4: arm-none-eabi/armv7m_hard_fpv4_sp_d16_exn_rtti{{$}} +# FPV4-EMPTY: +# +# RUN: %clang -print-multi-directory --target=armv7m-none-eabihf -mfpu=fpv5-d16 | FileCheck --check-prefix=FPV5 %s +# RUN: %clang -print-multi-directory --target=armv7em-none-eabihf -mfpu=fpv5-d16 | FileCheck --check-prefix=FPV5 %s +# FPV5: arm-none-eabi/armv7m_hard_fpv5_d16_exn_rtti{{$}} +# FPV5-EMPTY: + +# %clang -print-multi-directory --target=arm-none-eabi -mcpu=cortex-m3 | FileCheck %s --check-prefix=NONE +# %clang -print-multi-directory --target=arm-none-eabi -mcpu=cortex-m4 | FileCheck %s --check-prefix=SOFT-FPV4 +# %clang -print-multi-directory --target=arm-none-eabihf -mcpu=cortex-m4 | FileCheck %s --check-prefix=FPV4 +# %clang -print-multi-directory --target=arm-none-eabi -mcpu=cortex-m7 | FileCheck %s --check-prefix=SOFT-FPV4 +# %clang -print-multi-directory --target=arm-none-eabihf -mcpu=cortex-m7 | FileCheck %s --check-prefix=FPV4 diff --git a/scripts/llvm/test/multilib/armv7r.test b/scripts/llvm/test/multilib/armv7r.test new file mode 100644 index 00000000..a529b544 --- /dev/null +++ b/scripts/llvm/test/multilib/armv7r.test @@ -0,0 +1,23 @@ +# RUN: %clang -print-multi-directory --target=armv7r-none-eabi -mfpu=none | FileCheck %s +# RUN: %clang -print-multi-directory --target=armv7r-none-eabi -mfpu=none -marm | FileCheck %s +# RUN: %clang -print-multi-directory --target=armv7r-none-eabi -mfpu=none -mthumb | FileCheck %s +# CHECK: arm-none-eabi/armv7r_soft_nofp_exn_rtti{{$}} +# CHECK-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv7r-none-eabihf -mfpu=vfpv3-d16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7r-none-eabihf -mfpu=vfpv3-d16 -marm | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7r-none-eabihf -mfpu=vfpv3-d16 -mthumb | FileCheck --check-prefix=VFPV3 %s +# VFPV3: arm-none-eabi/armv7r_hard_vfpv3_d16_exn_rtti{{$}} +# VFPV3-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv7r-none-eabihf -mfpu=vfpv3-d16 -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7r-none-eabihf -mfpu=vfpv3-d16 -marm -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv7r-none-eabihf -mfpu=vfpv3-d16 -mthumb -mfloat-abi=softfp | FileCheck --check-prefix=SOFT-VFPV3 %s +# SOFT-VFPV3: arm-none-eabi/armv7r_soft_vfpv3_d16_exn_rtti{{$}} +# SOFT-VFPV3-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv7r-none-eabihf -mfpu=vfpv3xd | FileCheck --check-prefix=VFPV3XD %s +# RUN: %clang -print-multi-directory --target=armv7r-none-eabihf -mfpu=vfpv3xd -marm | FileCheck --check-prefix=VFPV3XD %s +# RUN: %clang -print-multi-directory --target=armv7r-none-eabihf -mfpu=vfpv3xd -mthumb | FileCheck --check-prefix=VFPV3XD %s +# VFPV3XD: arm-none-eabi/armv7r_hard_vfpv3xd_exn_rtti{{$}} +# VFPV3XD-EMPTY: diff --git a/scripts/llvm/test/multilib/armv8.1m.main.test b/scripts/llvm/test/multilib/armv8.1m.main.test new file mode 100644 index 00000000..b49d2380 --- /dev/null +++ b/scripts/llvm/test/multilib/armv8.1m.main.test @@ -0,0 +1,33 @@ +# RUN: %clang -print-multi-directory --target=armv8.1m.main-none-eabi -mfpu=none | FileCheck %s +# CHECK: arm-none-eabi/armv8.1m.main_soft_nofp_nomve_exn_rtti{{$}} +# CHECK-EMPTY: + +# If both MVE and FPU are present, FPU variant is selected. This is because, +# the nofp variant is only considered, when "-mfpu=none" is inferred from user +# commandline. + +# RUN: %clang -print-multi-directory --target=armv8.1m.main-none-eabihf -march=armv8.1m.main -mfpu=fp-armv8-fullfp16-sp-d16 | FileCheck --check-prefix=HARD_FP %s +# RUN: %clang -print-multi-directory --target=armv8.1m.main-none-eabihf -march=armv8.1m.main+mve -mfpu=fp-armv8-fullfp16-sp-d16 | FileCheck --check-prefix=HARD_FP %s +# HARD_FP: arm-none-eabi/armv8.1m.main_hard_fp_nomve_exn_rtti{{$}} +# HARD_FP-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv8.1m.main-none-eabihf -march=armv8.1m.main -mfpu=fp-armv8-fullfp16-d16 | FileCheck --check-prefix=HARD_FPDP %s +# RUN: %clang -print-multi-directory --target=armv8.1m.main-none-eabihf -march=armv8.1m.main+mve -mfpu=fp-armv8-fullfp16-d16 | FileCheck --check-prefix=HARD_FPDP %s +# HARD_FPDP: arm-none-eabi/armv8.1m.main_hard_fpdp_nomve_exn_rtti{{$}} +# HARD_FPDP-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv8.1m.main-none-eabihf -march=armv8.1m.main+mve -mfpu=none | FileCheck --check-prefix=MVE %s +# MVE: arm-none-eabi/armv8.1m.main_hard_nofp_mve_exn_rtti{{$}} +# MVE-EMPTY: + +# TODO: We need to find a way to make this fail. For now it fallbacks to +# arm-none-eabi/armv8.1m.main_soft_nofp, which will not initilize the +# coprocessor nor will save/restore its registers in setjmp/longjmp. +# DONT-RUN-YET: %clang -print-multi-directory --target=armv8.1m.main-none-eabi -march=armv8.1m.main+mve -mfpu=none | FileCheck --check-prefix=SOFTFP_MVE %s +# SOFTFP_MVE: ? +# SOFTFP_MVE-EMPTY: + +# RUN: %clang -print-multi-flags-experimental --target=arm-none-eabihf -mcpu=cortex-m55 | FileCheck --check-prefix=CORTEXM55 %s +# CORTEXM55: -march=thumbv8.1m.main+fp16 +# CORTEXM55: -march=thumbv8.1m.main+lob +# CORTEXM55: -march=thumbv8.1m.main+mve.fp diff --git a/scripts/llvm/test/multilib/armv8a.test b/scripts/llvm/test/multilib/armv8a.test new file mode 100644 index 00000000..d74f7104 --- /dev/null +++ b/scripts/llvm/test/multilib/armv8a.test @@ -0,0 +1,19 @@ +# RUN: %clang -print-multi-directory --target=armv8a-none-eabi -mfpu=none | FileCheck %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabi -mfpu=none -marm | FileCheck %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabi -mfpu=none -mthumb | FileCheck %s +# CHECK: arm-none-eabi/armv7a_soft_nofp_exn_rtti{{$}} +# CHECK-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=vfpv3-d16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=neon-vfpv3 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=vfpv3 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=vfpv3-d16-fp16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=vfpv3-fp16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=vfpv4-d16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=vfpv4 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=neon-fp16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=neon-vfpv4 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=vfpv3-d16 -marm | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8a-none-eabihf -mfpu=vfpv3-d16 -mthumb | FileCheck --check-prefix=VFPV3 %s +# VFPV3: arm-none-eabi/armv7a_hard_vfpv3_d16_exn_rtti{{$}} +# VFPV3-EMPTY: diff --git a/scripts/llvm/test/multilib/armv8m.main.test b/scripts/llvm/test/multilib/armv8m.main.test new file mode 100644 index 00000000..053c86c4 --- /dev/null +++ b/scripts/llvm/test/multilib/armv8m.main.test @@ -0,0 +1,12 @@ +# RUN: %clang -print-multi-directory --target=armv8m.main-none-eabi -mfpu=none | FileCheck %s +# CHECK: arm-none-eabi/armv8m.main_soft_nofp_exn_rtti{{$}} +# CHECK-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv8m.main-none-eabihf -mfpu=fpv5-sp-d16 | FileCheck --check-prefix=HARD %s +# HARD: arm-none-eabi/armv8m.main_hard_fp_exn_rtti{{$}} +# HARD-EMPTY: + +# Fallback to armv7m +# RUN: %clang -print-multi-directory --target=armv8m.main-none-eabi -mfpu=fpv5-sp-d16 | FileCheck --check-prefix=SOFTFP %s +# SOFTFP: arm-none-eabi/armv7m_soft_fpv4_sp_d16_exn_rtti{{$}} +# SOFTFP-EMPTY: diff --git a/scripts/llvm/test/multilib/armv8r.test b/scripts/llvm/test/multilib/armv8r.test new file mode 100644 index 00000000..e9c6a5ba --- /dev/null +++ b/scripts/llvm/test/multilib/armv8r.test @@ -0,0 +1,19 @@ +# RUN: %clang -print-multi-directory --target=armv8r-none-eabi -mfpu=none | FileCheck %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabi -mfpu=none -marm | FileCheck %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabi -mfpu=none -mthumb | FileCheck %s +# CHECK: arm-none-eabi/armv7r_soft_nofp_exn_rtti{{$}} +# CHECK-EMPTY: + +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=vfpv3-d16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=neon-vfpv3 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=vfpv3 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=vfpv3-d16-fp16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=vfpv3-fp16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=vfpv4-d16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=vfpv4 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=neon-fp16 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=neon-vfpv4 | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=vfpv3-d16 -marm | FileCheck --check-prefix=VFPV3 %s +# RUN: %clang -print-multi-directory --target=armv8r-none-eabihf -mfpu=vfpv3-d16 -mthumb | FileCheck --check-prefix=VFPV3 %s +# VFPV3: arm-none-eabi/armv7r_hard_vfpv3_d16_exn_rtti{{$}} +# VFPV3-EMPTY: diff --git a/scripts/llvm/test/multilib/fpus.test b/scripts/llvm/test/multilib/fpus.test new file mode 100644 index 00000000..ecd04b77 --- /dev/null +++ b/scripts/llvm/test/multilib/fpus.test @@ -0,0 +1,22 @@ +# RUN: %clang -print-multi-flags-experimental --target=arm-none-eabihf -march=armv7m -mfpu=fpv5-d16 | FileCheck --check-prefixes=VFPV4-D16,FPV4-SP-D16,FPV5-SP-D16 %s + +# RUN: %clang -print-multi-flags-experimental --target=arm-none-eabihf -march=armv7m -mfpu=fpv5-sp-d16 | FileCheck --check-prefix=FPV4-SP-D16 %s + +# RUN: %clang -print-multi-flags-experimental --target=arm-none-eabihf -march=armv7m -mfpu=vfpv4-d16 | FileCheck --check-prefix=FPV4-SP-D16 %s + +# RUN: %clang -print-multi-flags-experimental --target=arm-none-eabihf -march=armv7m -mfpu=fp-armv8-fullfp16-d16 | FileCheck --check-prefix=FP-ARMV8-FULLFP16-SP-D16 %s + +# RUN: %clang -print-multi-flags-experimental --target=arm-none-eabihf -march=armv8 -mfpu=crypto-neon-fp-armv8 | FileCheck --check-prefixes=NEON-FP-ARMV8,NEON-VFPV4,FP-ARMV8 %s +# RUN: %clang -print-multi-flags-experimental --target=arm-none-eabihf -march=armv8 -mfpu=neon-fp-armv8 | FileCheck --check-prefixes=NEON-VFPV4,FP-ARMV8 %s + +# RUN: %clang -print-multi-flags-experimental --target=arm-none-eabihf -march=armv8 -mfpu=vfpv3-d16 | FileCheck --check-prefixes=VFPV2,VFPV3XD %s + +# FP-ARMV8-FULLFP16-SP-D16: -mfpu=fp-armv8-fullfp16-sp-d16{{$}} +# FP-ARMV8: -mfpu=fp-armv8{{$}} +# FPV4-SP-D16: -mfpu=fpv4-sp-d16{{$}} +# FPV5-SP-D16: -mfpu=fpv5-sp-d16{{$}} +# NEON-FP-ARMV8: -mfpu=neon-fp-armv8{{$}} +# NEON-VFPV4: -mfpu=neon-vfpv4{{$}} +# VFPV2: -mfpu=vfpv2{{$}} +# VFPV3XD: -mfpu=vfpv3xd{{$}} +# VFPV4-D16: -mfpu=vfpv4-d16{{$}} diff --git a/scripts/llvm/test/multilib/rv32e.test b/scripts/llvm/test/multilib/rv32e.test new file mode 100644 index 00000000..f09c3ba5 --- /dev/null +++ b/scripts/llvm/test/multilib/rv32e.test @@ -0,0 +1,29 @@ +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32e_zicsr_zifencei -mabi=ilp32e | FileCheck %s --check-prefix=RV32E_ZICSR_ZIFENCEI_ILP32E +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32ea_zicsr_zifencei -mabi=ilp32e | FileCheck %s --check-prefix=RV32E_ZICSR_ZIFENCEI_ILP32E +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32eac_zicsr_zifencei -mabi=ilp32e | FileCheck %s --check-prefix=RV32E_ZICSR_ZIFENCEI_ILP32E +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32ec_zicsr_zifencei -mabi=ilp32e | FileCheck %s --check-prefix=RV32E_ZICSR_ZIFENCEI_ILP32E +# RV32E_ZICSR_ZIFENCEI_ILP32E: riscv32-none-elf/rv32e_zicsr_zifencei_ilp32e_exn_rtti{{$}} +# RV32E_ZICSR_ZIFENCEI_ILP32E-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32em_zicsr_zifencei -mabi=ilp32e | FileCheck %s --check-prefix=RV32EM_ZICSR_ZIFENCEI_ILP32E +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32ema_zicsr_zifencei -mabi=ilp32e | FileCheck %s --check-prefix=RV32EM_ZICSR_ZIFENCEI_ILP32E +# RV32EM_ZICSR_ZIFENCEI_ILP32E: riscv32-none-elf/rv32em_zicsr_zifencei_ilp32e_exn_rtti{{$}} +# RV32EM_ZICSR_ZIFENCEI_ILP32E-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32emc_zicsr_zifencei -mabi=ilp32e | FileCheck %s --check-prefix=RV32EMC_ZICSR_ZIFENCEI_ILP32E +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32emac_zicsr_zifencei -mabi=ilp32e | FileCheck %s --check-prefix=RV32EMC_ZICSR_ZIFENCEI_ILP32E +# RV32EMC_ZICSR_ZIFENCEI_ILP32E: riscv32-none-elf/rv32emc_zicsr_zifencei_ilp32e_exn_rtti{{$}} +# RV32EMC_ZICSR_ZIFENCEI_ILP32E-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32emc_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=ilp32e | FileCheck %s --check-prefix=RV32EMC_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_ILP32E +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32emac_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=ilp32e | FileCheck %s --check-prefix=RV32EMC_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_ILP32E +# RV32EMC_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_ILP32E: riscv32-none-elf/rv32emc_zicsr_zifencei_zba_zbb_zbc_zbs_ilp32e_exn_rtti{{$}} +# RV32EMC_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_ILP32E-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32emc_zicsr -mabi=ilp32e | FileCheck %s --check-prefix=RV32EMC_ZICSR_ILP32E +# RV32EMC_ZICSR_ILP32E: riscv32-none-elf/rv32emc_zicsr_ilp32e_exn_rtti{{$}} +# RV32EMC_ZICSR_ILP32E-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32emc_zicsr_zba_zbb_zbc_zbs -mabi=ilp32e | FileCheck %s --check-prefix=RV32EMC_ZICSR_ZBA_ZBB_ZBC_ZBS_ILP32E +# RV32EMC_ZICSR_ZBA_ZBB_ZBC_ZBS_ILP32E: riscv32-none-elf/rv32emc_zicsr_zba_zbb_zbc_zbs_ilp32e_exn_rtti{{$}} +# RV32EMC_ZICSR_ZBA_ZBB_ZBC_ZBS_ILP32E-EMPTY: diff --git a/scripts/llvm/test/multilib/rv32i.test b/scripts/llvm/test/multilib/rv32i.test new file mode 100644 index 00000000..40149866 --- /dev/null +++ b/scripts/llvm/test/multilib/rv32i.test @@ -0,0 +1,44 @@ +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32i_zicsr_zifencei -mabi=ilp32 | FileCheck %s --check-prefix=RV32I_ZICSR_ZIFENCEI_ILP32 +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32ia_zicsr_zifencei -mabi=ilp32 | FileCheck %s --check-prefix=RV32I_ZICSR_ZIFENCEI_ILP32 +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32iac_zicsr_zifencei -mabi=ilp32 | FileCheck %s --check-prefix=RV32I_ZICSR_ZIFENCEI_ILP32 +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32iafc_zicsr_zifencei -mabi=ilp32 | FileCheck %s --check-prefix=RV32I_ZICSR_ZIFENCEI_ILP32 +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32ic_zicsr_zifencei -mabi=ilp32 | FileCheck %s --check-prefix=RV32I_ZICSR_ZIFENCEI_ILP32 +# RV32I_ZICSR_ZIFENCEI_ILP32: riscv32-none-elf/rv32i_zicsr_zifencei_ilp32_exn_rtti{{$}} +# RV32I_ZICSR_ZIFENCEI_ILP32-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32im_zicsr_zifencei -mabi=ilp32 | FileCheck %s --check-prefix=RV32IM_ZICSR_ZIFENCEI_ILP32 +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32ima_zicsr_zifencei -mabi=ilp32 | FileCheck %s --check-prefix=RV32IM_ZICSR_ZIFENCEI_ILP32 +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32imc_zicsr_zifencei -mabi=ilp32 | FileCheck %s --check-prefix=RV32IM_ZICSR_ZIFENCEI_ILP32 +# RV32IM_ZICSR_ZIFENCEI_ILP32: riscv32-none-elf/rv32im_zicsr_zifencei_ilp32_exn_rtti{{$}} +# RV32IM_ZICSR_ZIFENCEI_ILP32-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32im_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=ilp32 | FileCheck %s --check-prefix=RV32IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_ILP32 +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32ima_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=ilp32 | FileCheck %s --check-prefix=RV32IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_ILP32 +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32imac_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=ilp32 | FileCheck %s --check-prefix=RV32IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_ILP32 +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32imc_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=ilp32 | FileCheck %s --check-prefix=RV32IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_ILP32 +# RV32IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_ILP32: riscv32-none-elf/rv32im_zicsr_zifencei_zba_zbb_zbc_zbs_ilp32_exn_rtti{{$}} +# RV32IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_ILP32-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32imac_zicsr_zifencei -mabi=ilp32 | FileCheck %s --check-prefix=RV32IMAC_ZICSR_ZIFENCEI_ILP32 +# RV32IMAC_ZICSR_ZIFENCEI_ILP32: riscv32-none-elf/rv32imac_zicsr_zifencei_ilp32_exn_rtti{{$}} +# RV32IMAC_ZICSR_ZIFENCEI_ILP32-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32imafc_zicsr_zifencei -mabi=ilp32f | FileCheck %s --check-prefix=RV32IMAFC_ZICSR_ZIFENCEI_ILP32F +# RV32IMAFC_ZICSR_ZIFENCEI_ILP32F: riscv32-none-elf/rv32imafc_zicsr_zifencei_ilp32f_exn_rtti{{$}} +# RV32IMAFC_ZICSR_ZIFENCEI_ILP32F-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32imfc_zicsr_zifencei -mabi=ilp32f | FileCheck %s --check-prefix=RV32IMFC_ZICSR_ZIFENCEI_ILP32F +# RV32IMFC_ZICSR_ZIFENCEI_ILP32F: riscv32-none-elf/rv32imfc_zicsr_zifencei_ilp32f_exn_rtti{{$}} +# RV32IMFC_ZICSR_ZIFENCEI_ILP32F-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32imafd_zicsr_zifencei -mabi=ilp32d | FileCheck %s --check-prefix=RV32IMAFD_ZICSR_ZIFENCEI_ILP32D +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32imafdc_zicsr_zifencei -mabi=ilp32d | FileCheck %s --check-prefix=RV32IMAFD_ZICSR_ZIFENCEI_ILP32D +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32g -mabi=ilp32d | FileCheck %s --check-prefix=RV32IMAFD_ZICSR_ZIFENCEI_ILP32D +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32gc -mabi=ilp32d | FileCheck %s --check-prefix=RV32IMAFD_ZICSR_ZIFENCEI_ILP32D +# RV32IMAFD_ZICSR_ZIFENCEI_ILP32D: riscv32-none-elf/rv32imafd_zicsr_zifencei_ilp32d_exn_rtti{{$}} +# RV32IMAFD_ZICSR_ZIFENCEI_ILP32D-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32if_zicsr_zifencei -mabi=ilp32f | FileCheck %s --check-prefix=RV32IF_ZICSR_ZIFENCEI_ILP32F +# RUN: %clang -print-multi-directory --target=riscv32-none-elf -march=rv32iafc_zicsr_zifencei -mabi=ilp32f | FileCheck %s --check-prefix=RV32IF_ZICSR_ZIFENCEI_ILP32F +# RV32IF_ZICSR_ZIFENCEI_ILP32F: riscv32-none-elf/rv32if_zicsr_zifencei_ilp32f_exn_rtti{{$}} +# RV32IF_ZICSR_ZIFENCEI_ILP32F-EMPTY: diff --git a/scripts/llvm/test/multilib/rv64i.test b/scripts/llvm/test/multilib/rv64i.test new file mode 100644 index 00000000..be3d6334 --- /dev/null +++ b/scripts/llvm/test/multilib/rv64i.test @@ -0,0 +1,44 @@ +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64i_zicsr_zifencei -mabi=lp64 | FileCheck %s --check-prefix=RV64I_ZICSR_ZIFENCEI_LP64 +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64ia_zicsr_zifencei -mabi=lp64 | FileCheck %s --check-prefix=RV64I_ZICSR_ZIFENCEI_LP64 +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64iac_zicsr_zifencei -mabi=lp64 | FileCheck %s --check-prefix=RV64I_ZICSR_ZIFENCEI_LP64 +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64ic_zicsr_zifencei -mabi=lp64 | FileCheck %s --check-prefix=RV64I_ZICSR_ZIFENCEI_LP64 +# RV64I_ZICSR_ZIFENCEI_LP64: riscv64-none-elf/rv64i_zicsr_zifencei_lp64_exn_rtti{{$}} +# RV64I_ZICSR_ZIFENCEI_LP64-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64im_zicsr_zifencei -mabi=lp64 | FileCheck %s --check-prefix=RV64IM_ZICSR_ZIFENCEI_LP64 +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64ima_zicsr_zifencei -mabi=lp64 | FileCheck %s --check-prefix=RV64IM_ZICSR_ZIFENCEI_LP64 +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64imc_zicsr_zifencei -mabi=lp64 | FileCheck %s --check-prefix=RV64IM_ZICSR_ZIFENCEI_LP64 +# RV64IM_ZICSR_ZIFENCEI_LP64: riscv64-none-elf/rv64im_zicsr_zifencei_lp64_exn_rtti{{$}} +# RV64IM_ZICSR_ZIFENCEI_LP64-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64im_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=lp64 | FileCheck %s --check-prefix=RV64IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64 +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64ima_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=lp64 | FileCheck %s --check-prefix=RV64IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64 +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64imc_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=lp64 | FileCheck %s --check-prefix=RV64IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64 +# RV64IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64: riscv64-none-elf/rv64im_zicsr_zifencei_zba_zbb_zbc_zbs_lp64_exn_rtti{{$}} +# RV64IM_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64imac_zicsr_zifencei -mabi=lp64 | FileCheck %s --check-prefix=RV64IMAC_ZICSR_ZIFENCEI_LP64 +# RV64IMAC_ZICSR_ZIFENCEI_LP64: riscv64-none-elf/rv64imac_zicsr_zifencei_lp64_exn_rtti{{$}} +# RV64IMAC_ZICSR_ZIFENCEI_LP64-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64imac_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=lp64 | FileCheck %s --check-prefix=RV64IMAC_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64 +# RV64IMAC_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64: riscv64-none-elf/rv64imac_zicsr_zifencei_zba_zbb_zbc_zbs_lp64_exn_rtti{{$}} +# RV64IMAC_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64imafdc_zicsr_zifencei -mabi=lp64d | FileCheck %s --check-prefix=RV64IMAFDC_ZICSR_ZIFENCEI_LP64D +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64gc -mabi=lp64d | FileCheck %s --check-prefix=RV64IMAFDC_ZICSR_ZIFENCEI_LP64D +# RV64IMAFDC_ZICSR_ZIFENCEI_LP64D: riscv64-none-elf/rv64imafdc_zicsr_zifencei_lp64d_exn_rtti{{$}} +# RV64IMAFDC_ZICSR_ZIFENCEI_LP64D-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64imafd_zicsr_zifencei -mabi=lp64d | FileCheck %s --check-prefix=RV64IMAFD_ZICSR_ZIFENCEI_LP64D +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64g -mabi=lp64d | FileCheck %s --check-prefix=RV64IMAFD_ZICSR_ZIFENCEI_LP64D +# RV64IMAFD_ZICSR_ZIFENCEI_LP64D: riscv64-none-elf/rv64imafd_zicsr_zifencei_lp64d_exn_rtti{{$}} +# RV64IMAFD_ZICSR_ZIFENCEI_LP64D-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64imfc_zicsr_zifencei -mabi=lp64f | FileCheck %s --check-prefix=RV64IMFC_ZICSR_ZIFENCEI_LP64F +# RV64IMFC_ZICSR_ZIFENCEI_LP64F: riscv64-none-elf/rv64imfc_zicsr_zifencei_lp64f_exn_rtti{{$}} +# RV64IMFC_ZICSR_ZIFENCEI_LP64F-EMPTY: + +# RUN: %clang -print-multi-directory --target=riscv64-none-elf -march=rv64imfc_zicsr_zifencei_zba_zbb_zbc_zbs -mabi=lp64f | FileCheck %s --check-prefix=RV64IMFC_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64F +# RV64IMFC_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64F: riscv64-none-elf/rv64imfc_zicsr_zifencei_zba_zbb_zbc_zbs_lp64f_exn_rtti{{$}} +# RV64IMFC_ZICSR_ZIFENCEI_ZBA_ZBB_ZBC_ZBS_LP64F-EMPTY: diff --git a/scripts/template_setup_posix b/scripts/template_setup_posix index 2329d33c..d680bf85 100644 --- a/scripts/template_setup_posix +++ b/scripts/template_setup_posix @@ -48,11 +48,11 @@ check_command() fi } -# Check if the current installation is a full SDK with all toolchains -check_full_sdk() +# Check if the current installation is a full SDK with all GNU toolchains +check_full_gnu_sdk() { - for toolchain in ${toolchains[@]}; do - if [ ! -d "${toolchain}" ]; then + for toolchain in ${gnu_toolchains[@]}; do + if [ ! -d "gnu/${toolchain}" ]; then return 1 fi done @@ -63,16 +63,17 @@ check_full_sdk() # Display script usage usage() { - echo "Usage: $(basename $0) [-t ] [-h] [-c]" + echo "Usage: $(basename $0) [-t ] [-h] [-c]" echo - echo " -t Install specified toolchain" - echo " all Install all toolchains" - echo " -h Install host tools" - echo " -c Register Zephyr SDK CMake package" + echo " -t Install specified GNU toolchain" + echo " all Install all GNU toolchains" + echo " -l Install LLVM toolchain" + echo " -h Install host tools" + echo " -c Register Zephyr SDK CMake package" echo - echo "Supported Toolchains:" + echo "Supported GNU Toolchains:" echo - for toolchain in ${toolchains[@]}; do + for toolchain in ${gnu_toolchains[@]}; do echo " ${toolchain}" done echo @@ -88,21 +89,28 @@ user_prompt() echo "distribution bundle archive." echo - # Toolchains - check_full_sdk - if [ $? != 0 ]; then - ask_yn "Install toolchains for all targets" - if [ $? == 0 ]; then - inst_toolchains=(${toolchains[*]}) - else - for toolchain in ${toolchains[@]}; do - if [ ! -d "${toolchain}" ]; then - ask_yn "Install '${toolchain}' toolchain" && inst_toolchains+=("${toolchain}") - fi - done + # GNU Toolchains + ask_yn "Install GNU toolchain" + if [ $? == 0 ]; then + do_gnu_toolchain="y" + check_full_gnu_sdk + if [ $? != 0 ]; then + ask_yn "Install GNU toolchains for all targets" + if [ $? == 0 ]; then + inst_gnu_toolchains=(${gnu_toolchains[*]}) + else + for toolchain in ${gnu_toolchains[@]}; do + if [ ! -d "gnu/${toolchain}" ]; then + ask_yn "Install '${toolchain}' GNU toolchain" && inst_gnu_toolchains+=("${toolchain}") + fi + done + fi fi fi + # LLVM Toolchain + ask_yn "Install LLVM toolchain" && do_llvm_toolchain="y" + # Host Tools ask_yn "Install host tools" && do_hosttools="y" @@ -115,12 +123,12 @@ user_prompt() # Entry point pushd "$(dirname "${BASH_SOURCE[0]}")" -# Initialise toolchain list -toolchains=$( /dev/null assert_rc "ERROR: Host tools installation failed" 30 + popd ;; macos-*) echo "SKIPPED: macOS host tools are not available yet." diff --git a/scripts/template_setup_win b/scripts/template_setup_win index d3e1b1cc..02af1d4c 100644 --- a/scripts/template_setup_win +++ b/scripts/template_setup_win @@ -23,21 +23,22 @@ exit /b 0 :entry -REM # Initialise toolchain list -set TOOLCHAINS= -for /f %%t in (sdk_toolchains) do ( - set TOOLCHAINS=!TOOLCHAINS! %%t +REM # Initialise GNU toolchain list +set GNU_TOOLCHAINS= +for /f %%t in (sdk_gnu_toolchains) do ( + set GNU_TOOLCHAINS=!GNU_TOOLCHAINS! %%t ) -REM Initialise list of toolchains to install -set INST_TOOLCHAINS= +REM Initialise list of GNU toolchains to install +set INST_GNU_TOOLCHAINS= REM # Read bundle version from file set /p VERSION=] [/h] [/c] +echo %~n0 [/t ^] [/h] [/c] echo. -echo /t ^ Install specified toolchain -echo all Install all toolchains -echo /h Install host tools -echo /c Register Zephyr SDK CMake package +echo /t ^ Install specified GNU toolchain +echo all Install all GNU toolchains +echo /l Install LLVM toolchain +echo /h Install host tools +echo /c Register Zephyr SDK CMake package echo. -echo Supported Toolchains: +echo Supported GNU Toolchains: echo. -for %%t in (%TOOLCHAINS%) do ( +for %%t in (%GNU_TOOLCHAINS%) do ( echo %%t ) echo.