diff --git a/.editorconfig b/.editorconfig index 65377cc44..4cadd5648 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,7 +6,8 @@ insert_final_newline = true charset = utf-8 indent_style = tab -[*.yaml] +[*.{yaml,yml}] indent_style = space indent_size = 2 - +insert_final_newline = true +end_of_line = lf diff --git a/.github/actions/install-apple-certs/action.yml b/.github/actions/install-apple-certs/action.yml new file mode 100644 index 000000000..d1f54efd2 --- /dev/null +++ b/.github/actions/install-apple-certs/action.yml @@ -0,0 +1,42 @@ +name: 'Install Apple Certificates' +description: 'Installs Apple signing and notarization certificates and sets up the keychain' +inputs: + MACOS_CERTIFICATE_APP: + required: true + MACOS_CERTIFICATE_INST: + required: true + MACOS_CERTIFICATE_PWD: + required: true + MACOS_CI_KEYCHAIN_PWD: + required: true +runs: + using: "composite" + steps: + - name: Install certificates and provisioning profiles + shell: bash + run: | + # Create temporary keychain + KEYCHAIN_PATH=$RUNNER_TEMP/build.keychain + security create-keychain -p "${{ inputs.MACOS_CI_KEYCHAIN_PWD }}" $KEYCHAIN_PATH + security default-keychain -s $KEYCHAIN_PATH + security set-keychain-settings -lut 21600 $KEYCHAIN_PATH + security unlock-keychain -p "${{ inputs.MACOS_CI_KEYCHAIN_PWD }}" $KEYCHAIN_PATH + + # Import certificates from secrets ... + CERTIFICATE_PATH_APP=$RUNNER_TEMP/build_certificate_app.p12 + CERTIFICATE_PATH_INST=$RUNNER_TEMP/build_certificate_inst.p12 + echo -n "${{ inputs.MACOS_CERTIFICATE_APP }}" | base64 --decode -o $CERTIFICATE_PATH_APP + echo -n "${{ inputs.MACOS_CERTIFICATE_INST }}" | base64 --decode -o $CERTIFICATE_PATH_INST + # ... to keychain + security import $CERTIFICATE_PATH_APP -P "${{ inputs.MACOS_CERTIFICATE_PWD }}" -k $KEYCHAIN_PATH -A -t cert -f pkcs12 + security import $CERTIFICATE_PATH_INST -P "${{ inputs.MACOS_CERTIFICATE_PWD }}" -k $KEYCHAIN_PATH -A -t cert -f pkcs12 + + # Set trusted partitions (groups of applications) that can access the keychain items + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "${{ inputs.MACOS_CI_KEYCHAIN_PWD }}" $KEYCHAIN_PATH + security list-keychain -d user -s $KEYCHAIN_PATH + + # Get certificate identities into environment variables + CERT_IDENTITY_APP=$(security find-identity -v -p codesigning $KEYCHAIN_PATH | grep "Developer ID Application" | head -1 | awk -F'"' '{print $2}') + echo "APPLE_CODE_SIGN_IDENTITY_APP=$CERT_IDENTITY_APP" >> $GITHUB_ENV + CERT_IDENTITY_INST=$(security find-identity -v -p basic $KEYCHAIN_PATH | grep "Developer ID Installer" | head -1 | awk -F'"' '{print $2}') + echo "APPLE_CODE_SIGN_IDENTITY_INST=$CERT_IDENTITY_INST" >> $GITHUB_ENV \ No newline at end of file diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 5ab64200b..41225a76d 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -3,7 +3,11 @@ name: Android on: push: branches: ['androidci'] - paths_ignore: ['docs/**', '.travis.yml'] + paths: + - '**' + - '!docs/**' + - '!.github/**' + - '.github/workflows/android.yml' workflow_dispatch: inputs: cmakeextra: @@ -53,4 +57,3 @@ jobs: with: name: build-android-${{ matrix.config.arch }} path: install - diff --git a/.github/workflows/apple.yml b/.github/workflows/apple.yml new file mode 100644 index 000000000..3d01253a7 --- /dev/null +++ b/.github/workflows/apple.yml @@ -0,0 +1,259 @@ +name: Apple CI + +on: + push: + branches: + - main + - dev + tags: ['*'] + paths: + - '**' + - '!docs/**' + - '!.github/**' + - '.github/workflows/apple.yml' + pull_request: + release: + types: ['created'] + workflow_dispatch: + inputs: + cmakeextra: + description: 'Extra CMake options' + required: false + default: '' + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + fail-fast: false + matrix: + config: + - {name: "macOS-latest", os: "macOS-latest", cmake_extra: "-DCMAKE_OSX_DEPLOYMENT_TARGET=10.15 -DLSL_UNITTESTS=ON -DLSL_BENCHMARKS=ON -DCMAKE_OSX_ARCHITECTURES=\"x86_64;arm64\"" } + - {name: "iOS", os: "macOS-latest", cmake_extra: "-DCMAKE_TOOLCHAIN_FILE=cmake/ios.toolchain.cmake -DPLATFORM=OS64" } + - {name: "iOS Simulator", os: "macOS-latest", cmake_extra: "-DCMAKE_TOOLCHAIN_FILE=cmake/ios.toolchain.cmake -DPLATFORM=SIMULATOR64COMBINED -G Xcode" } + + steps: + - uses: actions/checkout@v4 + + - name: Install certificates and provisioning profiles + uses: ./.github/actions/install-apple-certs + with: + MACOS_CERTIFICATE_APP: ${{ secrets.PROD_MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_INST: ${{ secrets.PROD_MACOS_CERTIFICATE_INST }} + MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} + MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} + + - name: Configure CMake + env: + APPLE_DEVELOPMENT_TEAM: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }} + run: | + cmake --version + cmake -S . -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=${PWD}/install \ + -DCPACK_PACKAGE_DIRECTORY=${PWD}/package \ + -DLSL_FRAMEWORK=ON \ + -Dlslgitrevision=${{ github.sha }} \ + -Dlslgitbranch=${{ github.ref }} \ + ${{ matrix.config.cmake_extra }} \ + ${{ github.event.inputs.cmakeextra }} + echo ${PWD} + + - name: make + run: cmake --build build --config Release -j + + - name: make install + run: cmake --build build --config Release --target install + + - name: test install using examples + if: matrix.config.name == 'macOS-latest' + run: | + # Test that the in-tree install was successful by building the examples + cmake -S examples -B examples/build \ + -DLSL_INSTALL_ROOT=${PWD}/install \ + -DCMAKE_INSTALL_PREFIX=examples/build/install \ + -DLSL_COMFY_DEFAULTS=ON \ + ${{ matrix.config.cmake_extra }} \ + ${{ github.event.inputs.cmakeextra }} + cmake --build examples/build --target install --config Release -j + ./examples/build/install/bin/HandleMetaData + + - name: Codesign + run: | + if [[ "${{ matrix.config.name }}" == "macOS-latest" ]]; then + codesign -vvv --force --deep --sign "$APPLE_CODE_SIGN_IDENTITY_APP" \ + --entitlements lsl.entitlements --options runtime \ + install/Frameworks/lsl.framework/Versions/A/lsl + codesign -vvv --verify --deep --strict install/Frameworks/lsl.framework/Versions/A/lsl + elif [[ "${{ matrix.config.name }}" == "iOS" || "${{ matrix.config.name }}" == "iOS Simulator" ]]; then + codesign -vvv --force --deep --sign "$APPLE_CODE_SIGN_IDENTITY_APP" \ + install/Frameworks/lsl.framework/lsl + codesign -vvv --verify --deep --strict install/Frameworks/lsl.framework/lsl + fi + codesign -vvv --force --deep --sign "$APPLE_CODE_SIGN_IDENTITY_APP" \ + --entitlements lsl.entitlements --options runtime \ + install/Frameworks/lsl.framework + codesign -vvv --verify --deep --strict install/Frameworks/lsl.framework + + # run internal tests + - name: unit tests + if: matrix.config.name == 'macOS-latest' + run: | + mkdir -p dumps + install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes + install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes + timeout-minutes: 10 + - name: unit test (intel) + if: matrix.config.name == 'macOS-15-intel' + run: | + mkdir -p dumps + install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes + install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes + timeout-minutes: 10 + + - name: Package and Notarize macOS Installer + if: matrix.config.name == 'macOS-latest' + env: + APPLE_DEVELOPMENT_TEAM: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }} + APPLE_NOTARIZE_USERNAME: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }} + APPLE_NOTARIZE_PASSWORD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }} + run: | + # Get the version number from the framework's Info.plist + LSL_VERSION=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" install/Frameworks/lsl.framework/Versions/A/Resources/Info.plist) + echo "LSL_VERSION=$LSL_VERSION" >> $GITHUB_ENV + echo "Debug: LSL_VERSION=$LSL_VERSION" + + mkdir -p package + productbuild --sign "$APPLE_CODE_SIGN_IDENTITY_INST" \ + --component install/Frameworks/lsl.framework \ + /Library/Frameworks package/liblsl-${LSL_VERSION}-Darwin-universal.pkg + # Notarize the package + xcrun notarytool submit package/liblsl-${LSL_VERSION}-Darwin-universal.pkg \ + --apple-id "$APPLE_NOTARIZE_USERNAME" \ + --password "$APPLE_NOTARIZE_PASSWORD" \ + --team-id "$APPLE_DEVELOPMENT_TEAM" \ + --wait + # Staple the notarization ticket to the package + xcrun stapler staple package/liblsl-${LSL_VERSION}-Darwin-universal.pkg + + - name: upload dump + if: failure() + uses: actions/upload-artifact@v4 + with: + name: dumps-${{ matrix.config.name }} + path: dumps + + - name: Zip LSL Framework + run: | + cd install/Frameworks + zip -ry lsl.framework.zip lsl.framework + cd ../.. + + - name: Upload macOS Package and Framework + if: matrix.config.name == 'macOS-latest' + uses: actions/upload-artifact@v4 + with: + name: build-macOS-latest + path: | + package/*.pkg + install/Frameworks/lsl.framework.zip + # Note: the artifact will preserve the folder structure up to the common root, in this case all. + + - name: Upload iOS Framework + if: matrix.config.name == 'iOS' + uses: actions/upload-artifact@v4 + with: + name: build-iOS + path: install/Frameworks/lsl.framework.zip + # Note: the artifact drops the folder structure and only keeps the zip. + + - name: Upload iOS Simulator Framework + if: matrix.config.name == 'iOS Simulator' + uses: actions/upload-artifact@v4 + with: + name: build-iOS-Simulator + path: install/Frameworks/lsl.framework.zip + + xcframework_and_deploy: + name: XCFramework and Deploy + needs: build + runs-on: macOS-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/download-artifact@v4 + with: + name: build-macOS-latest + path: build-macOS-latest + - uses: actions/download-artifact@v4 + with: + name: build-iOS + path: build-iOS + - uses: actions/download-artifact@v4 + with: + name: build-iOS-Simulator + path: build-iOS-Simulator + + - name: Unzip macOS Framework + run: | + unzip build-macOS-latest/install/Frameworks/lsl.framework.zip -d build-macOS-latest/Frameworks + + - name: Unzip iOS Framework + run: | + unzip build-iOS/lsl.framework.zip -d build-iOS/Frameworks + + - name: Unzip iOS Simulator Framework + run: | + unzip build-iOS-Simulator/lsl.framework.zip -d build-iOS-Simulator/Frameworks + + - name: Install certificates and provisioning profiles + uses: ./.github/actions/install-apple-certs + with: + MACOS_CERTIFICATE_APP: ${{ secrets.PROD_MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_INST: ${{ secrets.PROD_MACOS_CERTIFICATE_INST }} + MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} + MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} + + - name: Create and Sign XCFramework + run: | + xcodebuild -create-xcframework \ + -framework build-macOS-latest/Frameworks/lsl.framework \ + -framework build-iOS/Frameworks/lsl.framework \ + -framework build-iOS-Simulator/Frameworks/lsl.framework \ + -output lsl.xcframework + + codesign -vvv --force --deep --sign "$APPLE_CODE_SIGN_IDENTITY_APP" lsl.xcframework + echo "✅ Verifying binary signatures in XCFramework..." + codesign -vvv --verify --deep --strict lsl.xcframework + + ditto -c -k --sequesterRsrc --keepParent lsl.xcframework lsl.xcframework.$LSL_VERSION.zip + + - name: upload artifacts + uses: actions/upload-artifact@v4 + with: + name: mac-packages + path: | + lsl.xcframework.*.zip + package/ + + - name: upload to release page + if: github.event_name == 'release' + env: + TOKEN: "token ${{ secrets.GITHUB_TOKEN }}" + TAG: ${{ github.event.release.tag_name }} + UPLOAD_URL: ${{ github.event.release.upload_url }} + run: | + UPLOAD_URL=${UPLOAD_URL%\{*} # remove "{name,label}" suffix + for pkg in lsl.xcframework.zip package/*.*; do + NAME=$(basename $pkg) + MIME=$(file --mime-type $pkg|cut -d ' ' -f2) + curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: $TOKEN" -H "Content-Type: $MIME" --data-binary @$pkg $UPLOAD_URL?name=$NAME + done diff --git a/.github/workflows/cppcmake.yml b/.github/workflows/cppcmake.yml index 4e1589563..202700b61 100644 --- a/.github/workflows/cppcmake.yml +++ b/.github/workflows/cppcmake.yml @@ -2,7 +2,9 @@ name: C/C++ CI on: push: - branches: ['*'] + branches: + - main + - dev tags: ['*'] paths: - '**' @@ -31,76 +33,169 @@ jobs: build: name: ${{ matrix.config.name }} runs-on: ${{ matrix.config.os }} + timeout-minutes: 30 strategy: fail-fast: false matrix: config: - - {name: "ubuntu-22.04", os: "ubuntu-22.04", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" } - - {name: "ubuntu-24.04", os: "ubuntu-24.04", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" } - - {name: "windows-x64", os: "windows-latest", cmake_extra: "-T v142,host=x86"} - - {name: "windows-32", os: "windows-latest", cmake_extra: "-T v142,host=x86 -A Win32"} - - {name: "macOS-latest", os: "macOS-latest"} - - # runs all steps in the container configured in config.docker or as subprocesses when empty - container: ${{ matrix.config.docker }} + # x86_64 Linux builds + - {name: "ubuntu-22.04-x64", os: "ubuntu-22.04", arch: "x86_64", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" } + - {name: "ubuntu-24.04-x64", os: "ubuntu-24.04", arch: "x86_64", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" } + + # ARM Linux builds - cross-compiled with QEMU testing (Jetson, Raspberry Pi compatible) + # SHLIBDEPS must be disabled for cross-compiled packages as the host system + # does not have the target architecture libraries installed + - {name: "ubuntu-22.04-arm64", os: "ubuntu-22.04", arch: "aarch64", cross_compile: true, cmake_extra: "-DLSL_BUNDLED_PUGIXML=ON -DLSL_DISABLE_PACKAGE_SHLIBDEPS=ON" } + - {name: "ubuntu-22.04-armhf", os: "ubuntu-22.04", arch: "armv7", cross_compile: true, cmake_extra: "-DLSL_BUNDLED_PUGIXML=ON -DLSL_DISABLE_PACKAGE_SHLIBDEPS=ON" } + + # Native ARM build + # - {name: "ubuntu-24.04-arm64-native", os: "ubuntu-24.04-arm", arch: "aarch64", cmake_extra: "-DLSL_BUNDLED_PUGIXML=OFF" } + + # Windows builds + - {name: "windows-x64", os: "windows-latest", arch: "x86_64", cmake_extra: "-T v142,host=x86"} + - {name: "windows-x86", os: "windows-latest", arch: "x86", cmake_extra: "-T v142,host=x86 -A Win32"} + - {name: "windows-arm64", os: "windows-11-arm", arch: "aarch64", cmake_extra: "-T v143,host=ARM64 -A ARM64"} + + # macOS builds (Apple Silicon + Intel) + # - {name: "macos-latest", os: "macos-latest", arch: "universal"} + steps: - - uses: actions/checkout@v4 - - name: set up build environment in container + - uses: actions/checkout@v5 + + # Set up cross-compilation toolchain for ARM on Linux + - name: Install cross-compilation toolchain + if: matrix.config.cross_compile && runner.os == 'Linux' run: | - set -x - apt update - apt install -y --no-install-recommends g++ git ninja-build file dpkg-dev lsb-release sudo curl cmake libpugixml-dev - if: ${{ matrix.config.docker }} + sudo apt-get update + if [[ "${{ matrix.config.arch }}" == "aarch64" ]]; then + sudo apt-get install -y --no-install-recommends \ + gcc-aarch64-linux-gnu \ + g++-aarch64-linux-gnu + echo "CMAKE_TOOLCHAIN=-DCMAKE_TOOLCHAIN_FILE=${GITHUB_WORKSPACE}/cmake/toolchains/aarch64-linux-gnu.cmake" >> $GITHUB_ENV + elif [[ "${{ matrix.config.arch }}" == "armv7" ]]; then + sudo apt-get install -y --no-install-recommends \ + gcc-arm-linux-gnueabihf \ + g++-arm-linux-gnueabihf + echo "CMAKE_TOOLCHAIN=-DCMAKE_TOOLCHAIN_FILE=${GITHUB_WORKSPACE}/cmake/toolchains/arm-linux-gnueabihf.cmake" >> $GITHUB_ENV + fi + + # Cache dependencies for Linux + - name: Cache APT packages + if: runner.os == 'Linux' + uses: actions/cache@v4 + with: + path: /var/cache/apt/archives + key: ${{ runner.os }}-apt-${{ matrix.config.name }}-${{ hashFiles('.github/workflows/cppcmake.yml') }} + restore-keys: | + ${{ runner.os }}-apt-${{ matrix.config.name }}- + ${{ runner.os }}-apt- + + # Cache build artifacts with ccache + - name: Cache ccache + if: runner.os == 'Linux' || runner.os == 'macOS' + uses: actions/cache@v4 + with: + path: ~/.ccache + key: ${{ runner.os }}-ccache-${{ matrix.config.name }}-${{ github.sha }} + restore-keys: | + ${{ runner.os }}-ccache-${{ matrix.config.name }}- + ${{ runner.os }}-ccache- + + - name: Install ccache + if: runner.os == 'Linux' || runner.os == 'macOS' + run: | + if [[ "${{ runner.os }}" == "Linux" ]]; then + sudo apt-get install -y ccache + elif [[ "${{ runner.os }}" == "macOS" ]]; then + brew install ccache + fi + ccache --max-size=500M + ccache --set-config=compression=true + + - name: Install dependencies + if: runner.os == 'Linux' + run: | + if [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then + sudo apt-get install -y --no-install-recommends libpugixml-dev + fi + - name: Configure CMake run: | - if [[ "${{ matrix.config.name }}" = ubuntu-2* ]]; then - sudo apt-get install -y --no-install-recommends libpugixml-dev - fi - cmake --version - cmake -S . -B build \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_INSTALL_PREFIX=${PWD}/install \ - -DLSL_UNITTESTS=ON \ - -DLSL_BENCHMARKS=ON \ - -DCPACK_PACKAGE_DIRECTORY=${PWD}/package \ - -Dlslgitrevision=${{ github.sha }} \ - -Dlslgitbranch=${{ github.ref }} \ - ${{ matrix.config.cmake_extra }} \ - ${{ github.event.inputs.cmakeextra }} - echo ${PWD} - - name: make - run: cmake --build build --target install --config Release -j - - - name: test install using examples + # Set up ccache as compiler wrapper (skip for cross-compilation) + if [[ "${{ runner.os }}" == "Linux" || "${{ runner.os }}" == "macOS" ]] && [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then + export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" + export CC="ccache gcc" + export CXX="ccache g++" + fi + + cmake --version + cmake -S . -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=${PWD}/install \ + -DLSL_UNITTESTS=ON \ + -DLSL_BENCHMARKS=ON \ + -DCPACK_PACKAGE_DIRECTORY=${PWD}/package \ + -DCPACK_PACKAGE_FILE_NAME="liblsl-${{ matrix.config.arch }}" \ + -Dlslgitrevision=${{ github.sha }} \ + -Dlslgitbranch=${{ github.ref }} \ + ${CMAKE_TOOLCHAIN} \ + ${{ matrix.config.cmake_extra }} \ + ${{ github.event.inputs.cmakeextra }} + echo "Build directory: ${PWD}" + + - name: Build + run: | + cmake --build build --config Release -j + # Show ccache statistics + if command -v ccache &> /dev/null; then + ccache -s + fi + + - name: Install + run: cmake --build build --config Release --target install + + - name: Test install using examples run: | - # Test that the in-tree install was successful by building the examples - cmake -S examples -B examples/build \ - -DLSL_INSTALL_ROOT=${PWD}/install \ - -DCMAKE_INSTALL_PREFIX=examples/build/install \ - -DLSL_COMFY_DEFAULTS=ON \ - ${{ matrix.config.cmake_extra }} \ - ${{ github.event.inputs.cmakeextra }} - cmake --build examples/build --target install --config Release -j + # Test that the in-tree install was successful by building the examples + cmake -S examples -B examples/build \ + -DLSL_INSTALL_ROOT=${PWD}/install \ + -DCMAKE_INSTALL_PREFIX=examples/build/install \ + -DLSL_COMFY_DEFAULTS=ON \ + ${CMAKE_TOOLCHAIN} \ + ${{ matrix.config.cmake_extra }} \ + ${{ github.event.inputs.cmakeextra }} + cmake --build examples/build --target install --config Release -j + + # Run example binary (skip for cross-compiled builds - no QEMU) + if [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then ./examples/build/install/bin/HandleMetaData - - - name: package + else + echo "Skipping example execution for cross-compiled build (requires real ARM hardware)" + echo "Build validation successful - binary can be tested on target hardware" + fi + + - name: Package run: | - echo $GITHUB_REF - cmake --build build --target package --config Release -j - echo $PWD - ls -la - # On Debian / Ubuntu the dependencies can only be resolved for - # already installed packages. Therefore, we have built all - # packages without dependencies in the previous step, - # install them and rebuild them with dependency discovery enabled - if [[ "${{ matrix.config.os }}" == ubuntu-* ]]; then - cmake -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON . - sudo dpkg -i package/*.deb - cmake --build build --target package --config Release -j - dpkg -I package/liblsl*.deb - fi - cmake -E remove_directory package/_CPack_Packages - cp testing/lslcfgs/default.cfg . + echo "Creating package for ${{ matrix.config.arch }}" + cmake --build build --target package --config Release -j + + # On Debian / Ubuntu the dependencies can only be resolved for + # already installed packages (only for native builds, not cross-compiled) + if [[ "${{ matrix.config.os }}" == ubuntu-* ]] && [[ "${{ matrix.config.cross_compile }}" != "true" ]]; then + cmake -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON build + sudo dpkg -i package/*.deb + cmake --build build --target package --config Release -j + dpkg -I package/liblsl*.deb + fi + + if [[ "${{ matrix.config.cross_compile }}" == "true" ]]; then + echo "Cross-compiled ${{ matrix.config.arch }} package created" + ls -lh package/ + fi + + cmake -E remove_directory package/_CPack_Packages + cp testing/lslcfgs/default.cfg . 2>/dev/null || true + - name: upload install dir uses: actions/upload-artifact@master with: @@ -112,6 +207,7 @@ jobs: with: name: pkg-${{ matrix.config.name }} path: package + - name: print network config run: | which ifconfig && ifconfig @@ -121,24 +217,30 @@ jobs: ip route ip -6 route fi - - # run internal tests, ignore test failures on docker (missing IPv6 connectivity) - - name: unit tests + + # Run tests (native builds only) + - name: Unit tests + if: matrix.config.cross_compile != true run: | - if [[ "${{ matrix.config.name }}" = ubuntu-2* ]]; then + # Set up core dumps for debugging + if [[ "${{ matrix.config.name }}" == ubuntu-* ]]; then ulimit -c unlimited echo "$PWD/dumps/corefile-%e-%p-%t" | sudo tee /proc/sys/kernel/core_pattern fi mkdir -p dumps - install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes || test ! -z "${{ matrix.config.docker }}" + + # Run unit tests + install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes timeout-minutes: 10 + - name: upload dump if: failure() uses: actions/upload-artifact@master with: name: dumps-${{ matrix.config.name }} path: dumps + - name: upload to release page if: github.event_name == 'release' env: diff --git a/.github/workflows/raspberry_pi_manual.yml b/.github/workflows/raspberry_pi_manual.yml new file mode 100644 index 000000000..d4d6a9dc2 --- /dev/null +++ b/.github/workflows/raspberry_pi_manual.yml @@ -0,0 +1,136 @@ +name: Raspberry Pi Native Build (Manual trigger) +on: + workflow_dispatch: + inputs: + cmakeextra: + description: 'Extra CMake options' + required: false + default: '' +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + build: + name: Raspberry Pi ${{ matrix.config.name }} + runs-on: ubuntu-latest + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + config: + # cortex-a7 -> RPi 3+, if we need 1,2,zero, needs to use arm1176 + # see: https://github.com/marketplace/actions/arm-runner + # adapted from: https://github.com/castle-engine/castle-engine/blob/master/.github/workflows/test-and-pack-arm-runner.yml + - {name: "rpi-armv7l", os: "raspios_lite:latest", cpu: "cortex-a7", cpu_info: "cpuinfo/raspberrypi_3b", cmake_extra: "-DLSL_UNITTESTS=ON -DLSL_BENCHMARKS=ON" } + - {name: "rpi-aarch64", os: "raspios_lite_arm64:latest", cpu: "cortex-a53", cpu_info: "cpuinfo/raspberrypi_4b", cmake_extra: "-DLSL_UNITTESTS=ON -DLSL_BENCHMARKS=ON" } + steps: + - uses: actions/checkout@v5 + - uses: pguyot/arm-runner-action@v2 + with: + base_image: ${{ matrix.config.os }} + cpu: ${{ matrix.config.cpu }} + cpu_info: ${{ matrix.config.cpu_info }} + shell: /bin/bash -eo pipefail + image_additional_mb: 1024 + bind_mount_repository: true + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake build-essential pkg-config + - name: Configure CMake + run: | + cmake --version + cmake -S . -B build \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=${PWD}/install \ + -DLSL_UNITTESTS=ON \ + -DLSL_BENCHMARKS=ON \ + -Dlslgitrevision=${{ github.sha }} \ + -Dlslgitbranch=${{ github.ref }} \ + ${{ matrix.config.cmake_extra }} + + - name: make + run: cmake --build build --config Release -j + + - name: make install + run: cmake --build build --config Release --target install -j + + - name: test install using examples + run: | + # Test that the in-tree install was successful by building the examples + cmake -S examples -B examples/build \ + -DLSL_INSTALL_ROOT=${PWD}/install \ + -DCMAKE_INSTALL_PREFIX=examples/build/install \ + -DLSL_COMFY_DEFAULTS=ON \ + ${{ matrix.config.cmake_extra }} \ + ${{ github.event.inputs.cmakeextra }} + cmake --build examples/build --target install --config Release -j + ./examples/build/install/bin/HandleMetaData + + - name: package + run: | + echo $GITHUB_REF + cmake --build build --target package --config Release -j + echo $PWD + ls -la + cmake -DCPACK_DEBIAN_PACKAGE_SHLIBDEPS=ON . + sudo dpkg -i build/*.deb + cmake --build build --target package --config Release -j + dpkg -I build/liblsl*.deb + cmake -E remove_directory build/_CPack_Packages + cp testing/lslcfgs/default.cfg . + + - name: upload install dir + uses: actions/upload-artifact@master + with: + name: build-${{ matrix.config.name }} + path: install + - name: upload package + uses: actions/upload-artifact@master + with: + name: pkg-${{ matrix.config.name }} + path: package + + # Run tests + - name: unit tests + run: | + if [[ "${{ matrix.config.name }}" = ubuntu-2* ]]; then + ulimit -c unlimited + echo "$PWD/dumps/corefile-%e-%p-%t" | sudo tee /proc/sys/kernel/core_pattern + fi + mkdir -p dumps + install/bin/lsl_test_internal --order rand --wait-for-keypress never --durations yes + install/bin/lsl_test_exported --order rand --wait-for-keypress never --durations yes + timeout-minutes: 10 + + - name: upload dump + if: failure() + uses: actions/upload-artifact@master + with: + name: dumps-${{ matrix.config.name }} + path: dumps + + - name: upload to release page + if: github.event_name == 'release' + env: + TOKEN: "token ${{ secrets.GITHUB_TOKEN }}" + TAG: ${{ github.event.release.tag_name }} + UPLOAD_URL: ${{ github.event.release.upload_url }} + run: | + # Do try this at home! The REST API is documented at + # https://docs.github.com/en/free-pro-team@latest/rest and you can get a personal + # access token at https://github.com/settings/tokens + # (set TOKEN to "bearer abcdef1234") + # you can get the UPLOAD_URL with a short bash snippet; make sure to set the env var TAG: + # UPLOAD_URL=$(curl -H 'Accept: application/vnd.github.v3+json' $GITHUB_API_URL/repos/$GITHUB_REPOSITORY/releases/tags/$TAG | jq -r .upload_url) + UPLOAD_URL=${UPLOAD_URL%\{*} # remove "{name,label}" suffix + for pkg in package/*.*; do + NAME=$(basename $pkg) + MIME=$(file --mime-type $pkg|cut -d ' ' -f2) + curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: $TOKEN" -H "Content-Type: $MIME" --data-binary @$pkg $UPLOAD_URL?name=$NAME + done diff --git a/CMakeLists.txt b/CMakeLists.txt index c4e0dea1c..45b513ca9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ include(cmake/TargetLib.cmake) # include(cmake/Installation.cmake) # include(cmake/TargetOther.cmake) -if(LSL_UNITTESTS) +if(LSL_UNITTESTS AND NOT IOS) add_subdirectory(testing) endif() diff --git a/cmake/CompilerSettings.cmake b/cmake/CompilerSettings.cmake index 31868a85b..56cbbd3d4 100644 --- a/cmake/CompilerSettings.cmake +++ b/cmake/CompilerSettings.cmake @@ -30,6 +30,4 @@ endif() # Platform-specific settings if(WIN32) add_definitions(-D_CRT_SECURE_NO_WARNINGS) -elseif(APPLE) - set(CMAKE_MACOSX_RPATH ON) endif() diff --git a/cmake/CreateFrameworkSymlinks.cmake.in b/cmake/CreateFrameworkSymlinks.cmake.in new file mode 100644 index 000000000..d614091ad --- /dev/null +++ b/cmake/CreateFrameworkSymlinks.cmake.in @@ -0,0 +1,39 @@ +# This script is executed at install time. +# It was generated from CreateFrameworkSymlinks.cmake.in + +set(FRAMEWORK_DIR "${CMAKE_INSTALL_PREFIX}/@CMAKE_INSTALL_FRAMEWORK_DIR@/lsl.framework") + +message(STATUS "Executing configured symlink script.") +message(STATUS " -- Target Directory='${FRAMEWORK_DIR}'") + +if(NOT EXISTS "${FRAMEWORK_DIR}") + message(FATAL_ERROR "Framework version directory does not exist. Cannot create symlink.") +endif() + +message(STATUS " -- Framework version directory exists. Creating symlink...") + +execute_process( + COMMAND ln -sf include Headers + WORKING_DIRECTORY "${FRAMEWORK_DIR}/Versions/A" + RESULT_VARIABLE result + ERROR_VARIABLE error +) +if(NOT result EQUAL 0) + message(FATAL_ERROR "Failed to create Headers->include symlink: ${error}") +endif() + +execute_process( + COMMAND ln -sf Versions/Current/Headers + WORKING_DIRECTORY "${FRAMEWORK_DIR}" + RESULT_VARIABLE result + ERROR_VARIABLE error +) +if(NOT result EQUAL 0) + message(FATAL_ERROR "Failed to create Headers->Versions/Current/Headers symlink: ${error}") +endif() + +if(NOT result EQUAL 0) + message(FATAL_ERROR "Failed to create Headers symlink in framework: ${error}") +endif() + +message(STATUS " -- Framework symlink created successfully.") diff --git a/cmake/Installation.cmake b/cmake/Installation.cmake index 44f99839c..4b82864c7 100644 --- a/cmake/Installation.cmake +++ b/cmake/Installation.cmake @@ -4,10 +4,28 @@ include(CMakePackageConfigHelpers) # Paths if(LSL_UNIXFOLDERS) include(GNUInstallDirs) + set(CMAKE_INSTALL_FRAMEWORK_DIR ${FRAMEWORK_DIR_DEFAULT} CACHE PATH "Install directory for frameworks on macOS") else() set(CMAKE_INSTALL_BINDIR LSL) set(CMAKE_INSTALL_LIBDIR LSL) set(CMAKE_INSTALL_INCLUDEDIR LSL/include) + set(CMAKE_INSTALL_FRAMEWORK_DIR LSL/Frameworks CACHE PATH "Install directory for frameworks on macOS") +endif() + +# For Apple frameworks, we need to next the install directories within the framework. +if(APPLE AND LSL_FRAMEWORK) + # For the includes, this is insufficient. Later we will create more accessible symlinks. + if(IOS) + set(LSL_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_FRAMEWORK_DIR}/lsl.framework/Headers) + set(LSL_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_FRAMEWORK_DIR}/lsl.framework/CMake) + else() + set(LSL_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_FRAMEWORK_DIR}/lsl.framework/Versions/A/include) + set(LSL_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_FRAMEWORK_DIR}/lsl.framework/Resources/CMake) + endif() + +else() + set(LSL_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR}) + set(LSL_CONFIG_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/lsl) endif() # Generate a version file for the package. @@ -30,20 +48,26 @@ install(TARGETS ${LSLTargets} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - FILE_SET HEADERS DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + FRAMEWORK DESTINATION ${CMAKE_INSTALL_FRAMEWORK_DIR} ) +# Unfortunately, `INCLUDES DESTINATION` does not work. +# PUBLIC_HEADER does not work because it flattens the tree. +# FILE_SET is preferable but does not work with frameworks. +# So we are stuck manually specifying the headers to be installed. +install(DIRECTORY include/lsl DESTINATION ${LSL_INSTALL_INCLUDEDIR}) +install(FILES include/lsl_c.h include/lsl_cpp.h DESTINATION ${LSL_INSTALL_INCLUDEDIR}) # Generate the LSLConfig.cmake file and mark it for installation install(EXPORT LSLTargets FILE LSLConfig.cmake COMPONENT liblsl NAMESPACE "LSL::" - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LSL + DESTINATION ${LSL_CONFIG_INSTALL_DIR} ) # A common alternative to installing the exported package config file is to generate it from a template. #configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/lslConfig.cmake.in # ${CMAKE_CURRENT_BINARY_DIR}/LSLConfig.cmake -# INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/lsl) +# INSTALL_DESTINATION ${LSL_CONFIG_INSTALL_DIR}) # If we use this method, then we need a corresponding install(FILES ...) command to install the generated file. # Install the version file and the helper CMake script. @@ -52,5 +76,17 @@ install( cmake/LSLCMake.cmake ${CMAKE_CURRENT_BINARY_DIR}/LSLConfigVersion.cmake COMPONENT liblsl - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/LSL + DESTINATION ${LSL_CONFIG_INSTALL_DIR} ) + +if(APPLE AND LSL_FRAMEWORK AND NOT IOS) + # Create symlinks for the framework. The variables we want to use to identify the symlink locations + # are not available at install time. Instead, we create a script during configuration time that will + # be run at install time to create the symlinks. + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/CreateFrameworkSymlinks.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/CreateFrameworkSymlinks.cmake + @ONLY + ) + install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/CreateFrameworkSymlinks.cmake COMPONENT liblsl) +endif() diff --git a/cmake/LSLCMake.cmake b/cmake/LSLCMake.cmake index f64b001bb..20234b48b 100644 --- a/cmake/LSLCMake.cmake +++ b/cmake/LSLCMake.cmake @@ -1,6 +1,6 @@ # Common functions and settings for LSL -option(LSL_DEPLOYAPPLIBS "Copy library dependencies (at the moment Qt + liblsl) to the installation dir" ON) +option(LSL_DEPLOYAPPLIBS "Copy library dependencies (at the moment Qt + liblsl) to the installation dir" ${WIN32}) option(LSL_COMFY_DEFAULTS "Set some quality of life options, e.g. a sensible 'install' directory" OFF) macro(LSLAPP_Setup_Boilerplate) @@ -90,8 +90,13 @@ endfunction() # After the target, additional libraries to install alongside the target can be # specified, e.g. installLSLApp(FooApp libXY libZ) function(installLSLApp target) + # We use some generator expressions that only became available in CMake 3.16. + cmake_minimum_required(VERSION 3.16) + + # Identify if the application links qt libraries. get_target_property(TARGET_LIBRARIES ${target} LINK_LIBRARIES) string(REGEX MATCH ";Qt[56]?::" qtapp ";${TARGET_LIBRARIES}") + if(qtapp) # Enable automatic compilation of .cpp->.moc, xy.ui->ui_xy.h and resource files set_target_properties(${target} PROPERTIES @@ -101,25 +106,31 @@ function(installLSLApp target) ) endif() - # Set runtime path, i.e. where shared libs are searched relative to the exe - # CMake>=3.16: set(LIBDIR "../$,lib/,LSL/lib/>") - if(LSL_UNIXFOLDERS) - set(LIBDIR "../lib") - else() - set(LIBDIR "../LSL/lib") - endif() - if(APPLE AND NOT CMAKE_INSTALL_RPATH) - set_property(TARGET ${target} APPEND - PROPERTY INSTALL_RPATH "@executable_path/;@executable_path/${LIBDIR};@executable_path/../Frameworks") - elseif(UNIX AND NOT CMAKE_INSTALL_RPATH) - set_property(TARGET ${target} - PROPERTY INSTALL_RPATH "\$ORIGIN:\$ORIGIN/${LIBDIR}") - endif() + # Provide a default rpath if not set. + if(NOT CMAKE_INSTALL_RPATH) + # If not otherwise provided, our default RPATH is the same directory as the executable, + # and on Mac into the ../Frameworks directory. + # We additionally search a specific path for the LSL library. + # If `LSL_UNIXFOLDERS` is set, we use the ../lib/ directory (assumes target in bin/). + # Otherwise, we use the ../LSL/lib/ directory. + set(LIBDIR "../$,lib/,LSL/lib/>") + if(APPLE AND NOT CMAKE_INSTALL_RPATH) + set_property(TARGET ${target} APPEND + PROPERTY INSTALL_RPATH "@executable_path/;@executable_path/${LIBDIR};@executable_path/../Frameworks") + elseif(UNIX AND NOT CMAKE_INSTALL_RPATH) + set_property(TARGET ${target} + PROPERTY INSTALL_RPATH "\$ORIGIN:\$ORIGIN/${LIBDIR}") + endif() + endif() if(LSL_UNIXFOLDERS) + # Use common folders for libraries and executables include(GNUInstallDirs) set(lsldir "\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") - else() + else() + # Dump everything into ${CMAKE_INSTALL_PREFIX}/${PROJECT_NAME} + # except LSL specifically goes into ${CMAKE_INSTALL_PREFIX}/LSL + # This is why above we set the INSTALL_RPATH to include ../LSL/lib set(CMAKE_INSTALL_BINDIR ${PROJECT_NAME}) set(CMAKE_INSTALL_LIBDIR ${PROJECT_NAME}) set(lsldir "\${CMAKE_INSTALL_PREFIX}/LSL") @@ -140,13 +151,18 @@ function(installLSLApp target) if(NOT PROJECT_NAME STREQUAL "liblsl") set_property(GLOBAL APPEND PROPERTY "LSLDEPENDS_${PROJECT_NAME}" liblsl) endif() - install(TARGETS ${target} COMPONENT ${PROJECT_NAME} + install( + TARGETS ${target} + COMPONENT ${PROJECT_NAME} + # EXPORTS ? RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}) - # skip copying libraries if disabled or on Linux - if(NOT LSL_DEPLOYAPPLIBS OR UNIX AND NOT APPLE) + BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} + ) + + # skip copying libraries if disabled + if(NOT LSL_DEPLOYAPPLIBS) return() endif() @@ -154,7 +170,9 @@ function(installLSLApp target) get_target_property(target_type ${target} TYPE) if(NOT target_type STREQUAL "EXECUTABLE") return() - endif() + endif() + + message(STATUS "Preparing to deploy libraries for target ${target}") # Some Windows installers have problems with several components having the same file, # so libs shared between targets are copied into the SHAREDLIBCOMPONENT component if set @@ -174,7 +192,7 @@ function(installLSLApp target) # then the application needs to have liblsl in an expected location. if(NOT TARGET liblsl AND NOT LSL_UNIXFOLDERS) if(APPLE AND target_is_bundle) - # Copy the dylib into the bundle + # Copy the framework into the bundle install(FILES $ DESTINATION ${CMAKE_INSTALL_BINDIR}/${target}.app/Contents/MacOS/ COMPONENT ${SHAREDLIBCOMPONENT}) @@ -206,7 +224,6 @@ function(installLSLApp target) return() endif() - cmake_minimum_required(VERSION 3.15) # generator expressions in install(CODE) if(WIN32) findQtInstallationTool("windeployqt") install(CODE " @@ -287,34 +304,52 @@ macro(LSLGenerateCPackConfig) set(CPACK_STRIP_FILES ON) set(CPACK_ARCHIVE_COMPONENT_INSTALL ON) set(CPACK_PACKAGE_NAME lsl) - set(CPACK_PACKAGE_VENDOR "Labstreaminglayer") + if(NOT CPACK_PACKAGE_VENDOR) + message(STATUS "CPACK_PACKAGE_VENDOR is not set, using default.") + set(CPACK_PACKAGE_VENDOR "Labstreaminglayer") + endif() + # The remaining options are platform-specific. if(APPLE) set(LSL_CPACK_DEFAULT_GEN TBZ2) - if(DEFINED ENV{OSXVER}) - # Configured by Travis-CI for multi-osx builds. - set(LSL_OS "$ENV{OSXVER}") - else() - set(LSL_OS "OSX${lslplatform}") - endif(DEFINED ENV{OSXVER}) + set(LSL_OS "OSX${lslplatform}") elseif(WIN32) set(LSL_CPACK_DEFAULT_GEN ZIP) + set(LSL_OS "Win") set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_WIX_CMAKE_PACKAGE_REGISTRY ON) set(CPACK_WIX_UPGRADE_GUID "ee28a351-3b27-4c2b-8b48-259c87d1b1b4") set(CPACK_WIX_PROPERTY_ARPHELPLINK "https://labstreaminglayer.readthedocs.io/info/getting_started.html#getting-help") - set(LSL_OS "Win") elseif(UNIX) set(LSL_CPACK_DEFAULT_GEN DEB) set(LSL_OS "Linux") - set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Tristan Stenner ") - + if(NOT CPACK_DEBIAN_PACKAGE_MAINTAINER) + message(STATUS "CPACK_DEBIAN_PACKAGE_MAINTAINER is not set, using default.") + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Tristan Stenner ") + endif() set(CPACK_DEBIAN_ENABLE_COMPONENT_DEPENDS ON) set(CPACK_DEB_COMPONENT_INSTALL ON) set(CPACK_DEBIAN_PACKAGE_PRIORITY optional) - set(CPACK_DEBIAN_LIBLSL_PACKAGE_SHLIBDEPS ON) + # Allow disabling SHLIBDEPS for cross-compilation (dpkg-shlibdeps can't analyze ARM binaries on x86 host) + if(NOT LSL_DISABLE_PACKAGE_SHLIBDEPS) + set(CPACK_DEBIAN_LIBLSL_PACKAGE_SHLIBDEPS ON) + endif() set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS ON) + # determine architecture for cross-compiled packages + if(CMAKE_CROSSCOMPILING) + if(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(armv7|arm)") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "armhf") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(x86_64|amd64)") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64") + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(i.86|x86)") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "i386") + endif() + message(STATUS "Cross-compiling: Setting Debian package architecture to ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE} (CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR})") + endif() + # include distribution name (e.g. trusty or xenial) in the file name find_program(LSB_RELEASE lsb_release) execute_process(COMMAND ${LSB_RELEASE} -cs @@ -326,7 +361,8 @@ macro(LSLGenerateCPackConfig) set(CPACK_DEBIAN_PACKAGE_RELEASE ${LSB_RELEASE_CODENAME}) set(LSL_OS "${LSB_RELEASE_CODENAME}") endif() - endif() + endif() + # https://cmake.org/cmake/help/latest/manual/cpack-generators.7.html set(CPACK_GENERATOR ${LSL_CPACK_DEFAULT_GEN} CACHE STRING "CPack pkg type(s) to generate") get_cmake_property(LSL_COMPONENTS COMPONENTS) foreach(component ${LSL_COMPONENTS}) @@ -343,9 +379,10 @@ macro(LSLGenerateCPackConfig) endif() set("CPACK_COMPONENT_${COMPONENT}_DEPENDS" ${LSLDEPENDS}) endif() - - set("CPACK_DEBIAN_${COMPONENT}_PACKAGE_NAME" ${component}) - set("CPACK_DEBIAN_${COMPONENT}_FILE_NAME" "${LSL_CPACK_FILENAME}.deb") + if(UNIX) + set("CPACK_DEBIAN_${COMPONENT}_PACKAGE_NAME" ${component}) + set("CPACK_DEBIAN_${COMPONENT}_FILE_NAME" "${LSL_CPACK_FILENAME}.deb") + endif() set("CPACK_ARCHIVE_${COMPONENT}_FILE_NAME" ${LSL_CPACK_FILENAME}) endforeach() diff --git a/cmake/ProjectOptions.cmake b/cmake/ProjectOptions.cmake index 48f4c5656..fa8bebda5 100644 --- a/cmake/ProjectOptions.cmake +++ b/cmake/ProjectOptions.cmake @@ -1,12 +1,23 @@ +include(CMakeDependentOption) + # Project build options option(LSL_DEBUGLOG "Enable (lots of) additional debug messages" OFF) option(LSL_UNIXFOLDERS "Use the unix folder layout for install targets" ON) option(LSL_BUILD_STATIC "Build LSL as a static library." OFF) +option(LSL_FRAMEWORK "Build LSL as an Apple Framework (Mac only)" ON) option(LSL_LEGACY_CPP_ABI "Build legacy C++ ABI into lsl-static" OFF) option(LSL_OPTIMIZATIONS "Enable some more compiler optimizations" ON) option(LSL_BUNDLED_BOOST "Use the bundled Boost by default" ON) option(LSL_BUNDLED_PUGIXML "Use the bundled pugixml by default" ON) -option(LSL_TOOLS "Build some experimental tools for in-depth tests" OFF) -option(LSL_UNITTESTS "Build LSL library unit tests" OFF) +cmake_dependent_option(LSL_TOOLS "Build some experimental tools for in-depth tests" OFF "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF) +cmake_dependent_option(LSL_UNITTESTS "Build LSL library unit tests" OFF "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF) option(LSL_FORCE_FANCY_LIBNAME "Add library name decorations (32/64/-debug)" OFF) mark_as_advanced(LSL_FORCE_FANCY_LIBNAME) + +# If we install to the system then we want the framework to land in +# `Library/Frameworks`, otherwise (e.g., Homebrew) we want `Frameworks` +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(FRAMEWORK_DIR_DEFAULT Library/Frameworks) +else() + set(FRAMEWORK_DIR_DEFAULT Frameworks) +endif() diff --git a/cmake/TargetLib.cmake b/cmake/TargetLib.cmake index 7e7d515f0..92d6f0ffb 100644 --- a/cmake/TargetLib.cmake +++ b/cmake/TargetLib.cmake @@ -31,12 +31,20 @@ target_link_libraries(lsl PRIVATE lslobj) # Set the include directories for the lsl target. # Note: We had to link lslobj as a PRIVATE dependency, therefore we must manually expose the include directories -get_target_property(LSLOBJ_HEADERS lslobj HEADER_SET) -target_sources(lsl - INTERFACE - FILE_SET HEADERS - BASE_DIRS include - FILES ${LSLOBJ_HEADERS} +if(APPLE AND LSL_FRAMEWORK) + # For frameworks, the install interface needs to point into the framework bundle + if(LSL_UNIXFOLDERS) + set(LSL_INSTALL_INTERFACE_INCLUDE_DIR "${FRAMEWORK_DIR_DEFAULT}/lsl.framework/Versions/A/Headers") + else() + set(LSL_INSTALL_INTERFACE_INCLUDE_DIR "LSL/Frameworks/lsl.framework/Versions/A/Headers") + endif() +else() + set(LSL_INSTALL_INTERFACE_INCLUDE_DIR "include") +endif() +target_include_directories(lsl + PUBLIC + $ + $ ) # Set compile definitions for lsl @@ -47,3 +55,34 @@ target_compile_definitions(lsl # don't use #pragma(lib) in MSVC builds. TODO: Maybe this can be inherited from lslobj or removed on lslobj? $<$:LSLNOAUTOLINK> ) + +# Extra configuration for Apple targets -- set xcode attributes +if(APPLE) + set_target_properties(lsl PROPERTIES + XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "org.labstreaminglayer.liblsl" + ) + # If environment variables are set for Apple Development Team and Code Sign Identity then add these to the target + # -> if `-G Xcode` generator is used then Xcode will use these variables to sign the framework. + # Note, however, that it is likely that the build products will be modified post-build, invalidating the signature, + # so post-hoc signing will be required. Nevertheless, this is useful for initial signing and normal Xcode workflow. + if(DEFINED ENV{APPLE_DEVELOPMENT_TEAM} AND DEFINED ENV{APPLE_CODE_SIGN_IDENTITY_APP}) + set_target_properties(lsl PROPERTIES + XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY $ENV{APPLE_CODE_SIGN_IDENTITY_APP} + XCODE_ATTRIBUTE_DEVELOPMENT_TEAM $ENV{APPLE_DEVELOPMENT_TEAM} + XCODE_ATTRIBUTE_CODE_SIGN_STYLE "Manual" + XCODE_ATTRIBUTE_DEPLOYMENT_POSTPROCESSING YES # this is needed for strip symbols + XCODE_ATTRIBUTE_OTHER_CODE_SIGN_FLAGS "--deep" + ) + endif() + # Configure Apple Framework + if(LSL_FRAMEWORK) + set_target_properties(lsl PROPERTIES + FRAMEWORK TRUE + FRAMEWORK_VERSION A # Ignored on iOS + MACOSX_FRAMEWORK_IDENTIFIER "org.labstreaminglayer.liblsl" + MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${liblsl_VERSION_MAJOR}.${liblsl_VERSION_MINOR}" + MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION} + XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/lsl.entitlements" + ) + endif(LSL_FRAMEWORK) +endif(APPLE) diff --git a/cmake/TargetObjLib.cmake b/cmake/TargetObjLib.cmake index 4e32ef79f..844e12679 100644 --- a/cmake/TargetObjLib.cmake +++ b/cmake/TargetObjLib.cmake @@ -1,18 +1,16 @@ # Create object library so all files are only compiled once add_library(lslobj OBJECT ${lslsources} -# ${lslheaders} # Headers are added later using FILE_SET + ${lslheaders} ) # Set the includes/headers for the lslobj target -# Note: We cannot use the PUBLIC_HEADER property of the target, -# because it flattens the include directories. -# Note: IME, this approach is less error prone than target_include_directories -target_sources(lslobj - INTERFACE - FILE_SET HEADERS # special set name; implies TYPE. - BASE_DIRS include - FILES ${lslheaders} +# Note: We cannot use PUBLIC_HEADER because it flattens the include tree upon install +# Note: We cannot use FILE_SET because it is not compatible with HEADERS. +target_include_directories(lslobj + PUBLIC + $ + $ # For targets that link to the installed lslobj ) # Link system libs @@ -59,30 +57,6 @@ if(WIN32) endif(BUILD_SHARED_LIBS) endif() -# Compiler settings -target_compile_definitions(lslobj - PRIVATE - LIBLSL_EXPORTS - LOGURU_DEBUG_LOGGING=$ - PUBLIC - ASIO_NO_DEPRECATED - $<$:LSLNOAUTOLINK> # don't use #pragma(lib) in CMake builds -) -if(WIN32) - target_compile_definitions(lslobj - PRIVATE - _CRT_SECURE_NO_WARNINGS - PUBLIC - _WIN32_WINNT=${LSL_WINVER} - ) - if(BUILD_SHARED_LIBS) - # set_target_properties(lslobj - # PROPERTIES - # WINDOWS_EXPORT_ALL_SYMBOLS ON - # ) - endif(BUILD_SHARED_LIBS) -endif(WIN32) - # Link in 3rd party dependencies # - loguru and asio header-only target_include_directories(lslobj diff --git a/cmake/TargetOther.cmake b/cmake/TargetOther.cmake index 9900f4b34..924d5e1b9 100644 --- a/cmake/TargetOther.cmake +++ b/cmake/TargetOther.cmake @@ -1,13 +1,16 @@ -include(cmake/LSLCMake.cmake) # Needed for `installLSLApp` +include(cmake/LSLCMake.cmake) # Needed for `installLSLApp` and `LSLGenerateCPackConfig` -# Build utilities + # Build utilities add_executable(lslver testing/lslver.c) target_link_libraries(lslver PRIVATE lsl) +if(NOT IOS) installLSLApp(lslver) - +endif(NOT IOS) if(NOT WIN32 AND LSL_TOOLS) add_executable(blackhole testing/blackhole.cpp) target_link_libraries(blackhole PRIVATE Threads::Threads) target_include_directories(blackhole PRIVATE "thirdparty/asio/") - installLSLApp(blackhole) + if(NOT IOS) + installLSLApp(blackhole) + endif(NOT IOS) endif() diff --git a/cmake/ios.toolchain.cmake b/cmake/ios.toolchain.cmake new file mode 100644 index 000000000..abaa47600 --- /dev/null +++ b/cmake/ios.toolchain.cmake @@ -0,0 +1,1177 @@ +# This file is part of the ios-cmake project. It was retrieved from +# https://github.com/leetal/ios-cmake.git, which is a fork of +# https://github.com/gerstrong/ios-cmake.git, which is a fork of +# https://github.com/cristeab/ios-cmake.git, which is a fork of +# https://code.google.com/p/ios-cmake/. Which in turn is based off of +# the Platform/Darwin.cmake and Platform/UnixPaths.cmake files which +# are included with CMake 2.8.4 +# +# The ios-cmake project is licensed under the new BSD license. +# +# Copyright (c) 2014, Bogdan Cristea and LTE Engineering Software, +# Kitware, Inc., Insight Software Consortium. All rights reserved. +# 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. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 +# COPYRIGHT HOLDER 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. +# +# This file is based on the Platform/Darwin.cmake and +# Platform/UnixPaths.cmake files which are included with CMake 2.8.4 +# It has been altered for iOS development. +# +# Updated by Alex Stewart (alexs.mac@gmail.com) +# +# ***************************************************************************** +# Now maintained by Alexander Widerberg (widerbergaren [at] gmail.com) +# under the BSD-3-Clause license +# https://github.com/leetal/ios-cmake +# ***************************************************************************** +# +# INFORMATION / HELP +# +############################################################################### +# OPTIONS # +############################################################################### +# +# PLATFORM: (default "OS64") +# OS = Build for iPhoneOS. +# OS64 = Build for arm64 iphoneOS. +# OS64COMBINED = Build for arm64 x86_64 iphoneOS + iphoneOS Simulator. Combined into FAT STATIC lib (only supported on 3.14+ of CMake with "-G Xcode" argument in combination with the "cmake --install" CMake build step) +# SIMULATOR = Build for x86 i386 iphoneOS Simulator. +# SIMULATOR64 = Build for x86_64 iphoneOS Simulator. +# SIMULATORARM64 = Build for arm64 iphoneOS Simulator. +# SIMULATOR64COMBINED = Build for arm64 x86_64 iphoneOS Simulator. Combined into FAT STATIC lib (supported on 3.14+ of CMakewith "-G Xcode" argument ONLY) +# TVOS = Build for arm64 tvOS. +# TVOSCOMBINED = Build for arm64 x86_64 tvOS + tvOS Simulator. Combined into FAT STATIC lib (only supported on 3.14+ of CMake with "-G Xcode" argument in combination with the "cmake --install" CMake build step) +# SIMULATOR_TVOS = Build for x86_64 tvOS Simulator. +# SIMULATORARM64_TVOS = Build for arm64 tvOS Simulator. +# VISIONOSCOMBINED = Build for arm64 visionOS + visionOS Simulator. Combined into FAT STATIC lib (only supported on 3.14+ of CMake with "-G Xcode" argument in combination with the "cmake --install" CMake build step) +# VISIONOS = Build for arm64 visionOS. +# SIMULATOR_VISIONOS = Build for arm64 visionOS Simulator. +# WATCHOS = Build for armv7k arm64_32 for watchOS. +# WATCHOSCOMBINED = Build for armv7k arm64_32 x86_64 watchOS + watchOS Simulator. Combined into FAT STATIC lib (only supported on 3.14+ of CMake with "-G Xcode" argument in combination with the "cmake --install" CMake build step) +# SIMULATOR_WATCHOS = Build for x86_64 for watchOS Simulator. +# SIMULATORARM64_WATCHOS = Build for arm64 for watchOS Simulator. +# SIMULATOR_WATCHOSCOMBINED = Build for arm64 x86_64 for watchOS Simulator. Combined into FAT STATIC lib (supported on 3.14+ of CMakewith "-G Xcode" argument ONLY) +# MAC = Build for x86_64 macOS. +# MAC_ARM64 = Build for Apple Silicon macOS. +# MAC_UNIVERSAL = Combined build for x86_64 and Apple Silicon on macOS. +# MAC_CATALYST = Build for x86_64 macOS with Catalyst support (iOS toolchain on macOS). +# Note: The build argument "MACOSX_DEPLOYMENT_TARGET" can be used to control min-version of macOS +# MAC_CATALYST_ARM64 = Build for Apple Silicon macOS with Catalyst support (iOS toolchain on macOS). +# Note: The build argument "MACOSX_DEPLOYMENT_TARGET" can be used to control min-version of macOS +# MAC_CATALYST_UNIVERSAL = Combined build for x86_64 and Apple Silicon on Catalyst. +# +# CMAKE_OSX_SYSROOT: Path to the SDK to use. By default this is +# automatically determined from PLATFORM and xcodebuild, but +# can also be manually specified (although this should not be required). +# +# CMAKE_DEVELOPER_ROOT: Path to the Developer directory for the platform +# being compiled for. By default, this is automatically determined from +# CMAKE_OSX_SYSROOT, but can also be manually specified (although this should +# not be required). +# +# DEPLOYMENT_TARGET: Minimum SDK version to target. Default 6.0 on watchOS, 13.0 on tvOS+iOS/iPadOS, 11.0 on macOS, 1.0 on visionOS +# +# NAMED_LANGUAGE_SUPPORT: +# ON (default) = Will require "enable_language(OBJC) and/or enable_language(OBJCXX)" for full OBJC|OBJCXX support +# OFF = Will embed the OBJC and OBJCXX flags into the CMAKE_C_FLAGS and CMAKE_CXX_FLAGS (legacy behavior, CMake version < 3.16) +# +# ENABLE_BITCODE: (ON|OFF) Enables or disables bitcode support. Default OFF +# +# ENABLE_ARC: (ON|OFF) Enables or disables ARC support. Default ON (ARC enabled by default) +# +# ENABLE_VISIBILITY: (ON|OFF) Enables or disables symbol visibility support. Default OFF (visibility hidden by default) +# +# ENABLE_STRICT_TRY_COMPILE: (ON|OFF) Enables or disables strict try_compile() on all Check* directives (will run linker +# to actually check if linking is possible). Default OFF (will set CMAKE_TRY_COMPILE_TARGET_TYPE to STATIC_LIBRARY) +# +# ARCHS: (armv7 armv7s armv7k arm64 arm64_32 i386 x86_64) If specified, will override the default architectures for the given PLATFORM +# OS = armv7 armv7s arm64 (if applicable) +# OS64 = arm64 (if applicable) +# SIMULATOR = i386 +# SIMULATOR64 = x86_64 +# SIMULATORARM64 = arm64 +# TVOS = arm64 +# SIMULATOR_TVOS = x86_64 (i386 has since long been deprecated) +# SIMULATORARM64_TVOS = arm64 +# WATCHOS = armv7k arm64_32 (if applicable) +# SIMULATOR_WATCHOS = x86_64 (i386 has since long been deprecated) +# SIMULATORARM64_WATCHOS = arm64 +# MAC = x86_64 +# MAC_ARM64 = arm64 +# MAC_UNIVERSAL = x86_64 arm64 +# MAC_CATALYST = x86_64 +# MAC_CATALYST_ARM64 = arm64 +# MAC_CATALYST_UNIVERSAL = x86_64 arm64 +# +# NOTE: When manually specifying ARCHS, put a semi-colon between the entries. E.g., -DARCHS="armv7;arm64" +# +############################################################################### +# END OPTIONS # +############################################################################### +# +# This toolchain defines the following properties (available via get_property()) for use externally: +# +# PLATFORM: The currently targeted platform. +# XCODE_VERSION: Version number (not including Build version) of Xcode detected. +# SDK_VERSION: Version of SDK being used. +# OSX_ARCHITECTURES: Architectures being compiled for (generated from PLATFORM). +# APPLE_TARGET_TRIPLE: Used by autoconf build systems. NOTE: If "ARCHS" is overridden, this will *NOT* be set! +# +# This toolchain defines the following macros for use externally: +# +# set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE XCODE_VARIANT) +# A convenience macro for setting xcode specific properties on targets. +# Available variants are: All, Release, RelWithDebInfo, Debug, MinSizeRel +# example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1" "all"). +# +# find_host_package (PROGRAM ARGS) +# A macro used to find executable programs on the host system, not within the +# environment. Thanks to the android-cmake project for providing the +# command. +# + +cmake_minimum_required(VERSION 3.10.0) + +# CMake invokes the toolchain file twice during the first build, but only once during subsequent rebuilds. +# NOTE: To improve single-library build-times, provide the flag "OS_SINGLE_BUILD" as a build argument. +if(DEFINED OS_SINGLE_BUILD AND DEFINED ENV{_IOS_TOOLCHAIN_HAS_RUN}) + return() +endif() +set(ENV{_IOS_TOOLCHAIN_HAS_RUN} true) + +# List of supported platform values +list(APPEND _supported_platforms + "OS" "OS64" "OS64COMBINED" "SIMULATOR" "SIMULATOR64" "SIMULATORARM64" "SIMULATOR64COMBINED" + "TVOS" "TVOSCOMBINED" "SIMULATOR_TVOS" "SIMULATORARM64_TVOS" + "WATCHOS" "WATCHOSCOMBINED" "SIMULATOR_WATCHOS" "SIMULATORARM64_WATCHOS" "SIMULATOR_WATCHOSCOMBINED" + "MAC" "MAC_ARM64" "MAC_UNIVERSAL" + "VISIONOS" "SIMULATOR_VISIONOS" "VISIONOSCOMBINED" + "MAC_CATALYST" "MAC_CATALYST_ARM64" "MAC_CATALYST_UNIVERSAL") + +# Cache what generator is used +set(USED_CMAKE_GENERATOR "${CMAKE_GENERATOR}") + +# Check if using a CMake version capable of building combined FAT builds (simulator and target slices combined in one static lib) +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14") + set(MODERN_CMAKE YES) +endif() + +# Get the Xcode version being used. +# Problem: CMake runs toolchain files multiple times, but can't read cache variables on some runs. +# Workaround: On the first run (in which cache variables are always accessible), set an intermediary environment variable. +# +# NOTE: This pattern is used in many places in this toolchain to speed up checks of all sorts +if(DEFINED XCODE_VERSION_INT) + # Environment variables are always preserved. + set(ENV{_XCODE_VERSION_INT} "${XCODE_VERSION_INT}") +elseif(DEFINED ENV{_XCODE_VERSION_INT}) + set(XCODE_VERSION_INT "$ENV{_XCODE_VERSION_INT}") +elseif(NOT DEFINED XCODE_VERSION_INT) + find_program(XCODEBUILD_EXECUTABLE xcodebuild) + if(NOT XCODEBUILD_EXECUTABLE) + message(FATAL_ERROR "xcodebuild not found. Please install either the standalone commandline tools or Xcode.") + endif() + execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -version + OUTPUT_VARIABLE XCODE_VERSION_INT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION_INT "${XCODE_VERSION_INT}") + string(REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION_INT "${XCODE_VERSION_INT}") + set(XCODE_VERSION_INT "${XCODE_VERSION_INT}" CACHE INTERNAL "") +endif() + +# Assuming that xcode 12.0 is installed you most probably have ios sdk 14.0 or later installed (tested on Big Sur) +# if you don't set a deployment target it will be set the way you only get 64-bit builds +#if(NOT DEFINED DEPLOYMENT_TARGET AND XCODE_VERSION_INT VERSION_GREATER 12.0) +# Temporarily fix the arm64 issues in CMake install-combined by excluding arm64 for simulator builds (needed for Apple Silicon...) +# set(CMAKE_XCODE_ATTRIBUTE_EXCLUDED_ARCHS[sdk=iphonesimulator*] "arm64") +#endif() + +# Check if the platform variable is set +if(DEFINED PLATFORM) + # Environment variables are always preserved. + set(ENV{_PLATFORM} "${PLATFORM}") +elseif(DEFINED ENV{_PLATFORM}) + set(PLATFORM "$ENV{_PLATFORM}") +elseif(NOT DEFINED PLATFORM) + message(FATAL_ERROR "PLATFORM argument not set. Bailing configure since I don't know what target you want to build for!") +endif () + +if(PLATFORM MATCHES ".*COMBINED" AND NOT CMAKE_GENERATOR MATCHES "Xcode") + message(FATAL_ERROR "The combined builds support requires Xcode to be used as a generator via '-G Xcode' command-line argument in CMake") +endif() + +# Safeguard that the platform value is set and is one of the supported values +list(FIND _supported_platforms ${PLATFORM} contains_PLATFORM) +if("${contains_PLATFORM}" EQUAL "-1") + string(REPLACE ";" "\n * " _supported_platforms_formatted "${_supported_platforms}") + message(FATAL_ERROR " Invalid PLATFORM specified! Current value: ${PLATFORM}.\n" + " Supported PLATFORM values: \n * ${_supported_platforms_formatted}") +endif() + +# Check if Apple Silicon is supported +if(PLATFORM MATCHES "^(MAC_ARM64)$|^(MAC_CATALYST_ARM64)$|^(MAC_UNIVERSAL)$|^(MAC_CATALYST_UNIVERSAL)$" AND ${CMAKE_VERSION} VERSION_LESS "3.19.5") + message(FATAL_ERROR "Apple Silicon builds requires a minimum of CMake 3.19.5") +endif() + +# Touch the toolchain variable to suppress the "unused variable" warning. +# This happens if CMake is invoked with the same command line the second time. +if(CMAKE_TOOLCHAIN_FILE) +endif() + +# Fix for PThread library not in path +set(CMAKE_THREAD_LIBS_INIT "-lpthread") +set(CMAKE_HAVE_THREADS_LIBRARY 1) +set(CMAKE_USE_WIN32_THREADS_INIT 0) +set(CMAKE_USE_PTHREADS_INIT 1) + +# Specify named language support defaults. +if(NOT DEFINED NAMED_LANGUAGE_SUPPORT AND ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16") + set(NAMED_LANGUAGE_SUPPORT ON) + message(STATUS "[DEFAULTS] Using explicit named language support! E.g., enable_language(CXX) is needed in the project files.") +elseif(NOT DEFINED NAMED_LANGUAGE_SUPPORT AND ${CMAKE_VERSION} VERSION_LESS "3.16") + set(NAMED_LANGUAGE_SUPPORT OFF) + message(STATUS "[DEFAULTS] Disabling explicit named language support. Falling back to legacy behavior.") +elseif(DEFINED NAMED_LANGUAGE_SUPPORT AND ${CMAKE_VERSION} VERSION_LESS "3.16") + message(FATAL_ERROR "CMake named language support for OBJC and OBJCXX was added in CMake 3.16.") +endif() +set(NAMED_LANGUAGE_SUPPORT_INT ${NAMED_LANGUAGE_SUPPORT} CACHE BOOL + "Whether or not to enable explicit named language support" FORCE) + +# Specify the minimum version of the deployment target. +if(NOT DEFINED DEPLOYMENT_TARGET) + if (PLATFORM MATCHES "WATCHOS") + # Unless specified, SDK version 6.0 is used by default as minimum target version (watchOS). + set(DEPLOYMENT_TARGET "6.0") + elseif(PLATFORM STREQUAL "MAC") + # Unless specified, SDK version 11.0 (Big Sur) is used by default as the minimum target version (macOS on x86). + set(DEPLOYMENT_TARGET "11.0") + elseif(PLATFORM STREQUAL "VISIONOS" OR PLATFORM STREQUAL "SIMULATOR_VISIONOS" OR PLATFORM STREQUAL "VISIONOSCOMBINED") + # Unless specified, SDK version 1.0 is used by default as minimum target version (visionOS). + set(DEPLOYMENT_TARGET "1.0") + elseif(PLATFORM STREQUAL "MAC_ARM64") + # Unless specified, SDK version 11.0 (Big Sur) is used by default as the minimum target version (macOS on arm). + set(DEPLOYMENT_TARGET "11.0") + elseif(PLATFORM STREQUAL "MAC_UNIVERSAL") + # Unless specified, SDK version 11.0 (Big Sur) is used by default as minimum target version for universal builds. + set(DEPLOYMENT_TARGET "11.0") + elseif(PLATFORM STREQUAL "MAC_CATALYST" OR PLATFORM STREQUAL "MAC_CATALYST_ARM64" OR PLATFORM STREQUAL "MAC_CATALYST_UNIVERSAL") + # Unless specified, SDK version 13.1 is used by default as the minimum target version (mac catalyst minimum requirement). + set(DEPLOYMENT_TARGET "13.1") + else() + # Unless specified, SDK version 13.0 is used by default as the minimum target version (iOS, tvOS). + set(DEPLOYMENT_TARGET "13.0") + endif() + message(STATUS "[DEFAULTS] Using the default min-version since DEPLOYMENT_TARGET not provided!") +elseif(DEFINED DEPLOYMENT_TARGET AND PLATFORM MATCHES "^MAC_CATALYST" AND ${DEPLOYMENT_TARGET} VERSION_LESS "13.1") + message(FATAL_ERROR "Mac Catalyst builds requires a minimum deployment target of 13.1!") +endif() + +# Store the DEPLOYMENT_TARGET in the cache +set(DEPLOYMENT_TARGET "${DEPLOYMENT_TARGET}" CACHE INTERNAL "") + +# Handle the case where we are targeting iOS and a version above 10.3.4 (32-bit support dropped officially) +if(PLATFORM STREQUAL "OS" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.3.4) + set(PLATFORM "OS64") + message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.") +elseif(PLATFORM STREQUAL "SIMULATOR" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.3.4) + set(PLATFORM "SIMULATOR64") + message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.") +endif() + +set(PLATFORM_INT "${PLATFORM}") + +if(DEFINED ARCHS) + string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") +endif() + +# Determine the platform name and architectures for use in xcodebuild commands +# from the specified PLATFORM_INT name. +if(PLATFORM_INT STREQUAL "OS") + set(SDK_NAME iphoneos) + if(NOT ARCHS) + set(ARCHS armv7 armv7s arm64) + set(APPLE_TARGET_TRIPLE_INT arm-apple-ios${DEPLOYMENT_TARGET}) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}) + endif() +elseif(PLATFORM_INT STREQUAL "OS64") + set(SDK_NAME iphoneos) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 10.0) + set(ARCHS arm64) # FIXME: Add arm64e when Apple has fixed the integration issues with it, libarclite_iphoneos.a is currently missing bitcode markers for example + else() + set(ARCHS arm64) + endif() + set(APPLE_TARGET_TRIPLE_INT arm64-apple-ios${DEPLOYMENT_TARGET}) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}) + endif() +elseif(PLATFORM_INT STREQUAL "OS64COMBINED") + set(SDK_NAME iphoneos) + if(MODERN_CMAKE) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 12.0) + set(ARCHS arm64 x86_64) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64 arm64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64 arm64") + else() + set(ARCHS arm64 x86_64) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64") + endif() + set(APPLE_TARGET_TRIPLE_INT arm64-x86_64-apple-ios${DEPLOYMENT_TARGET}) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the OS64COMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR64COMBINED") + set(SDK_NAME iphonesimulator) + if(MODERN_CMAKE) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 12.0) + set(ARCHS arm64 x86_64) # FIXME: Add arm64e when Apple have fixed the integration issues with it, libarclite_iphoneos.a is currently missing bitcode markers for example + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64 arm64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64 arm64") + else() + set(ARCHS arm64 x86_64) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "x86_64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "x86_64") + endif() + set(APPLE_TARGET_TRIPLE_INT aarch64-x86_64-apple-ios${DEPLOYMENT_TARGET}-simulator) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-simulator) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the SIMULATOR64COMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR") + set(SDK_NAME iphonesimulator) + if(NOT ARCHS) + set(ARCHS i386) + set(APPLE_TARGET_TRIPLE_INT i386-apple-ios${DEPLOYMENT_TARGET}-simulator) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-simulator) + endif() + message(DEPRECATION "SIMULATOR IS DEPRECATED. Consider using SIMULATOR64 instead.") +elseif(PLATFORM_INT STREQUAL "SIMULATOR64") + set(SDK_NAME iphonesimulator) + if(NOT ARCHS) + set(ARCHS x86_64) + set(APPLE_TARGET_TRIPLE_INT x86_64-apple-ios${DEPLOYMENT_TARGET}-simulator) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-simulator) + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATORARM64") + set(SDK_NAME iphonesimulator) + if(NOT ARCHS) + set(ARCHS arm64) + set(APPLE_TARGET_TRIPLE_INT arm64-apple-ios${DEPLOYMENT_TARGET}-simulator) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-simulator) + endif() +elseif(PLATFORM_INT STREQUAL "TVOS") + set(SDK_NAME appletvos) + if(NOT ARCHS) + set(ARCHS arm64) + set(APPLE_TARGET_TRIPLE_INT arm64-apple-tvos${DEPLOYMENT_TARGET}) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos${DEPLOYMENT_TARGET}) + endif() +elseif (PLATFORM_INT STREQUAL "TVOSCOMBINED") + set(SDK_NAME appletvos) + if(MODERN_CMAKE) + if(NOT ARCHS) + set(ARCHS arm64 x86_64) + set(APPLE_TARGET_TRIPLE_INT arm64-x86_64-apple-tvos${DEPLOYMENT_TARGET}) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=appletvos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=appletvsimulator*] "x86_64 arm64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=appletvos*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=appletvsimulator*] "x86_64 arm64") + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos${DEPLOYMENT_TARGET}) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the TVOSCOMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS") + set(SDK_NAME appletvsimulator) + if(NOT ARCHS) + set(ARCHS x86_64) + set(APPLE_TARGET_TRIPLE_INT x86_64-apple-tvos${DEPLOYMENT_TARGET}-simulator) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos${DEPLOYMENT_TARGET}-simulator) + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATORARM64_TVOS") + set(SDK_NAME appletvsimulator) + if(NOT ARCHS) + set(ARCHS arm64) + set(APPLE_TARGET_TRIPLE_INT arm64-apple-tvos${DEPLOYMENT_TARGET}-simulator) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-tvos${DEPLOYMENT_TARGET}-simulator) + endif() +elseif(PLATFORM_INT STREQUAL "WATCHOS") + set(SDK_NAME watchos) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 10.0) + set(ARCHS armv7k arm64_32) + set(APPLE_TARGET_TRIPLE_INT arm64_32-apple-watchos${DEPLOYMENT_TARGET}) + else() + set(ARCHS armv7k) + set(APPLE_TARGET_TRIPLE_INT arm-apple-watchos${DEPLOYMENT_TARGET}) + endif() + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos${DEPLOYMENT_TARGET}) + endif() +elseif(PLATFORM_INT STREQUAL "WATCHOSCOMBINED") + set(SDK_NAME watchos) + if(MODERN_CMAKE) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 10.0) + set(ARCHS armv7k arm64_32 x86_64) + set(APPLE_TARGET_TRIPLE_INT arm64_32-x86_64-apple-watchos${DEPLOYMENT_TARGET}) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchos*] "armv7k arm64_32") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchsimulator*] "x86_64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchos*] "armv7k arm64_32") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchsimulator*] "x86_64") + else() + set(ARCHS armv7k i386) + set(APPLE_TARGET_TRIPLE_INT arm-i386-apple-watchos${DEPLOYMENT_TARGET}) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchos*] "armv7k") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchsimulator*] "i386") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchos*] "armv7k") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchsimulator*] "i386") + endif() + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos${DEPLOYMENT_TARGET}) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the WATCHOSCOMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") + set(SDK_NAME watchsimulator) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 10.0) + set(ARCHS x86_64) + set(APPLE_TARGET_TRIPLE_INT x86_64-apple-watchos${DEPLOYMENT_TARGET}-simulator) + else() + set(ARCHS i386) + set(APPLE_TARGET_TRIPLE_INT i386-apple-watchos${DEPLOYMENT_TARGET}-simulator) + endif() + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos${DEPLOYMENT_TARGET}-simulator) + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATORARM64_WATCHOS") + set(SDK_NAME watchsimulator) + if(NOT ARCHS) + set(ARCHS arm64) + set(APPLE_TARGET_TRIPLE_INT arm64-apple-watchos${DEPLOYMENT_TARGET}-simulator) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos${DEPLOYMENT_TARGET}-simulator) + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOSCOMBINED") + set(SDK_NAME watchsimulator) + if(MODERN_CMAKE) + if(NOT ARCHS) + if (XCODE_VERSION_INT VERSION_GREATER 12.0) + set(ARCHS arm64 x86_64) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchos*] "") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchsimulator*] "arm64 x86_64") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchos*] "") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchsimulator*] "arm64 x86_64") + set(APPLE_TARGET_TRIPLE_INT arm64_x86_64-apple-watchos${DEPLOYMENT_TARGET}-simulator) + else() + set(ARCHS arm64 i386) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchos*] "") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=watchsimulator*] "i386") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchos*] "") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=watchsimulator*] "i386") + set(APPLE_TARGET_TRIPLE_INT arm64_i386-apple-watchos${DEPLOYMENT_TARGET}-simulator) + endif() + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-watchos${DEPLOYMENT_TARGET}-simulator) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the SIMULATOR_WATCHOSCOMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR_VISIONOS") + set(SDK_NAME xrsimulator) + if(NOT ARCHS) + set(ARCHS arm64) + set(APPLE_TARGET_TRIPLE_INT arm64-apple-xros${DEPLOYMENT_TARGET}-simulator) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-xros${DEPLOYMENT_TARGET}-simulator) + endif() +elseif(PLATFORM_INT STREQUAL "VISIONOS") + set(SDK_NAME xros) + if(NOT ARCHS) + set(ARCHS arm64) + set(APPLE_TARGET_TRIPLE_INT arm64-apple-xros${DEPLOYMENT_TARGET}) + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-xros${DEPLOYMENT_TARGET}) + endif() +elseif(PLATFORM_INT STREQUAL "VISIONOSCOMBINED") + set(SDK_NAME xros) + if(MODERN_CMAKE) + if(NOT ARCHS) + set(ARCHS arm64) + set(APPLE_TARGET_TRIPLE_INT arm64-apple-xros${DEPLOYMENT_TARGET}) + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=xros*] "arm64") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=xrsimulator*] "arm64") + else() + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-xros${DEPLOYMENT_TARGET}) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the VISIONOSCOMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "MAC" OR PLATFORM_INT STREQUAL "MAC_CATALYST") + set(SDK_NAME macosx) + if(NOT ARCHS) + set(ARCHS x86_64) + endif() + string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") + if(PLATFORM_INT STREQUAL "MAC") + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-macosx${DEPLOYMENT_TARGET}) + elseif(PLATFORM_INT STREQUAL "MAC_CATALYST") + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-macabi) + endif() +elseif(PLATFORM_INT MATCHES "^(MAC_ARM64)$|^(MAC_CATALYST_ARM64)$") + set(SDK_NAME macosx) + if(NOT ARCHS) + set(ARCHS arm64) + endif() + string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") + if(PLATFORM_INT STREQUAL "MAC_ARM64") + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-macosx${DEPLOYMENT_TARGET}) + elseif(PLATFORM_INT STREQUAL "MAC_CATALYST_ARM64") + set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-ios${DEPLOYMENT_TARGET}-macabi) + endif() +elseif(PLATFORM_INT STREQUAL "MAC_UNIVERSAL") + set(SDK_NAME macosx) + if(NOT ARCHS) + set(ARCHS "x86_64;arm64") + endif() + # For universal builds, don't set target triple - let CMake handle it + # string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") + # set(APPLE_TARGET_TRIPLE_INT ${ARCHS_SPLIT}-apple-macosx${DEPLOYMENT_TARGET}) +elseif(PLATFORM_INT STREQUAL "MAC_CATALYST_UNIVERSAL") + set(SDK_NAME macosx) + if(NOT ARCHS) + set(ARCHS "x86_64;arm64") + endif() + string(REPLACE ";" "-" ARCHS_SPLIT "${ARCHS}") + set(APPLE_TARGET_TRIPLE_INT apple-ios${DEPLOYMENT_TARGET}-macabi) +else() + message(FATAL_ERROR "Invalid PLATFORM: ${PLATFORM_INT}") +endif() + +string(REPLACE ";" " " ARCHS_SPACED "${ARCHS}") + +if(MODERN_CMAKE AND PLATFORM_INT MATCHES ".*COMBINED" AND NOT CMAKE_GENERATOR MATCHES "Xcode") + message(FATAL_ERROR "The COMBINED options only work with Xcode generator, -G Xcode") +endif() + +if(CMAKE_GENERATOR MATCHES "Xcode" AND PLATFORM_INT MATCHES "^MAC_CATALYST") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + set(CMAKE_XCODE_ATTRIBUTE_SUPPORTED_PLATFORMS "macosx") + set(CMAKE_XCODE_ATTRIBUTE_SUPPORTS_MACCATALYST "YES") + if(NOT DEFINED MACOSX_DEPLOYMENT_TARGET) + set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET "10.15") + else() + set(CMAKE_XCODE_ATTRIBUTE_MACOSX_DEPLOYMENT_TARGET "${MACOSX_DEPLOYMENT_TARGET}") + endif() +elseif(CMAKE_GENERATOR MATCHES "Xcode") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") + set(CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "${DEPLOYMENT_TARGET}") + if(NOT PLATFORM_INT MATCHES ".*COMBINED") + set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=${SDK_NAME}*] "${ARCHS_SPACED}") + set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=${SDK_NAME}*] "${ARCHS_SPACED}") + endif() +endif() + +# If the user did not specify the SDK root to use, then query xcodebuild for it. +if(DEFINED CMAKE_OSX_SYSROOT_INT) + # Environment variables are always preserved. + set(ENV{_CMAKE_OSX_SYSROOT_INT} "${CMAKE_OSX_SYSROOT_INT}") +elseif(DEFINED ENV{_CMAKE_OSX_SYSROOT_INT}) + set(CMAKE_OSX_SYSROOT_INT "$ENV{_CMAKE_OSX_SYSROOT_INT}") +elseif(NOT DEFINED CMAKE_OSX_SYSROOT_INT) + execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -version -sdk ${SDK_NAME} Path + OUTPUT_VARIABLE CMAKE_OSX_SYSROOT_INT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +if (NOT DEFINED CMAKE_OSX_SYSROOT_INT AND NOT DEFINED CMAKE_OSX_SYSROOT) + message(SEND_ERROR "Please make sure that Xcode is installed and that the toolchain" + "is pointing to the correct path. Please run:" + "sudo xcode-select -s /Applications/Xcode.app/Contents/Developer" + "and see if that fixes the problem for you.") + message(FATAL_ERROR "Invalid CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT} " + "does not exist.") +elseif(DEFINED CMAKE_OSX_SYSROOT_INT) + set(CMAKE_OSX_SYSROOT_INT "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") + # Specify the location or name of the platform SDK to be used in CMAKE_OSX_SYSROOT. + set(CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") +endif() + +# Use bitcode or not +if(NOT DEFINED ENABLE_BITCODE) + message(STATUS "[DEFAULTS] Disabling bitcode support by default. ENABLE_BITCODE not provided for override!") + set(ENABLE_BITCODE OFF) +endif() +set(ENABLE_BITCODE_INT ${ENABLE_BITCODE} CACHE BOOL + "Whether or not to enable bitcode" FORCE) +# Use ARC or not +if(NOT DEFINED ENABLE_ARC) + # Unless specified, enable ARC support by default + set(ENABLE_ARC ON) + message(STATUS "[DEFAULTS] Enabling ARC support by default. ENABLE_ARC not provided!") +endif() +set(ENABLE_ARC_INT ${ENABLE_ARC} CACHE BOOL "Whether or not to enable ARC" FORCE) +# Use hidden visibility or not +if(NOT DEFINED ENABLE_VISIBILITY) + # Unless specified, disable symbols visibility by default + set(ENABLE_VISIBILITY OFF) + message(STATUS "[DEFAULTS] Hiding symbols visibility by default. ENABLE_VISIBILITY not provided!") +endif() +set(ENABLE_VISIBILITY_INT ${ENABLE_VISIBILITY} CACHE BOOL "Whether or not to hide symbols from the dynamic linker (-fvisibility=hidden)" FORCE) +# Set strict compiler checks or not +if(NOT DEFINED ENABLE_STRICT_TRY_COMPILE) + # Unless specified, disable strict try_compile() + set(ENABLE_STRICT_TRY_COMPILE OFF) + message(STATUS "[DEFAULTS] Using NON-strict compiler checks by default. ENABLE_STRICT_TRY_COMPILE not provided!") +endif() +set(ENABLE_STRICT_TRY_COMPILE_INT ${ENABLE_STRICT_TRY_COMPILE} CACHE BOOL + "Whether or not to use strict compiler checks" FORCE) + +# Get the SDK version information. +if(DEFINED SDK_VERSION) + # Environment variables are always preserved. + set(ENV{_SDK_VERSION} "${SDK_VERSION}") +elseif(DEFINED ENV{_SDK_VERSION}) + set(SDK_VERSION "$ENV{_SDK_VERSION}") +elseif(NOT DEFINED SDK_VERSION) + execute_process(COMMAND ${XCODEBUILD_EXECUTABLE} -sdk ${CMAKE_OSX_SYSROOT_INT} -version SDKVersion + OUTPUT_VARIABLE SDK_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() + +# Find the Developer root for the specific iOS platform being compiled for +# from CMAKE_OSX_SYSROOT. Should be ../../ from SDK specified in +# CMAKE_OSX_SYSROOT. There does not appear to be a direct way to obtain +# this information from xcrun or xcodebuild. +if (NOT DEFINED CMAKE_DEVELOPER_ROOT AND NOT CMAKE_GENERATOR MATCHES "Xcode") + get_filename_component(PLATFORM_SDK_DIR ${CMAKE_OSX_SYSROOT_INT} PATH) + get_filename_component(CMAKE_DEVELOPER_ROOT ${PLATFORM_SDK_DIR} PATH) + if (NOT EXISTS "${CMAKE_DEVELOPER_ROOT}") + message(FATAL_ERROR "Invalid CMAKE_DEVELOPER_ROOT: ${CMAKE_DEVELOPER_ROOT} does not exist.") + endif() +endif() + +# Find the C & C++ compilers for the specified SDK. +if(DEFINED CMAKE_C_COMPILER) + # Environment variables are always preserved. + set(ENV{_CMAKE_C_COMPILER} "${CMAKE_C_COMPILER}") +elseif(DEFINED ENV{_CMAKE_C_COMPILER}) + set(CMAKE_C_COMPILER "$ENV{_CMAKE_C_COMPILER}") + set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +elseif(NOT DEFINED CMAKE_C_COMPILER) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find clang + OUTPUT_VARIABLE CMAKE_C_COMPILER + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +endif() +if(DEFINED CMAKE_CXX_COMPILER) + # Environment variables are always preserved. + set(ENV{_CMAKE_CXX_COMPILER} "${CMAKE_CXX_COMPILER}") +elseif(DEFINED ENV{_CMAKE_CXX_COMPILER}) + set(CMAKE_CXX_COMPILER "$ENV{_CMAKE_CXX_COMPILER}") +elseif(NOT DEFINED CMAKE_CXX_COMPILER) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find clang++ + OUTPUT_VARIABLE CMAKE_CXX_COMPILER + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() +# Find (Apple's) libtool. +if(DEFINED BUILD_LIBTOOL) + # Environment variables are always preserved. + set(ENV{_BUILD_LIBTOOL} "${BUILD_LIBTOOL}") +elseif(DEFINED ENV{_BUILD_LIBTOOL}) + set(BUILD_LIBTOOL "$ENV{_BUILD_LIBTOOL}") +elseif(NOT DEFINED BUILD_LIBTOOL) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find libtool + OUTPUT_VARIABLE BUILD_LIBTOOL + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() +# Find the toolchain's provided install_name_tool if none is found on the host +if(DEFINED CMAKE_INSTALL_NAME_TOOL) + # Environment variables are always preserved. + set(ENV{_CMAKE_INSTALL_NAME_TOOL} "${CMAKE_INSTALL_NAME_TOOL}") +elseif(DEFINED ENV{_CMAKE_INSTALL_NAME_TOOL}) + set(CMAKE_INSTALL_NAME_TOOL "$ENV{_CMAKE_INSTALL_NAME_TOOL}") +elseif(NOT DEFINED CMAKE_INSTALL_NAME_TOOL) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT_INT} -find install_name_tool + OUTPUT_VARIABLE CMAKE_INSTALL_NAME_TOOL_INT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(CMAKE_INSTALL_NAME_TOOL ${CMAKE_INSTALL_NAME_TOOL_INT} CACHE INTERNAL "") +endif() + +# Configure libtool to be used instead of ar + ranlib to build static libraries. +# This is required on Xcode 7+, but should also work on previous versions of +# Xcode. +get_property(languages GLOBAL PROPERTY ENABLED_LANGUAGES) +foreach(lang ${languages}) + set(CMAKE_${lang}_CREATE_STATIC_LIBRARY "${BUILD_LIBTOOL} -static -o " CACHE INTERNAL "") +endforeach() + +# CMake 3.14+ support building for iOS, watchOS, and tvOS out of the box. +if(MODERN_CMAKE) + if(SDK_NAME MATCHES "iphone") + set(CMAKE_SYSTEM_NAME iOS) + elseif(SDK_NAME MATCHES "xros") + set(CMAKE_SYSTEM_NAME visionOS) + elseif(SDK_NAME MATCHES "xrsimulator") + set(CMAKE_SYSTEM_NAME visionOS) + elseif(SDK_NAME MATCHES "macosx") + set(CMAKE_SYSTEM_NAME Darwin) + elseif(SDK_NAME MATCHES "appletv") + set(CMAKE_SYSTEM_NAME tvOS) + elseif(SDK_NAME MATCHES "watch") + set(CMAKE_SYSTEM_NAME watchOS) + endif() + # Provide flags for a combined FAT library build on newer CMake versions + if(PLATFORM_INT MATCHES ".*COMBINED") + set(CMAKE_IOS_INSTALL_COMBINED YES) + if(CMAKE_GENERATOR MATCHES "Xcode") + # Set the SDKROOT Xcode properties to a Xcode-friendly value (the SDK_NAME, E.g, iphoneos) + # This way, Xcode will automatically switch between the simulator and device SDK when building. + set(CMAKE_XCODE_ATTRIBUTE_SDKROOT "${SDK_NAME}") + # Force to not build just one ARCH, but all! + set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO") + endif() + endif() +elseif(NOT DEFINED CMAKE_SYSTEM_NAME AND ${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.10") + # Legacy code path prior to CMake 3.14 or fallback if no CMAKE_SYSTEM_NAME specified + set(CMAKE_SYSTEM_NAME iOS) +elseif(NOT DEFINED CMAKE_SYSTEM_NAME) + # Legacy code path before CMake 3.14 or fallback if no CMAKE_SYSTEM_NAME specified + set(CMAKE_SYSTEM_NAME Darwin) +endif() +# Standard settings. +set(CMAKE_SYSTEM_VERSION ${SDK_VERSION} CACHE INTERNAL "") +set(UNIX ON CACHE BOOL "") +set(APPLE ON CACHE BOOL "") +if(PLATFORM STREQUAL "MAC" OR PLATFORM STREQUAL "MAC_ARM64" OR PLATFORM STREQUAL "MAC_UNIVERSAL") + set(IOS OFF CACHE BOOL "") + set(MACOS ON CACHE BOOL "") +elseif(PLATFORM STREQUAL "MAC_CATALYST" OR PLATFORM STREQUAL "MAC_CATALYST_ARM64" OR PLATFORM STREQUAL "MAC_CATALYST_UNIVERSAL") + set(IOS ON CACHE BOOL "") + set(MACOS ON CACHE BOOL "") +elseif(PLATFORM STREQUAL "VISIONOS" OR PLATFORM STREQUAL "SIMULATOR_VISIONOS" OR PLATFORM STREQUAL "VISIONOSCOMBINED") + set(IOS OFF CACHE BOOL "") + set(VISIONOS ON CACHE BOOL "") +else() + set(IOS ON CACHE BOOL "") +endif() +# Set the architectures for which to build. +set(CMAKE_OSX_ARCHITECTURES ${ARCHS} CACHE INTERNAL "") +# Change the type of target generated for try_compile() so it'll work when cross-compiling, weak compiler checks +if(NOT ENABLE_STRICT_TRY_COMPILE_INT) + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +endif() +# All iOS/Darwin specific settings - some may be redundant. +if (NOT DEFINED CMAKE_MACOSX_BUNDLE) + set(CMAKE_MACOSX_BUNDLE YES) +endif() +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO") +set(CMAKE_SHARED_LIBRARY_PREFIX "lib") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib") +set(CMAKE_EXTRA_SHARED_LIBRARY_SUFFIXES ".tbd" ".so") +set(CMAKE_SHARED_MODULE_PREFIX "lib") +set(CMAKE_SHARED_MODULE_SUFFIX ".so") +set(CMAKE_C_COMPILER_ABI ELF) +set(CMAKE_CXX_COMPILER_ABI ELF) +set(CMAKE_C_HAS_ISYSROOT 1) +set(CMAKE_CXX_HAS_ISYSROOT 1) +set(CMAKE_MODULE_EXISTS 1) +set(CMAKE_DL_LIBS "") +set(CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") +set(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ") +set(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}") +set(CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}") + +if(ARCHS MATCHES "((^|;|, )(arm64|arm64e|x86_64))+") + set(CMAKE_C_SIZEOF_DATA_PTR 8) + set(CMAKE_CXX_SIZEOF_DATA_PTR 8) + if(ARCHS MATCHES "((^|;|, )(arm64|arm64e))+") + set(CMAKE_SYSTEM_PROCESSOR "aarch64") + else() + set(CMAKE_SYSTEM_PROCESSOR "x86_64") + endif() +else() + set(CMAKE_C_SIZEOF_DATA_PTR 4) + set(CMAKE_CXX_SIZEOF_DATA_PTR 4) + set(CMAKE_SYSTEM_PROCESSOR "arm") +endif() + +# Note that only Xcode 7+ supports the newer more specific: +# -m${SDK_NAME}-version-min flags, older versions of Xcode use: +# -m(ios/ios-simulator)-version-min instead. +if(${CMAKE_VERSION} VERSION_LESS "3.11") + if(PLATFORM_INT STREQUAL "OS" OR PLATFORM_INT STREQUAL "OS64") + if(XCODE_VERSION_INT VERSION_LESS 7.0) + set(SDK_NAME_VERSION_FLAGS + "-mios-version-min=${DEPLOYMENT_TARGET}") + else() + # Xcode 7.0+ uses flags we can build directly from SDK_NAME. + set(SDK_NAME_VERSION_FLAGS + "-m${SDK_NAME}-version-min=${DEPLOYMENT_TARGET}") + endif() + elseif(PLATFORM_INT STREQUAL "TVOS") + set(SDK_NAME_VERSION_FLAGS + "-mtvos-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS") + set(SDK_NAME_VERSION_FLAGS + "-mtvos-simulator-version-min=${DEPLOYMENT_TARGET}") +elseif(PLATFORM_INT STREQUAL "SIMULATORARM64_TVOS") + set(SDK_NAME_VERSION_FLAGS + "-mtvos-simulator-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "WATCHOS") + set(SDK_NAME_VERSION_FLAGS + "-mwatchos-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") + set(SDK_NAME_VERSION_FLAGS + "-mwatchos-simulator-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "SIMULATORARM64_WATCHOS") + set(SDK_NAME_VERSION_FLAGS + "-mwatchos-simulator-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "MAC") + set(SDK_NAME_VERSION_FLAGS + "-mmacosx-version-min=${DEPLOYMENT_TARGET}") + else() + # SIMULATOR or SIMULATOR64 both use -mios-simulator-version-min. + set(SDK_NAME_VERSION_FLAGS + "-mios-simulator-version-min=${DEPLOYMENT_TARGET}") + endif() +elseif(NOT PLATFORM_INT MATCHES "^MAC_CATALYST") + # Newer versions of CMake sets the version min flags correctly, skip this for Mac Catalyst targets + set(CMAKE_OSX_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET} CACHE INTERNAL "Minimum OS X deployment version") +endif() + +if(DEFINED APPLE_TARGET_TRIPLE_INT) + set(APPLE_TARGET_TRIPLE ${APPLE_TARGET_TRIPLE_INT} CACHE INTERNAL "") + set(CMAKE_C_COMPILER_TARGET ${APPLE_TARGET_TRIPLE}) + set(CMAKE_CXX_COMPILER_TARGET ${APPLE_TARGET_TRIPLE}) + set(CMAKE_ASM_COMPILER_TARGET ${APPLE_TARGET_TRIPLE}) +endif() + +if(PLATFORM_INT MATCHES "^MAC_CATALYST") + set(C_TARGET_FLAGS "-isystem ${CMAKE_OSX_SYSROOT_INT}/System/iOSSupport/usr/include -iframework ${CMAKE_OSX_SYSROOT_INT}/System/iOSSupport/System/Library/Frameworks") +endif() + +if(ENABLE_BITCODE_INT) + set(BITCODE "-fembed-bitcode") + set(CMAKE_XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE "bitcode") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES") +else() + set(BITCODE "") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO") +endif() + +if(ENABLE_ARC_INT) + set(FOBJC_ARC "-fobjc-arc") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES") +else() + set(FOBJC_ARC "-fno-objc-arc") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "NO") +endif() + +if(NAMED_LANGUAGE_SUPPORT_INT) + set(OBJC_VARS "-fobjc-abi-version=2 -DOBJC_OLD_DISPATCH_PROTOTYPES=0") + set(OBJC_LEGACY_VARS "") +else() + set(OBJC_VARS "") + set(OBJC_LEGACY_VARS "-fobjc-abi-version=2 -DOBJC_OLD_DISPATCH_PROTOTYPES=0") +endif() + +if(NOT ENABLE_VISIBILITY_INT) + foreach(lang ${languages}) + set(CMAKE_${lang}_VISIBILITY_PRESET "hidden" CACHE INTERNAL "") + endforeach() + set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "YES") + set(VISIBILITY "-fvisibility=hidden -fvisibility-inlines-hidden") +else() + foreach(lang ${languages}) + set(CMAKE_${lang}_VISIBILITY_PRESET "default" CACHE INTERNAL "") + endforeach() + set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "NO") + set(VISIBILITY "-fvisibility=default") +endif() + +if(DEFINED APPLE_TARGET_TRIPLE) + set(APPLE_TARGET_TRIPLE_FLAG "-target ${APPLE_TARGET_TRIPLE}") +endif() + +#Check if Xcode generator is used since that will handle these flags automagically +if(CMAKE_GENERATOR MATCHES "Xcode") + message(STATUS "Not setting any manual command-line buildflags, since Xcode is selected as the generator. Modifying the Xcode build-settings directly instead.") +else() + set(CMAKE_C_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${OBJC_LEGACY_VARS} ${BITCODE} ${VISIBILITY} ${CMAKE_C_FLAGS}" CACHE INTERNAL + "Flags used by the compiler during all C build types.") + set(CMAKE_C_FLAGS_DEBUG "-O0 -g ${CMAKE_C_FLAGS_DEBUG}") + set(CMAKE_C_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_C_FLAGS_MINSIZEREL}") + set(CMAKE_C_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_C_FLAGS_RELWITHDEBINFO}") + set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_C_FLAGS_RELEASE}") + set(CMAKE_CXX_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${OBJC_LEGACY_VARS} ${BITCODE} ${VISIBILITY} ${CMAKE_CXX_FLAGS}" CACHE INTERNAL + "Flags used by the compiler during all CXX build types.") + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g ${CMAKE_CXX_FLAGS_DEBUG}") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_CXX_FLAGS_MINSIZEREL}") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_CXX_FLAGS_RELEASE}") + if(NAMED_LANGUAGE_SUPPORT_INT) + set(CMAKE_OBJC_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} ${FOBJC_ARC} ${OBJC_VARS} ${CMAKE_OBJC_FLAGS}" CACHE INTERNAL + "Flags used by the compiler during all OBJC build types.") + set(CMAKE_OBJC_FLAGS_DEBUG "-O0 -g ${CMAKE_OBJC_FLAGS_DEBUG}") + set(CMAKE_OBJC_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_OBJC_FLAGS_MINSIZEREL}") + set(CMAKE_OBJC_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_OBJC_FLAGS_RELWITHDEBINFO}") + set(CMAKE_OBJC_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_OBJC_FLAGS_RELEASE}") + set(CMAKE_OBJCXX_FLAGS "${C_TARGET_FLAGS} ${APPLE_TARGET_TRIPLE_FLAG} ${SDK_NAME_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} ${FOBJC_ARC} ${OBJC_VARS} ${CMAKE_OBJCXX_FLAGS}" CACHE INTERNAL + "Flags used by the compiler during all OBJCXX build types.") + set(CMAKE_OBJCXX_FLAGS_DEBUG "-O0 -g ${CMAKE_OBJCXX_FLAGS_DEBUG}") + set(CMAKE_OBJCXX_FLAGS_MINSIZEREL "-DNDEBUG -Os ${CMAKE_OBJCXX_FLAGS_MINSIZEREL}") + set(CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO "-DNDEBUG -O2 -g ${CMAKE_OBJCXX_FLAGS_RELWITHDEBINFO}") + set(CMAKE_OBJCXX_FLAGS_RELEASE "-DNDEBUG -O3 ${CMAKE_OBJCXX_FLAGS_RELEASE}") + endif() + set(CMAKE_C_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}" CACHE INTERNAL + "Flags used by the compiler for all C link types.") + set(CMAKE_CXX_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}" CACHE INTERNAL + "Flags used by the compiler for all CXX link types.") + if(NAMED_LANGUAGE_SUPPORT_INT) + set(CMAKE_OBJC_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_OBJC_LINK_FLAGS}" CACHE INTERNAL + "Flags used by the compiler for all OBJC link types.") + set(CMAKE_OBJCXX_LINK_FLAGS "${C_TARGET_FLAGS} ${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_OBJCXX_LINK_FLAGS}" CACHE INTERNAL + "Flags used by the compiler for all OBJCXX link types.") + endif() + set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp -arch ${CMAKE_OSX_ARCHITECTURES} ${APPLE_TARGET_TRIPLE_FLAG}" CACHE INTERNAL + "Flags used by the compiler for all ASM build types.") +endif() + +## Print status messages to inform of the current state +message(STATUS "Configuring ${SDK_NAME} build for platform: ${PLATFORM_INT}, architecture(s): ${ARCHS}") +message(STATUS "Using SDK: ${CMAKE_OSX_SYSROOT_INT}") +message(STATUS "Using C compiler: ${CMAKE_C_COMPILER}") +message(STATUS "Using CXX compiler: ${CMAKE_CXX_COMPILER}") +message(STATUS "Using libtool: ${BUILD_LIBTOOL}") +message(STATUS "Using install name tool: ${CMAKE_INSTALL_NAME_TOOL}") +if(DEFINED APPLE_TARGET_TRIPLE) + message(STATUS "Autoconf target triple: ${APPLE_TARGET_TRIPLE}") +endif() +message(STATUS "Using minimum deployment version: ${DEPLOYMENT_TARGET}" + " (SDK version: ${SDK_VERSION})") +if(MODERN_CMAKE) + message(STATUS "Merging integrated CMake 3.14+ iOS,tvOS,watchOS,macOS toolchain(s) with this toolchain!") + if(PLATFORM_INT MATCHES ".*COMBINED") + message(STATUS "Will combine built (static) artifacts into FAT lib...") + endif() +endif() +if(CMAKE_GENERATOR MATCHES "Xcode") + message(STATUS "Using Xcode version: ${XCODE_VERSION_INT}") +endif() +message(STATUS "CMake version: ${CMAKE_VERSION}") +if(DEFINED SDK_NAME_VERSION_FLAGS) + message(STATUS "Using version flags: ${SDK_NAME_VERSION_FLAGS}") +endif() +message(STATUS "Using a data_ptr size of: ${CMAKE_CXX_SIZEOF_DATA_PTR}") +if(ENABLE_BITCODE_INT) + message(STATUS "Bitcode: Enabled") +else() + message(STATUS "Bitcode: Disabled") +endif() + +if(ENABLE_ARC_INT) + message(STATUS "ARC: Enabled") +else() + message(STATUS "ARC: Disabled") +endif() + +if(ENABLE_VISIBILITY_INT) + message(STATUS "Hiding symbols: Disabled") +else() + message(STATUS "Hiding symbols: Enabled") +endif() + +# Set global properties +set_property(GLOBAL PROPERTY PLATFORM "${PLATFORM}") +set_property(GLOBAL PROPERTY APPLE_TARGET_TRIPLE "${APPLE_TARGET_TRIPLE_INT}") +set_property(GLOBAL PROPERTY SDK_VERSION "${SDK_VERSION}") +set_property(GLOBAL PROPERTY XCODE_VERSION "${XCODE_VERSION_INT}") +set_property(GLOBAL PROPERTY OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") + +# Export configurable variables for the try_compile() command. +set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES + PLATFORM + XCODE_VERSION_INT + SDK_VERSION + NAMED_LANGUAGE_SUPPORT + DEPLOYMENT_TARGET + CMAKE_DEVELOPER_ROOT + CMAKE_OSX_SYSROOT_INT + ENABLE_BITCODE + ENABLE_ARC + CMAKE_ASM_COMPILER + CMAKE_C_COMPILER + CMAKE_C_COMPILER_TARGET + CMAKE_CXX_COMPILER + CMAKE_CXX_COMPILER_TARGET + BUILD_LIBTOOL + CMAKE_INSTALL_NAME_TOOL + CMAKE_C_FLAGS + CMAKE_C_DEBUG + CMAKE_C_MINSIZEREL + CMAKE_C_RELWITHDEBINFO + CMAKE_C_RELEASE + CMAKE_CXX_FLAGS + CMAKE_CXX_FLAGS_DEBUG + CMAKE_CXX_FLAGS_MINSIZEREL + CMAKE_CXX_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS_RELEASE + CMAKE_C_LINK_FLAGS + CMAKE_CXX_LINK_FLAGS + CMAKE_ASM_FLAGS +) + +if(NAMED_LANGUAGE_SUPPORT_INT) + list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES + CMAKE_OBJC_FLAGS + CMAKE_OBJC_DEBUG + CMAKE_OBJC_MINSIZEREL + CMAKE_OBJC_RELWITHDEBINFO + CMAKE_OBJC_RELEASE + CMAKE_OBJCXX_FLAGS + CMAKE_OBJCXX_DEBUG + CMAKE_OBJCXX_MINSIZEREL + CMAKE_OBJCXX_RELWITHDEBINFO + CMAKE_OBJCXX_RELEASE + CMAKE_OBJC_LINK_FLAGS + CMAKE_OBJCXX_LINK_FLAGS + ) +endif() + +set(CMAKE_PLATFORM_HAS_INSTALLNAME 1) +set(CMAKE_SHARED_LINKER_FLAGS "-rpath @executable_path/Frameworks -rpath @loader_path/Frameworks") +set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names") +set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -Wl,-headerpad_max_install_names") +set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,") +set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,") +set(CMAKE_FIND_LIBRARY_SUFFIXES ".tbd" ".dylib" ".so" ".a") +set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name") + +# Set the find root to the SDK developer roots. +# Note: CMAKE_FIND_ROOT_PATH is only useful when cross-compiling. Thus, do not set on macOS builds. +if(NOT PLATFORM_INT MATCHES "^MAC.*$") + list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") + set(CMAKE_IGNORE_PATH "/System/Library/Frameworks;/usr/local/lib;/opt/homebrew" CACHE INTERNAL "") +endif() + +# Default to searching for frameworks first. +IF(NOT DEFINED CMAKE_FIND_FRAMEWORK) + set(CMAKE_FIND_FRAMEWORK FIRST) +ENDIF(NOT DEFINED CMAKE_FIND_FRAMEWORK) + +# Set up the default search directories for frameworks. +if(PLATFORM_INT MATCHES "^MAC_CATALYST") + set(CMAKE_FRAMEWORK_PATH + ${CMAKE_DEVELOPER_ROOT}/Library/PrivateFrameworks + ${CMAKE_OSX_SYSROOT_INT}/System/Library/Frameworks + ${CMAKE_OSX_SYSROOT_INT}/System/iOSSupport/System/Library/Frameworks + ${CMAKE_FRAMEWORK_PATH} CACHE INTERNAL "") +else() + set(CMAKE_FRAMEWORK_PATH + ${CMAKE_DEVELOPER_ROOT}/Library/PrivateFrameworks + ${CMAKE_OSX_SYSROOT_INT}/System/Library/Frameworks + ${CMAKE_FRAMEWORK_PATH} CACHE INTERNAL "") +endif() + +# By default, search both the specified iOS SDK and the remainder of the host filesystem. +if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH CACHE INTERNAL "") +endif() +if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH CACHE INTERNAL "") +endif() +if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH CACHE INTERNAL "") +endif() +if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH CACHE INTERNAL "") +endif() + +# +# Some helper-macros below to simplify and beautify the CMakeFile +# + +# This little macro lets you set any Xcode specific property. +macro(set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE XCODE_RELVERSION) + set(XCODE_RELVERSION_I "${XCODE_RELVERSION}") + if(XCODE_RELVERSION_I STREQUAL "All") + set_property(TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY} "${XCODE_VALUE}") + else() + set_property(TARGET ${TARGET} PROPERTY XCODE_ATTRIBUTE_${XCODE_PROPERTY}[variant=${XCODE_RELVERSION_I}] "${XCODE_VALUE}") + endif() +endmacro(set_xcode_property) + +# This macro lets you find executable programs on the host system. +macro(find_host_package) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) + set(_TOOLCHAIN_IOS ${IOS}) + set(IOS OFF) + find_package(${ARGN}) + set(IOS ${_TOOLCHAIN_IOS}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) +endmacro(find_host_package) diff --git a/cmake/toolchains/README.md b/cmake/toolchains/README.md new file mode 100644 index 000000000..3d02b54ad --- /dev/null +++ b/cmake/toolchains/README.md @@ -0,0 +1,38 @@ +# CMake toolchains + +To build locally for ARM64: +```bash +cmake -S . -B build-arm64 \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/aarch64-linux-gnu.cmake \ + -DCMAKE_BUILD_TYPE=Release +cmake --build build-arm64 +``` + +To build locally for ARMv7: +```bash +cmake -S . -B build-armv7 \ + -DCMAKE_TOOLCHAIN_FILE=cmake/toolchains/arm-linux-gnueabihf.cmake \ + -DCMAKE_BUILD_TYPE=Release +cmake --build build-armv7 +``` + +It is also possible to cross-compile from other hosts but the toolchain files may need to be adjusted accordingly. + +## Testing Cross-Compiled Binaries + +With QEMU: + +```bash +# Install QEMU +sudo apt-get install qemu-user-static + +# Run ARM64 binary +qemu-aarch64-static -L /usr/aarch64-linux-gnu ./build-arm64/your-binary + +# Run ARMv7 binary +qemu-arm-static -L /usr/arm-linux-gnueabihf ./build-armv7/your-binary +``` + +## NVIDIA Jetson + +The ARM64 build (`aarch64-linux-gnu.cmake`) binaries should be compatible with NVIDIA Jetson. diff --git a/cmake/toolchains/aarch64-linux-gnu.cmake b/cmake/toolchains/aarch64-linux-gnu.cmake new file mode 100644 index 000000000..3583c4e86 --- /dev/null +++ b/cmake/toolchains/aarch64-linux-gnu.cmake @@ -0,0 +1,24 @@ +# CMake toolchain file for cross-compiling to ARM64/aarch64 +# Compatible with NVIDIA Jetson, Raspberry Pi 4/5, and other ARM64 Linux systems + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR aarch64) + +# Specify the cross compiler +set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) +set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) + +# Where to look for the target environment +set(CMAKE_FIND_ROOT_PATH /usr/aarch64-linux-gnu) + +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# Search for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) + +# Set additional compiler flags for better compatibility +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv8-a" CACHE STRING "C flags") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv8-a" CACHE STRING "C++ flags") diff --git a/cmake/toolchains/arm-linux-gnueabihf.cmake b/cmake/toolchains/arm-linux-gnueabihf.cmake new file mode 100644 index 000000000..59fe073ef --- /dev/null +++ b/cmake/toolchains/arm-linux-gnueabihf.cmake @@ -0,0 +1,24 @@ +# CMake toolchain file for cross-compiling to ARMv7 (32-bit ARM with hard float) +# Compatible with Raspberry Pi 2/3 and other ARMv7 Linux systems + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR armv7l) + +# Specify the cross compiler +set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) +set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++) + +# Where to look for the target environment +set(CMAKE_FIND_ROOT_PATH /usr/arm-linux-gnueabihf) + +# Search for programs in the build host directories +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + +# Search for libraries and headers in the target directories +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) + +# Set additional compiler flags for ARMv7 with NEON support +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard" CACHE STRING "C flags") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=armv7-a -mfpu=neon-vfpv4 -mfloat-abi=hard" CACHE STRING "C++ flags") diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index aa997882e..d4caf88d4 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -5,13 +5,28 @@ project(lslexamples include(GNUInstallDirs) -find_package(LSL REQUIRED - HINTS - ${LSL_INSTALL_ROOT} - "${CMAKE_CURRENT_LIST_DIR}/../install" # GHA scripts default install directory - "${CMAKE_CURRENT_LIST_DIR}/../cmake-build-release/install" # CLion default if using -DCMAKE_INSTALL_PREFIX=install +set(LSL_SEARCH_PATHS + ${LSL_INSTALL_ROOT} + "${CMAKE_CURRENT_LIST_DIR}/../install" # GHA scripts default install directory + "${CMAKE_CURRENT_LIST_DIR}/../cmake-build-release/install" # CLion default if using -DCMAKE_INSTALL_PREFIX=install +) +if(APPLE) + # Also search in a Frameworks subdirectory for each path + foreach(p IN LISTS LSL_SEARCH_PATHS) + if(p) + list(APPEND LSL_SEARCH_PATHS "${p}/Frameworks") + endif() + endforeach() +else() + # Add MSVC-specific paths if not on Apple + list(APPEND LSL_SEARCH_PATHS "${CMAKE_CURRENT_LIST_DIR}/../cmake-build-release-visual-studio/install" # CLion default if using VS compiler "${CMAKE_CURRENT_LIST_DIR}/../out/build/x64-Release/install" # MSVC default if using -DCMAKE_INSTALL_PREFIX=install + ) +endif() + +find_package(LSL REQUIRED + HINTS ${LSL_SEARCH_PATHS} PATH_SUFFIXES share/LSL ) get_filename_component(LSL_PATH ${LSL_CONFIG} DIRECTORY) @@ -42,7 +57,7 @@ function(addlslexample name extension) # However, this is not necessary for the examples, as they are not intended to be relocated. # if(APPLE) # set_target_properties(${name} PROPERTIES -# INSTALL_RPATH "@loader_path;@loader_path/../lib" +# INSTALL_RPATH "@loader_path;@loader_path/../lib;@loader_path/../Frameworks" # ) # elseif(UNIX) # set_target_properties(${name} PROPERTIES diff --git a/lsl.entitlements b/lsl.entitlements new file mode 100644 index 000000000..70055b747 --- /dev/null +++ b/lsl.entitlements @@ -0,0 +1,17 @@ + + + + + + com.apple.security.network.client + + + + com.apple.security.network.server + + + + com.apple.security.network.multicast + + + diff --git a/lslboost/boost/assert.hpp b/lslboost/boost/assert.hpp index b644a888a..40d147ef7 100644 --- a/lslboost/boost/assert.hpp +++ b/lslboost/boost/assert.hpp @@ -46,7 +46,13 @@ namespace lslboost { +#if defined(BOOST_ASSERT_HANDLER_IS_NORETURN) + BOOST_NORETURN +#endif void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined +#if defined(BOOST_ASSERT_HANDLER_IS_NORETURN) + BOOST_NORETURN +#endif void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line); // user defined } // namespace lslboost diff --git a/lslboost/boost/config/assert_cxx17.hpp b/lslboost/boost/config/assert_cxx17.hpp index ffa1ae918..e2402515f 100644 --- a/lslboost/boost/config/assert_cxx17.hpp +++ b/lslboost/boost/config/assert_cxx17.hpp @@ -12,6 +12,9 @@ #include #include +#ifdef BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +# error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS." +#endif #ifdef BOOST_NO_CXX17_DEDUCTION_GUIDES # error "Your compiler appears not to be fully C++17 compliant. Detected via defect macro BOOST_NO_CXX17_DEDUCTION_GUIDES." #endif diff --git a/lslboost/boost/config/compiler/borland.hpp b/lslboost/boost/config/compiler/borland.hpp index 567636c5b..51d518869 100644 --- a/lslboost/boost/config/compiler/borland.hpp +++ b/lslboost/boost/config/compiler/borland.hpp @@ -245,6 +245,9 @@ #if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif #if __BORLANDC__ >= 0x590 # define BOOST_HAS_TR1_HASH diff --git a/lslboost/boost/config/compiler/clang.hpp b/lslboost/boost/config/compiler/clang.hpp index 1eeed315d..f9a5050b4 100644 --- a/lslboost/boost/config/compiler/clang.hpp +++ b/lslboost/boost/config/compiler/clang.hpp @@ -321,6 +321,10 @@ # define BOOST_NO_CXX17_FOLD_EXPRESSIONS #endif +#if (__clang_major__ < 4) || (__cplusplus < 201406L) /* non-standard value that is greater than 201402, which is reported by clang 4.0.0 for C++1z */ +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + #if __cplusplus < 201103L #define BOOST_NO_CXX11_SFINAE_EXPR #endif diff --git a/lslboost/boost/config/compiler/codegear.hpp b/lslboost/boost/config/compiler/codegear.hpp index 4d3f42aef..49f934c02 100644 --- a/lslboost/boost/config/compiler/codegear.hpp +++ b/lslboost/boost/config/compiler/codegear.hpp @@ -316,6 +316,10 @@ # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + // // TR1 macros: // diff --git a/lslboost/boost/config/compiler/common_edg.hpp b/lslboost/boost/config/compiler/common_edg.hpp index dc049893c..0d59ae0e6 100644 --- a/lslboost/boost/config/compiler/common_edg.hpp +++ b/lslboost/boost/config/compiler/common_edg.hpp @@ -171,10 +171,12 @@ #if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) # define BOOST_NO_CXX17_FOLD_EXPRESSIONS #endif - #if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif #ifdef c_plusplus // EDG has "long long" in non-strict mode diff --git a/lslboost/boost/config/compiler/digitalmars.hpp b/lslboost/boost/config/compiler/digitalmars.hpp index bb56ff6c0..4fa347ab8 100644 --- a/lslboost/boost/config/compiler/digitalmars.hpp +++ b/lslboost/boost/config/compiler/digitalmars.hpp @@ -130,6 +130,9 @@ #if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif #if (__DMC__ <= 0x840) #error "Compiler not supported or configured - please reconfigure" diff --git a/lslboost/boost/config/compiler/gcc.hpp b/lslboost/boost/config/compiler/gcc.hpp index 2f1fe5508..fc05a9186 100644 --- a/lslboost/boost/config/compiler/gcc.hpp +++ b/lslboost/boost/config/compiler/gcc.hpp @@ -319,6 +319,9 @@ #if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if (__GNUC__ < 7) || (__cplusplus < 201703L) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif #if __GNUC__ >= 7 # define BOOST_FALLTHROUGH __attribute__((fallthrough)) diff --git a/lslboost/boost/config/compiler/gcc_xml.hpp b/lslboost/boost/config/compiler/gcc_xml.hpp index 75cac44e9..e23b14d0f 100644 --- a/lslboost/boost/config/compiler/gcc_xml.hpp +++ b/lslboost/boost/config/compiler/gcc_xml.hpp @@ -108,7 +108,8 @@ #if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif #define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ - - diff --git a/lslboost/boost/config/compiler/hp_acc.hpp b/lslboost/boost/config/compiler/hp_acc.hpp index 25636324b..42e35e553 100644 --- a/lslboost/boost/config/compiler/hp_acc.hpp +++ b/lslboost/boost/config/compiler/hp_acc.hpp @@ -137,6 +137,10 @@ #define BOOST_NO_CXX11_VARIADIC_MACROS #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + #endif // diff --git a/lslboost/boost/config/compiler/metrowerks.hpp b/lslboost/boost/config/compiler/metrowerks.hpp index 448ab67bc..c38efb321 100644 --- a/lslboost/boost/config/compiler/metrowerks.hpp +++ b/lslboost/boost/config/compiler/metrowerks.hpp @@ -173,6 +173,9 @@ #if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif #define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) diff --git a/lslboost/boost/config/compiler/mpw.hpp b/lslboost/boost/config/compiler/mpw.hpp index 8433f3719..3adb61221 100644 --- a/lslboost/boost/config/compiler/mpw.hpp +++ b/lslboost/boost/config/compiler/mpw.hpp @@ -122,6 +122,9 @@ #if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif // // versions check: diff --git a/lslboost/boost/config/compiler/nvcc.hpp b/lslboost/boost/config/compiler/nvcc.hpp index 419dd724a..147f75dbf 100644 --- a/lslboost/boost/config/compiler/nvcc.hpp +++ b/lslboost/boost/config/compiler/nvcc.hpp @@ -57,5 +57,8 @@ # define BOOST_NO_CXX11_NOEXCEPT #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS #endif +#endif diff --git a/lslboost/boost/config/compiler/pathscale.hpp b/lslboost/boost/config/compiler/pathscale.hpp index 5348cf7f7..59ab9b007 100644 --- a/lslboost/boost/config/compiler/pathscale.hpp +++ b/lslboost/boost/config/compiler/pathscale.hpp @@ -135,4 +135,7 @@ #if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif #endif diff --git a/lslboost/boost/config/compiler/sunpro_cc.hpp b/lslboost/boost/config/compiler/sunpro_cc.hpp index 490dc76dc..334b604bb 100644 --- a/lslboost/boost/config/compiler/sunpro_cc.hpp +++ b/lslboost/boost/config/compiler/sunpro_cc.hpp @@ -194,6 +194,9 @@ #if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif // Turn on threading support for Solaris 12. // Ticket #11972 diff --git a/lslboost/boost/config/compiler/vacpp.hpp b/lslboost/boost/config/compiler/vacpp.hpp index 9cfa1adf8..3794d3601 100644 --- a/lslboost/boost/config/compiler/vacpp.hpp +++ b/lslboost/boost/config/compiler/vacpp.hpp @@ -184,3 +184,6 @@ #if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) # define BOOST_NO_CXX17_IF_CONSTEXPR #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif diff --git a/lslboost/boost/config/compiler/visualc.hpp b/lslboost/boost/config/compiler/visualc.hpp index c0ada098a..ce0fc15e3 100644 --- a/lslboost/boost/config/compiler/visualc.hpp +++ b/lslboost/boost/config/compiler/visualc.hpp @@ -263,6 +263,9 @@ #define BOOST_NO_CXX17_INLINE_VARIABLES #define BOOST_NO_CXX17_FOLD_EXPRESSIONS #endif +#if (_MSC_VER < 1914) || (_MSVC_LANG < 201703) +#define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif // // Things that don't work in clr mode: diff --git a/lslboost/boost/config/compiler/xlcpp.hpp b/lslboost/boost/config/compiler/xlcpp.hpp index 99b8b2455..4a4477d9d 100644 --- a/lslboost/boost/config/compiler/xlcpp.hpp +++ b/lslboost/boost/config/compiler/xlcpp.hpp @@ -265,6 +265,10 @@ # define BOOST_NO_CXX17_FOLD_EXPRESSIONS #endif +#if !defined(__cpp_nontype_template_parameter_auto) || (__cpp_nontype_template_parameter_auto < 201606) +# define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS +#endif + #if !__has_feature(cxx_thread_local) # define BOOST_NO_CXX11_THREAD_LOCAL #endif diff --git a/lslboost/boost/config/compiler/xlcpp_zos.hpp b/lslboost/boost/config/compiler/xlcpp_zos.hpp index 9a177f1bb..0b288a880 100644 --- a/lslboost/boost/config/compiler/xlcpp_zos.hpp +++ b/lslboost/boost/config/compiler/xlcpp_zos.hpp @@ -157,6 +157,7 @@ #define BOOST_NO_CXX17_INLINE_VARIABLES #define BOOST_NO_CXX17_FOLD_EXPRESSIONS #define BOOST_NO_CXX17_IF_CONSTEXPR +#define BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS // ------------------------------------- diff --git a/lslboost/boost/config/detail/cxx_composite.hpp b/lslboost/boost/config/detail/cxx_composite.hpp index 9c2c01ead..acd8e8496 100644 --- a/lslboost/boost/config/detail/cxx_composite.hpp +++ b/lslboost/boost/config/detail/cxx_composite.hpp @@ -164,6 +164,7 @@ #endif #if defined(BOOST_NO_CXX14)\ + || defined(BOOST_NO_CXX17_AUTO_NONTYPE_TEMPLATE_PARAMS)\ || defined(BOOST_NO_CXX17_DEDUCTION_GUIDES)\ || defined(BOOST_NO_CXX17_FOLD_EXPRESSIONS)\ || defined(BOOST_NO_CXX17_HDR_ANY)\ diff --git a/lslboost/boost/config/stdlib/libcpp.hpp b/lslboost/boost/config/stdlib/libcpp.hpp index 0e9f2445e..777228fad 100644 --- a/lslboost/boost/config/stdlib/libcpp.hpp +++ b/lslboost/boost/config/stdlib/libcpp.hpp @@ -177,4 +177,9 @@ #endif #endif +#if _LIBCPP_VERSION <= 170006 +// no std::ranges::join_view +# define BOOST_NO_CXX20_HDR_RANGES +#endif + // --- end --- diff --git a/lslboost/boost/smart_ptr/detail/operator_bool.hpp b/lslboost/boost/smart_ptr/detail/operator_bool.hpp deleted file mode 100644 index f9c5ef680..000000000 --- a/lslboost/boost/smart_ptr/detail/operator_bool.hpp +++ /dev/null @@ -1,64 +0,0 @@ -// This header intentionally has no include guards. -// -// Copyright (c) 2001-2009, 2012 Peter Dimov -// -// Distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt - -#if !defined( BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS ) && !defined( BOOST_NO_CXX11_NULLPTR )\ - && !(defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5130)) - - explicit operator bool () const BOOST_SP_NOEXCEPT - { - return px != 0; - } - -#elif ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, < 0x570) ) || defined(__CINT__) - - operator bool () const BOOST_SP_NOEXCEPT - { - return px != 0; - } - -#elif defined( _MANAGED ) - - static void unspecified_bool( this_type*** ) - { - } - - typedef void (*unspecified_bool_type)( this_type*** ); - - operator unspecified_bool_type() const BOOST_SP_NOEXCEPT - { - return px == 0? 0: unspecified_bool; - } - -#elif \ - ( defined(__MWERKS__) && BOOST_WORKAROUND(__MWERKS__, < 0x3200) ) || \ - ( defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 304) ) || \ - ( defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x590) ) - - typedef element_type * (this_type::*unspecified_bool_type)() const; - - operator unspecified_bool_type() const BOOST_SP_NOEXCEPT - { - return px == 0? 0: &this_type::get; - } - -#else - - typedef element_type * this_type::*unspecified_bool_type; - - operator unspecified_bool_type() const BOOST_SP_NOEXCEPT - { - return px == 0? 0: &this_type::px; - } - -#endif - - // operator! is redundant, but some compilers need it - bool operator! () const BOOST_SP_NOEXCEPT - { - return px == 0; - } diff --git a/lslboost/boost/smart_ptr/detail/requires_cxx11.hpp b/lslboost/boost/smart_ptr/detail/requires_cxx11.hpp deleted file mode 100644 index fd719c877..000000000 --- a/lslboost/boost/smart_ptr/detail/requires_cxx11.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef BOOST_SMART_PTR_DETAIL_REQUIRES_CXX11_HPP_INCLUDED -#define BOOST_SMART_PTR_DETAIL_REQUIRES_CXX11_HPP_INCLUDED - -// Copyright 2023 Peter Dimov -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt - -#include -#include - -#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || \ - defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \ - defined(BOOST_NO_CXX11_DECLTYPE) || \ - defined(BOOST_NO_CXX11_CONSTEXPR) || \ - defined(BOOST_NO_CXX11_NOEXCEPT) || \ - defined(BOOST_NO_CXX11_NULLPTR) || \ - defined(BOOST_NO_CXX11_SMART_PTR) - -BOOST_PRAGMA_MESSAGE("C++03 support was deprecated in Boost.SmartPtr 1.82 and will be removed in Boost.SmartPtr 1.85.") - -#endif - -#endif // #ifndef BOOST_SMART_PTR_DETAIL_REQUIRES_CXX11_HPP_INCLUDED diff --git a/lslboost/boost/smart_ptr/detail/sp_convertible.hpp b/lslboost/boost/smart_ptr/detail/sp_convertible.hpp index 8e67d2317..c257d040b 100644 --- a/lslboost/boost/smart_ptr/detail/sp_convertible.hpp +++ b/lslboost/boost/smart_ptr/detail/sp_convertible.hpp @@ -18,20 +18,6 @@ #include #include -#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_NO_SFINAE ) -# define BOOST_SP_NO_SP_CONVERTIBLE -#endif - -#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ < 303 ) -# define BOOST_SP_NO_SP_CONVERTIBLE -#endif - -#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) && defined( BOOST_BORLANDC ) && ( BOOST_BORLANDC < 0x630 ) -# define BOOST_SP_NO_SP_CONVERTIBLE -#endif - -#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) - namespace lslboost { @@ -87,6 +73,4 @@ template< class Y, class T > struct sp_enable_if_convertible: public sp_enable_i } // namespace lslboost -#endif // !defined( BOOST_SP_NO_SP_CONVERTIBLE ) - #endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CONVERTIBLE_HPP_INCLUDED diff --git a/lslboost/boost/smart_ptr/detail/sp_cxx20_constexpr.hpp b/lslboost/boost/smart_ptr/detail/sp_cxx20_constexpr.hpp new file mode 100644 index 000000000..dc7c9ca15 --- /dev/null +++ b/lslboost/boost/smart_ptr/detail/sp_cxx20_constexpr.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#pragma once +#endif + +// detail/sp_noexcept.hpp +// +// Copyright 2025 Mathias Stearn +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + + +// This macro is used to mark functions as constexpr if the compiler supports +// constexpr destructors. Since you can't have a constexpr smart pointer object, +// everything except null constructors are guided behind this macro. Because +// this also guards a use of dynamic_cast, we need to check for its availability +// as well. It isn't worth splitting out since all known compilers that support +// constexpr dynamic_cast also support constexpr destructors. +// +// WARNING: This does not check for changing active member of a union in +// constant expressions which is allowed in C++20. If that is needed, we +// need to raise the checked version to 202002L. +#if defined(__cpp_constexpr_dynamic_alloc) && __cpp_constexpr_dynamic_alloc >= 201907L \ + && defined(__cpp_constexpr) && __cpp_constexpr >= 201907L +#define BOOST_SP_CXX20_CONSTEXPR constexpr +#else +#define BOOST_SP_CXX20_CONSTEXPR +#define BOOST_SP_NO_CXX20_CONSTEXPR +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_CXX20_CONSTEXPR_HPP_INCLUDED diff --git a/lslboost/boost/smart_ptr/detail/sp_noexcept.hpp b/lslboost/boost/smart_ptr/detail/sp_noexcept.hpp index 1287ba495..3b0d04ed5 100644 --- a/lslboost/boost/smart_ptr/detail/sp_noexcept.hpp +++ b/lslboost/boost/smart_ptr/detail/sp_noexcept.hpp @@ -15,25 +15,16 @@ // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt -#include -// BOOST_SP_NOEXCEPT +// BOOST_SP_NOEXCEPT (obsolete, only retained for compatibility) -#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1700 && BOOST_MSVC < 1900 +#define BOOST_SP_NOEXCEPT noexcept -# define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT_OR_NOTHROW - -#else - -# define BOOST_SP_NOEXCEPT BOOST_NOEXCEPT - -#endif - -// BOOST_SP_NOEXCEPT_WITH_ASSERT +// BOOST_SP_NOEXCEPT_WITH_ASSERT (noexcept, unless a user assertion handler is present) #if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) ) -# define BOOST_SP_NOEXCEPT_WITH_ASSERT BOOST_SP_NOEXCEPT +# define BOOST_SP_NOEXCEPT_WITH_ASSERT noexcept #elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) ) @@ -41,7 +32,7 @@ #else -# define BOOST_SP_NOEXCEPT_WITH_ASSERT BOOST_SP_NOEXCEPT +# define BOOST_SP_NOEXCEPT_WITH_ASSERT noexcept #endif diff --git a/lslboost/boost/smart_ptr/detail/sp_nullptr_t.hpp b/lslboost/boost/smart_ptr/detail/sp_nullptr_t.hpp deleted file mode 100644 index 5b5194bf7..000000000 --- a/lslboost/boost/smart_ptr/detail/sp_nullptr_t.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED -#define BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED - -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -// detail/sp_nullptr_t.hpp -// -// Copyright 2013 Peter Dimov -// -// Distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt - -#include -#include - -#if !defined( BOOST_NO_CXX11_NULLPTR ) - -namespace lslboost -{ - -namespace detail -{ - -#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) ) - - typedef decltype(nullptr) sp_nullptr_t; - -#else - - typedef std::nullptr_t sp_nullptr_t; - -#endif - -} // namespace detail - -} // namespace lslboost - -#endif // !defined( BOOST_NO_CXX11_NULLPTR ) - -#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_NULLPTR_T_HPP_INCLUDED diff --git a/lslboost/boost/smart_ptr/intrusive_ptr.hpp b/lslboost/boost/smart_ptr/intrusive_ptr.hpp index be0fe3e83..6e0a1ef91 100644 --- a/lslboost/boost/smart_ptr/intrusive_ptr.hpp +++ b/lslboost/boost/smart_ptr/intrusive_ptr.hpp @@ -13,26 +13,14 @@ // See http://www.boost.org/libs/smart_ptr/ for documentation. // -#include - -#include - -#include -#include +#include #include -#include #include +#include -#include // for std::less - -#if !defined(BOOST_NO_IOSTREAM) -#if !defined(BOOST_NO_IOSFWD) +#include // for std::less #include // for std::basic_ostream -#else -#include -#endif -#endif - +#include namespace lslboost { @@ -62,64 +50,46 @@ template class intrusive_ptr typedef T element_type; - BOOST_CONSTEXPR intrusive_ptr() BOOST_SP_NOEXCEPT : px( 0 ) + constexpr intrusive_ptr() noexcept : px( 0 ) { } - intrusive_ptr( T * p, bool add_ref = true ): px( p ) + BOOST_SP_CXX20_CONSTEXPR intrusive_ptr( T * p, bool add_ref = true ): px( p ) { if( px != 0 && add_ref ) intrusive_ptr_add_ref( px ); } -#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) - template -#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) - - intrusive_ptr( intrusive_ptr const & rhs, typename lslboost::detail::sp_enable_if_convertible::type = lslboost::detail::sp_empty() ) - -#else - - intrusive_ptr( intrusive_ptr const & rhs ) - -#endif + BOOST_SP_CXX20_CONSTEXPR intrusive_ptr( intrusive_ptr const & rhs, typename lslboost::detail::sp_enable_if_convertible::type = lslboost::detail::sp_empty() ) : px( rhs.get() ) { if( px != 0 ) intrusive_ptr_add_ref( px ); } -#endif - - intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px ) + BOOST_SP_CXX20_CONSTEXPR intrusive_ptr(intrusive_ptr const & rhs): px( rhs.px ) { if( px != 0 ) intrusive_ptr_add_ref( px ); } - ~intrusive_ptr() + BOOST_SP_CXX20_CONSTEXPR ~intrusive_ptr() { if( px != 0 ) intrusive_ptr_release( px ); } -#if !defined(BOOST_NO_MEMBER_TEMPLATES) || defined(BOOST_MSVC6_MEMBER_TEMPLATES) - - template intrusive_ptr & operator=(intrusive_ptr const & rhs) + template BOOST_SP_CXX20_CONSTEXPR intrusive_ptr & operator=(intrusive_ptr const & rhs) { this_type(rhs).swap(*this); return *this; } -#endif - // Move support -#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - - intrusive_ptr(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT : px( rhs.px ) + BOOST_SP_CXX20_CONSTEXPR intrusive_ptr(intrusive_ptr && rhs) noexcept : px( rhs.px ) { rhs.px = 0; } - intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT + BOOST_SP_CXX20_CONSTEXPR intrusive_ptr & operator=(intrusive_ptr && rhs) noexcept { this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this); return *this; @@ -128,84 +98,76 @@ template class intrusive_ptr template friend class intrusive_ptr; template -#if !defined( BOOST_SP_NO_SP_CONVERTIBLE ) - - intrusive_ptr(intrusive_ptr && rhs, typename lslboost::detail::sp_enable_if_convertible::type = lslboost::detail::sp_empty()) - -#else - - intrusive_ptr(intrusive_ptr && rhs) - -#endif + BOOST_SP_CXX20_CONSTEXPR intrusive_ptr(intrusive_ptr && rhs, typename lslboost::detail::sp_enable_if_convertible::type = lslboost::detail::sp_empty()) : px( rhs.px ) { rhs.px = 0; } template - intrusive_ptr & operator=(intrusive_ptr && rhs) BOOST_SP_NOEXCEPT + BOOST_SP_CXX20_CONSTEXPR intrusive_ptr & operator=(intrusive_ptr && rhs) noexcept { this_type( static_cast< intrusive_ptr && >( rhs ) ).swap(*this); return *this; } -#endif - - intrusive_ptr & operator=(intrusive_ptr const & rhs) + BOOST_SP_CXX20_CONSTEXPR intrusive_ptr & operator=(intrusive_ptr const & rhs) { this_type(rhs).swap(*this); return *this; } - intrusive_ptr & operator=(T * rhs) + BOOST_SP_CXX20_CONSTEXPR intrusive_ptr & operator=(T * rhs) { this_type(rhs).swap(*this); return *this; } - void reset() + BOOST_SP_CXX20_CONSTEXPR void reset() { this_type().swap( *this ); } - void reset( T * rhs ) + BOOST_SP_CXX20_CONSTEXPR void reset( T * rhs ) { this_type( rhs ).swap( *this ); } - void reset( T * rhs, bool add_ref ) + BOOST_SP_CXX20_CONSTEXPR void reset( T * rhs, bool add_ref ) { this_type( rhs, add_ref ).swap( *this ); } - T * get() const BOOST_SP_NOEXCEPT + BOOST_SP_CXX20_CONSTEXPR T * get() const noexcept { return px; } - T * detach() BOOST_SP_NOEXCEPT + BOOST_SP_CXX20_CONSTEXPR T * detach() noexcept { T * ret = px; px = 0; return ret; } - T & operator*() const BOOST_SP_NOEXCEPT_WITH_ASSERT + BOOST_SP_CXX20_CONSTEXPR T & operator*() const BOOST_SP_NOEXCEPT_WITH_ASSERT { BOOST_ASSERT( px != 0 ); return *px; } - T * operator->() const BOOST_SP_NOEXCEPT_WITH_ASSERT + BOOST_SP_CXX20_CONSTEXPR T * operator->() const BOOST_SP_NOEXCEPT_WITH_ASSERT { BOOST_ASSERT( px != 0 ); return px; } -// implicit conversion to "bool" -#include + BOOST_SP_CXX20_CONSTEXPR explicit operator bool () const noexcept + { + return px != 0; + } - void swap(intrusive_ptr & rhs) BOOST_SP_NOEXCEPT + BOOST_SP_CXX20_CONSTEXPR void swap(intrusive_ptr & rhs) noexcept { T * tmp = px; px = rhs.px; @@ -217,118 +179,101 @@ template class intrusive_ptr T * px; }; -template inline bool operator==(intrusive_ptr const & a, intrusive_ptr const & b) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator==(intrusive_ptr const & a, intrusive_ptr const & b) noexcept { return a.get() == b.get(); } -template inline bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) noexcept { return a.get() != b.get(); } -template inline bool operator==(intrusive_ptr const & a, U * b) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator==(intrusive_ptr const & a, U * b) noexcept { return a.get() == b; } -template inline bool operator!=(intrusive_ptr const & a, U * b) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator!=(intrusive_ptr const & a, U * b) noexcept { return a.get() != b; } -template inline bool operator==(T * a, intrusive_ptr const & b) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator==(T * a, intrusive_ptr const & b) noexcept { return a == b.get(); } -template inline bool operator!=(T * a, intrusive_ptr const & b) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator!=(T * a, intrusive_ptr const & b) noexcept { return a != b.get(); } -#if defined(__GNUC__) && __GNUC__ == 2 && __GNUC_MINOR__ <= 96 - -// Resolve the ambiguity between our op!= and the one in rel_ops - -template inline bool operator!=(intrusive_ptr const & a, intrusive_ptr const & b) BOOST_SP_NOEXCEPT -{ - return a.get() != b.get(); -} - -#endif - -#if !defined( BOOST_NO_CXX11_NULLPTR ) - -template inline bool operator==( intrusive_ptr const & p, lslboost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator==( intrusive_ptr const & p, std::nullptr_t ) noexcept { return p.get() == 0; } -template inline bool operator==( lslboost::detail::sp_nullptr_t, intrusive_ptr const & p ) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator==( std::nullptr_t, intrusive_ptr const & p ) noexcept { return p.get() == 0; } -template inline bool operator!=( intrusive_ptr const & p, lslboost::detail::sp_nullptr_t ) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator!=( intrusive_ptr const & p, std::nullptr_t ) noexcept { return p.get() != 0; } -template inline bool operator!=( lslboost::detail::sp_nullptr_t, intrusive_ptr const & p ) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator!=( std::nullptr_t, intrusive_ptr const & p ) noexcept { return p.get() != 0; } -#endif - -template inline bool operator<(intrusive_ptr const & a, intrusive_ptr const & b) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline bool operator<(intrusive_ptr const & a, intrusive_ptr const & b) noexcept { return std::less()(a.get(), b.get()); } -template void swap(intrusive_ptr & lhs, intrusive_ptr & rhs) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline void swap(intrusive_ptr & lhs, intrusive_ptr & rhs) noexcept { lhs.swap(rhs); } // mem_fn support -template T * get_pointer(intrusive_ptr const & p) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline T * get_pointer(intrusive_ptr const & p) noexcept { return p.get(); } // pointer casts -template intrusive_ptr static_pointer_cast(intrusive_ptr const & p) +template BOOST_SP_CXX20_CONSTEXPR inline intrusive_ptr static_pointer_cast(intrusive_ptr const & p) { return static_cast(p.get()); } -template intrusive_ptr const_pointer_cast(intrusive_ptr const & p) +template BOOST_SP_CXX20_CONSTEXPR inline intrusive_ptr const_pointer_cast(intrusive_ptr const & p) { return const_cast(p.get()); } -template intrusive_ptr dynamic_pointer_cast(intrusive_ptr const & p) +template BOOST_SP_CXX20_CONSTEXPR inline intrusive_ptr dynamic_pointer_cast(intrusive_ptr const & p) { return dynamic_cast(p.get()); } -#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - -template intrusive_ptr static_pointer_cast( intrusive_ptr && p ) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline intrusive_ptr static_pointer_cast( intrusive_ptr && p ) noexcept { return intrusive_ptr( static_cast( p.detach() ), false ); } -template intrusive_ptr const_pointer_cast( intrusive_ptr && p ) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline intrusive_ptr const_pointer_cast( intrusive_ptr && p ) noexcept { return intrusive_ptr( const_cast( p.detach() ), false ); } -template intrusive_ptr dynamic_pointer_cast( intrusive_ptr && p ) BOOST_SP_NOEXCEPT +template BOOST_SP_CXX20_CONSTEXPR inline intrusive_ptr dynamic_pointer_cast( intrusive_ptr && p ) noexcept { T * p2 = dynamic_cast( p.get() ); @@ -339,48 +284,19 @@ template intrusive_ptr dynamic_pointer_cast( intrusive_ptr< return r; } -#endif // defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) - // operator<< -#if !defined(BOOST_NO_IOSTREAM) - -#if defined(BOOST_NO_TEMPLATED_IOSTREAMS) || ( defined(__GNUC__) && (__GNUC__ < 3) ) - -template std::ostream & operator<< (std::ostream & os, intrusive_ptr const & p) -{ - os << p.get(); - return os; -} - -#else - -// in STLport's no-iostreams mode no iostream symbols can be used -#ifndef _STLP_NO_IOSTREAMS - -# if defined(BOOST_MSVC) && BOOST_WORKAROUND(BOOST_MSVC, < 1300 && __SGI_STL_PORT) -// MSVC6 has problems finding std::basic_ostream through the using declaration in namespace _STL -using std::basic_ostream; -template basic_ostream & operator<< (basic_ostream & os, intrusive_ptr const & p) -# else template std::basic_ostream & operator<< (std::basic_ostream & os, intrusive_ptr const & p) -# endif { os << p.get(); return os; } -#endif // _STLP_NO_IOSTREAMS - -#endif // __GNUC__ < 3 - -#endif // !defined(BOOST_NO_IOSTREAM) - // hash_value template< class T > struct hash; -template< class T > std::size_t hash_value( lslboost::intrusive_ptr const & p ) BOOST_SP_NOEXCEPT +template< class T > std::size_t hash_value( lslboost::intrusive_ptr const & p ) noexcept { return lslboost::hash< T* >()( p.get() ); } @@ -389,14 +305,12 @@ template< class T > std::size_t hash_value( lslboost::intrusive_ptr const & p // std::hash -#if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) - namespace std { template struct hash< ::lslboost::intrusive_ptr > { - std::size_t operator()( ::lslboost::intrusive_ptr const & p ) const BOOST_SP_NOEXCEPT + std::size_t operator()( ::lslboost::intrusive_ptr const & p ) const noexcept { return std::hash< T* >()( p.get() ); } @@ -404,6 +318,4 @@ template struct hash< ::lslboost::intrusive_ptr > } // namespace std -#endif // #if !defined(BOOST_NO_CXX11_HDR_FUNCTIONAL) - #endif // #ifndef BOOST_SMART_PTR_INTRUSIVE_PTR_HPP_INCLUDED diff --git a/lslboost/boost/version.hpp b/lslboost/boost/version.hpp index 6cd7e9aa3..7b9876448 100644 --- a/lslboost/boost/version.hpp +++ b/lslboost/boost/version.hpp @@ -19,7 +19,7 @@ // BOOST_VERSION / 100 % 1000 is the minor version // BOOST_VERSION / 100000 is the major version -#define BOOST_VERSION 108400 +#define BOOST_VERSION 108900 // // BOOST_LIB_VERSION must be defined to be the same as BOOST_VERSION @@ -27,6 +27,6 @@ // number, y is the minor version number, and z is the patch level if not 0. // This is used by to select which library version to link to. -#define BOOST_LIB_VERSION "1_84" +#define BOOST_LIB_VERSION "1_89" #endif diff --git a/standalone_compilation_linux.sh b/scripts/standalone_compilation_linux.sh similarity index 97% rename from standalone_compilation_linux.sh rename to scripts/standalone_compilation_linux.sh index 6f9baecab..f275558f4 100755 --- a/standalone_compilation_linux.sh +++ b/scripts/standalone_compilation_linux.sh @@ -6,6 +6,7 @@ # (pip install cmake) or as binary download from cmake.org set -e -x +cd "$(dirname "$0")/.." # Try to read LSLGITREVISION from git if the variable isn't set echo ${LSLGITREVISION:="$(git describe --tags HEAD)"} ${CXX:-g++} -fPIC -fvisibility=hidden -O2 ${CFLAGS} ${CXXFLAGS} -Ilslboost \ diff --git a/update_lslboost.sh b/scripts/update_lslboost.sh similarity index 91% rename from update_lslboost.sh rename to scripts/update_lslboost.sh index 14e3115a7..25cf54640 100755 --- a/update_lslboost.sh +++ b/scripts/update_lslboost.sh @@ -1,7 +1,9 @@ # the absolute path to the extracted boost source archive (https://www.boost.org/users/download/) set -e set -x -BOOSTPATH=/tmp/boost_1_84_0 + +cd "$(dirname "$0")/.." +BOOSTPATH=/tmp/boost_1_89_0 TMPPATH=/tmp/lslboost # copy all needed boost files and rename all mentions of boost to lslboost @@ -12,4 +14,3 @@ rm -f $TMPPATH/Jamroot find $TMPPATH -type d -and \( -name build -o -name test -o -name edg -o -name dmc -o -name msvc?0 -o -name bcc* \) -print0 | xargs -0 rm -rf rsync -HAXavr --del $TMPPATH/boost lslboost - diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt index 3fe89fabb..b8e292343 100644 --- a/testing/CMakeLists.txt +++ b/testing/CMakeLists.txt @@ -74,7 +74,8 @@ endif() message(STATUS ${LSL_TEST_INTERNAL_SRCS}) add_executable(lsl_test_internal ${LSL_TEST_INTERNAL_SRCS}) target_link_libraries(lsl_test_internal PRIVATE lslobj lslboost common catch_main) - +# Pretend that lsl_test_internal is part of a shared lib so that it can use the __export symbols lslobj. REQ by MinGW. +target_compile_definitions(lsl_test_internal PRIVATE LIBLSL_EXPORTS) if(LSL_BENCHMARKS) # to get somewhat reproducible performance numbers: diff --git a/testing/ext/discovery.cpp b/testing/ext/discovery.cpp index 4523a1fed..9ff923a4c 100644 --- a/testing/ext/discovery.cpp +++ b/testing/ext/discovery.cpp @@ -7,16 +7,20 @@ namespace { TEST_CASE("resolve multiple streams", "[resolver][basic]") { - lsl::continuous_resolver resolver("type", "Resolve", 50.); + // First create the outlets (to avoid extra waiting for + // multiple resolves) std::vector outlets; const int n = 3; for (int i = 0; i < n; i++) outlets.emplace_back(lsl::stream_info("resolvetest_" + std::to_string(i), "Resolve")); + lsl::continuous_resolver resolver("type", "Resolve", 50.); + + // Verify with one-time resolve auto found_stream_info = lsl::resolve_stream("type", "Resolve", n, 2.0); REQUIRE(found_stream_info.size() == n); - // Allow the resolver a bit more time in case the first resolve wave was too fast - std::this_thread::sleep_for(std::chrono::seconds(1)); + // Allow for enough time (interval, min_rtt) + std::this_thread::sleep_for(std::chrono::milliseconds(1600)); REQUIRE(resolver.results().size() == n); } diff --git a/thirdparty/asio/asio.hpp b/thirdparty/asio/asio.hpp index a973ab178..2398b717f 100644 --- a/thirdparty/asio/asio.hpp +++ b/thirdparty/asio/asio.hpp @@ -2,7 +2,7 @@ // asio.hpp // ~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -28,7 +28,6 @@ #include "asio/async_result.hpp" #include "asio/awaitable.hpp" #include "asio/basic_datagram_socket.hpp" -#include "asio/basic_deadline_timer.hpp" #include "asio/basic_file.hpp" #include "asio/basic_io_object.hpp" #include "asio/basic_random_access_file.hpp" @@ -59,21 +58,27 @@ #include "asio/buffered_write_stream_fwd.hpp" #include "asio/buffered_write_stream.hpp" #include "asio/buffers_iterator.hpp" +#include "asio/cancel_after.hpp" +#include "asio/cancel_at.hpp" #include "asio/cancellation_signal.hpp" #include "asio/cancellation_state.hpp" #include "asio/cancellation_type.hpp" +#include "asio/co_composed.hpp" #include "asio/co_spawn.hpp" #include "asio/completion_condition.hpp" #include "asio/compose.hpp" +#include "asio/composed.hpp" +#include "asio/config.hpp" #include "asio/connect.hpp" #include "asio/connect_pipe.hpp" #include "asio/consign.hpp" #include "asio/coroutine.hpp" -#include "asio/deadline_timer.hpp" #include "asio/defer.hpp" #include "asio/deferred.hpp" +#include "asio/default_completion_token.hpp" #include "asio/detached.hpp" #include "asio/dispatch.hpp" +#include "asio/disposition.hpp" #include "asio/error.hpp" #include "asio/error_code.hpp" #include "asio/execution.hpp" @@ -81,30 +86,15 @@ #include "asio/execution/any_executor.hpp" #include "asio/execution/blocking.hpp" #include "asio/execution/blocking_adaptation.hpp" -#include "asio/execution/bulk_execute.hpp" -#include "asio/execution/bulk_guarantee.hpp" -#include "asio/execution/connect.hpp" #include "asio/execution/context.hpp" #include "asio/execution/context_as.hpp" -#include "asio/execution/execute.hpp" #include "asio/execution/executor.hpp" #include "asio/execution/invocable_archetype.hpp" #include "asio/execution/mapping.hpp" #include "asio/execution/occupancy.hpp" -#include "asio/execution/operation_state.hpp" #include "asio/execution/outstanding_work.hpp" #include "asio/execution/prefer_only.hpp" -#include "asio/execution/receiver.hpp" -#include "asio/execution/receiver_invocation_error.hpp" #include "asio/execution/relationship.hpp" -#include "asio/execution/schedule.hpp" -#include "asio/execution/scheduler.hpp" -#include "asio/execution/sender.hpp" -#include "asio/execution/set_done.hpp" -#include "asio/execution/set_error.hpp" -#include "asio/execution/set_value.hpp" -#include "asio/execution/start.hpp" -#include "asio/execution_context.hpp" #include "asio/executor.hpp" #include "asio/executor_work_guard.hpp" #include "asio/file_base.hpp" @@ -113,14 +103,11 @@ #include "asio/generic/raw_protocol.hpp" #include "asio/generic/seq_packet_protocol.hpp" #include "asio/generic/stream_protocol.hpp" -#include "asio/handler_alloc_hook.hpp" #include "asio/handler_continuation_hook.hpp" -#include "asio/handler_invoke_hook.hpp" #include "asio/high_resolution_timer.hpp" +#include "asio/immediate.hpp" #include "asio/io_context.hpp" #include "asio/io_context_strand.hpp" -#include "asio/io_service.hpp" -#include "asio/io_service_strand.hpp" #include "asio/ip/address.hpp" #include "asio/ip/address_v4.hpp" #include "asio/ip/address_v4_iterator.hpp" @@ -194,7 +181,6 @@ #include "asio/this_coro.hpp" #include "asio/thread.hpp" #include "asio/thread_pool.hpp" -#include "asio/time_traits.hpp" #include "asio/use_awaitable.hpp" #include "asio/use_future.hpp" #include "asio/uses_executor.hpp" diff --git a/thirdparty/asio/asio/any_completion_executor.hpp b/thirdparty/asio/asio/any_completion_executor.hpp index 420927cc1..c270b8d28 100644 --- a/thirdparty/asio/asio/any_completion_executor.hpp +++ b/thirdparty/asio/asio/any_completion_executor.hpp @@ -2,7 +2,7 @@ // any_completion_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -75,20 +75,18 @@ class any_completion_executor : #endif // !defined(GENERATING_DOCUMENTATION) /// Default constructor. - ASIO_DECL any_completion_executor() ASIO_NOEXCEPT; + ASIO_DECL any_completion_executor() noexcept; /// Construct in an empty state. Equivalent effects to default constructor. - ASIO_DECL any_completion_executor(nullptr_t) ASIO_NOEXCEPT; + ASIO_DECL any_completion_executor(nullptr_t) noexcept; /// Copy constructor. ASIO_DECL any_completion_executor( - const any_completion_executor& e) ASIO_NOEXCEPT; + const any_completion_executor& e) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. ASIO_DECL any_completion_executor( - any_completion_executor&& e) ASIO_NOEXCEPT; -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + any_completion_executor&& e) noexcept; /// Construct to point to the same target as another any_executor. #if defined(GENERATING_DOCUMENTATION) @@ -98,7 +96,7 @@ class any_completion_executor : #else // defined(GENERATING_DOCUMENTATION) template any_completion_executor(OtherAnyExecutor e, - typename constraint< + constraint_t< conditional< !is_same::value && is_base_of, false_type >::type::value - >::type = 0) - : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e)) + > = 0) + : base_type(static_cast(e)) { } #endif // defined(GENERATING_DOCUMENTATION) @@ -122,7 +120,7 @@ class any_completion_executor : #else // defined(GENERATING_DOCUMENTATION) template any_completion_executor(std::nothrow_t, OtherAnyExecutor e, - typename constraint< + constraint_t< conditional< !is_same::value && is_base_of, false_type >::type::value - >::type = 0) ASIO_NOEXCEPT - : base_type(std::nothrow, ASIO_MOVE_CAST(OtherAnyExecutor)(e)) + > = 0) noexcept + : base_type(std::nothrow, static_cast(e)) { } #endif // defined(GENERATING_DOCUMENTATION) /// Construct to point to the same target as another any_executor. ASIO_DECL any_completion_executor(std::nothrow_t, - const any_completion_executor& e) ASIO_NOEXCEPT; + const any_completion_executor& e) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct to point to the same target as another any_executor. ASIO_DECL any_completion_executor(std::nothrow_t, - any_completion_executor&& e) ASIO_NOEXCEPT; -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + any_completion_executor&& e) noexcept; /// Construct a polymorphic wrapper for the specified executor. #if defined(GENERATING_DOCUMENTATION) @@ -155,7 +151,7 @@ class any_completion_executor : #else // defined(GENERATING_DOCUMENTATION) template any_completion_executor(Executor e, - typename constraint< + constraint_t< conditional< !is_same::value && !is_base_of, false_type >::type::value - >::type = 0) - : base_type(ASIO_MOVE_CAST(Executor)(e)) + > = 0) + : base_type(static_cast(e)) { } #endif // defined(GENERATING_DOCUMENTATION) @@ -177,7 +173,7 @@ class any_completion_executor : #else // defined(GENERATING_DOCUMENTATION) template any_completion_executor(std::nothrow_t, Executor e, - typename constraint< + constraint_t< conditional< !is_same::value && !is_base_of, false_type >::type::value - >::type = 0) ASIO_NOEXCEPT - : base_type(std::nothrow, ASIO_MOVE_CAST(Executor)(e)) + > = 0) noexcept + : base_type(std::nothrow, static_cast(e)) { } #endif // defined(GENERATING_DOCUMENTATION) /// Assignment operator. ASIO_DECL any_completion_executor& operator=( - const any_completion_executor& e) ASIO_NOEXCEPT; + const any_completion_executor& e) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment operator. ASIO_DECL any_completion_executor& operator=( - any_completion_executor&& e) ASIO_NOEXCEPT; -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + any_completion_executor&& e) noexcept; /// Assignment operator that sets the polymorphic wrapper to the empty state. ASIO_DECL any_completion_executor& operator=(nullptr_t); @@ -209,7 +203,7 @@ class any_completion_executor : ASIO_DECL ~any_completion_executor(); /// Swap targets with another polymorphic wrapper. - ASIO_DECL void swap(any_completion_executor& other) ASIO_NOEXCEPT; + ASIO_DECL void swap(any_completion_executor& other) noexcept; /// Obtain a polymorphic wrapper with the specified property. /** @@ -222,9 +216,9 @@ class any_completion_executor : */ template any_completion_executor require(const Property& p, - typename constraint< + constraint_t< traits::require_member::is_valid - >::type = 0) const + > = 0) const { return static_cast(*this).require(p); } @@ -240,9 +234,9 @@ class any_completion_executor : */ template any_completion_executor prefer(const Property& p, - typename constraint< + constraint_t< traits::prefer_member::is_valid - >::type = 0) const + > = 0) const { return static_cast(*this).prefer(p); } diff --git a/thirdparty/asio/asio/any_completion_handler.hpp b/thirdparty/asio/asio/any_completion_handler.hpp index cd114537f..1114a09c6 100644 --- a/thirdparty/asio/asio/any_completion_handler.hpp +++ b/thirdparty/asio/asio/any_completion_handler.hpp @@ -2,7 +2,7 @@ // any_completion_handler.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -12,20 +12,16 @@ #define ASIO_ANY_COMPLETION_HANDLER_HPP #include "asio/detail/config.hpp" - -#if (defined(ASIO_HAS_STD_TUPLE) \ - && defined(ASIO_HAS_MOVE) \ - && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \ - || defined(GENERATING_DOCUMENTATION) - #include #include #include #include #include "asio/any_completion_executor.hpp" +#include "asio/any_io_executor.hpp" #include "asio/associated_allocator.hpp" #include "asio/associated_cancellation_slot.hpp" #include "asio/associated_executor.hpp" +#include "asio/associated_immediate_executor.hpp" #include "asio/cancellation_state.hpp" #include "asio/recycling_allocator.hpp" @@ -39,11 +35,11 @@ class any_completion_handler_impl_base public: template explicit any_completion_handler_impl_base(S&& slot) - : cancel_state_(ASIO_MOVE_CAST(S)(slot), enable_total_cancellation()) + : cancel_state_(static_cast(slot), enable_total_cancellation()) { } - cancellation_slot get_cancellation_slot() const ASIO_NOEXCEPT + cancellation_slot get_cancellation_slot() const noexcept { return cancel_state_.slot(); } @@ -59,8 +55,8 @@ class any_completion_handler_impl : public: template any_completion_handler_impl(S&& slot, H&& h) - : any_completion_handler_impl_base(ASIO_MOVE_CAST(S)(slot)), - handler_(ASIO_MOVE_CAST(H)(h)) + : any_completion_handler_impl_base(static_cast(slot)), + handler_(static_cast(h)) { } @@ -103,7 +99,7 @@ class any_completion_handler_impl : any_completion_handler_impl* ptr = new (uninit_ptr.get()) any_completion_handler_impl( - ASIO_MOVE_CAST(S)(slot), ASIO_MOVE_CAST(H)(h)); + static_cast(slot), static_cast(h)); uninit_ptr.release(); return ptr; @@ -119,13 +115,20 @@ class any_completion_handler_impl : } any_completion_executor executor( - const any_completion_executor& candidate) const ASIO_NOEXCEPT + const any_completion_executor& candidate) const noexcept { return any_completion_executor(std::nothrow, (get_associated_executor)(handler_, candidate)); } - void* allocate(std::size_t size, std::size_t align) const + any_completion_executor immediate_executor( + const any_io_executor& candidate) const noexcept + { + return any_completion_executor(std::nothrow, + (get_associated_immediate_executor)(handler_, candidate)); + } + + void* allocate(std::size_t size, std::size_t align_size) const { typename std::allocator_traits< associated_allocator_t())); - std::size_t space = size + align - 1; + std::size_t space = size + align_size - 1; unsigned char* base = std::allocator_traits::allocate( alloc, space + sizeof(std::ptrdiff_t)); void* p = base; - if (detail::align(align, size, p, space)) + if (detail::align(align_size, size, p, space)) { std::ptrdiff_t off = static_cast(p) - base; std::memcpy(static_cast(p) + size, &off, sizeof(off)); @@ -180,11 +183,11 @@ class any_completion_handler_impl : asio::recycling_allocator())}; std::unique_ptr ptr(this, d); - Handler handler(ASIO_MOVE_CAST(Handler)(handler_)); + Handler handler(static_cast(handler_)); ptr.reset(); - ASIO_MOVE_CAST(Handler)(handler)( - ASIO_MOVE_CAST(Args)(args)...); + static_cast(handler)( + static_cast(args)...); } private: @@ -207,14 +210,14 @@ class any_completion_handler_call_fn void call(any_completion_handler_impl_base* impl, Args... args) const { - call_fn_(impl, ASIO_MOVE_CAST(Args)(args)...); + call_fn_(impl, static_cast(args)...); } template static void impl(any_completion_handler_impl_base* impl, Args... args) { static_cast*>(impl)->call( - ASIO_MOVE_CAST(Args)(args)...); + static_cast(args)...); } private: @@ -305,6 +308,36 @@ class any_completion_handler_executor_fn type executor_fn_; }; +class any_completion_handler_immediate_executor_fn +{ +public: + using type = any_completion_executor(*)( + any_completion_handler_impl_base*, const any_io_executor&); + + constexpr any_completion_handler_immediate_executor_fn(type fn) + : immediate_executor_fn_(fn) + { + } + + any_completion_executor immediate_executor( + any_completion_handler_impl_base* impl, + const any_io_executor& candidate) const + { + return immediate_executor_fn_(impl, candidate); + } + + template + static any_completion_executor impl(any_completion_handler_impl_base* impl, + const any_io_executor& candidate) + { + return static_cast*>( + impl)->immediate_executor(candidate); + } + +private: + type immediate_executor_fn_; +}; + class any_completion_handler_allocate_fn { public: @@ -367,6 +400,7 @@ template class any_completion_handler_fn_table : private any_completion_handler_destroy_fn, private any_completion_handler_executor_fn, + private any_completion_handler_immediate_executor_fn, private any_completion_handler_allocate_fn, private any_completion_handler_deallocate_fn, private any_completion_handler_call_fns @@ -376,11 +410,13 @@ class any_completion_handler_fn_table constexpr any_completion_handler_fn_table( any_completion_handler_destroy_fn::type destroy_fn, any_completion_handler_executor_fn::type executor_fn, + any_completion_handler_immediate_executor_fn::type immediate_executor_fn, any_completion_handler_allocate_fn::type allocate_fn, any_completion_handler_deallocate_fn::type deallocate_fn, CallFns... call_fns) : any_completion_handler_destroy_fn(destroy_fn), any_completion_handler_executor_fn(executor_fn), + any_completion_handler_immediate_executor_fn(immediate_executor_fn), any_completion_handler_allocate_fn(allocate_fn), any_completion_handler_deallocate_fn(deallocate_fn), any_completion_handler_call_fns(call_fns...) @@ -389,6 +425,7 @@ class any_completion_handler_fn_table using any_completion_handler_destroy_fn::destroy; using any_completion_handler_executor_fn::executor; + using any_completion_handler_immediate_executor_fn::immediate_executor; using any_completion_handler_allocate_fn::allocate; using any_completion_handler_deallocate_fn::deallocate; using any_completion_handler_call_fns::call; @@ -401,6 +438,7 @@ struct any_completion_handler_fn_table_instance value = any_completion_handler_fn_table( &any_completion_handler_destroy_fn::impl, &any_completion_handler_executor_fn::impl, + &any_completion_handler_immediate_executor_fn::impl, &any_completion_handler_allocate_fn::impl, &any_completion_handler_deallocate_fn::impl, &any_completion_handler_call_fn::template impl...); @@ -431,7 +469,7 @@ class any_completion_handler_allocator detail::any_completion_handler_impl_base* impl_; constexpr any_completion_handler_allocator(int, - const any_completion_handler& h) ASIO_NOEXCEPT + const any_completion_handler& h) noexcept : fn_table_(h.fn_table_), impl_(h.impl_) { @@ -453,7 +491,7 @@ class any_completion_handler_allocator template constexpr any_completion_handler_allocator( const any_completion_handler_allocator& a) - ASIO_NOEXCEPT + noexcept : fn_table_(a.fn_table_), impl_(a.impl_) { @@ -461,14 +499,14 @@ class any_completion_handler_allocator /// Equality operator. constexpr bool operator==( - const any_completion_handler_allocator& other) const ASIO_NOEXCEPT + const any_completion_handler_allocator& other) const noexcept { return fn_table_ == other.fn_table_ && impl_ == other.impl_; } /// Inequality operator. constexpr bool operator!=( - const any_completion_handler_allocator& other) const ASIO_NOEXCEPT + const any_completion_handler_allocator& other) const noexcept { return fn_table_ != other.fn_table_ || impl_ != other.impl_; } @@ -476,9 +514,15 @@ class any_completion_handler_allocator /// Allocate space for @c n objects of the allocator's value type. T* allocate(std::size_t n) const { - return static_cast( - fn_table_->allocate( - impl_, sizeof(T) * n, alignof(T))); + if (fn_table_) + { + return static_cast( + fn_table_->allocate( + impl_, sizeof(T) * n, alignof(T))); + } + std::bad_alloc ex; + asio::detail::throw_exception(ex); + return nullptr; } /// Deallocate space for @c n objects of the allocator's value type. @@ -505,7 +549,7 @@ class any_completion_handler_allocator detail::any_completion_handler_impl_base* impl_; constexpr any_completion_handler_allocator(int, - const any_completion_handler& h) ASIO_NOEXCEPT + const any_completion_handler& h) noexcept : fn_table_(h.fn_table_), impl_(h.impl_) { @@ -527,7 +571,7 @@ class any_completion_handler_allocator template constexpr any_completion_handler_allocator( const any_completion_handler_allocator& a) - ASIO_NOEXCEPT + noexcept : fn_table_(a.fn_table_), impl_(a.impl_) { @@ -535,14 +579,14 @@ class any_completion_handler_allocator /// Equality operator. constexpr bool operator==( - const any_completion_handler_allocator& other) const ASIO_NOEXCEPT + const any_completion_handler_allocator& other) const noexcept { return fn_table_ == other.fn_table_ && impl_ == other.impl_; } /// Inequality operator. constexpr bool operator!=( - const any_completion_handler_allocator& other) const ASIO_NOEXCEPT + const any_completion_handler_allocator& other) const noexcept { return fn_table_ != other.fn_table_ || impl_ != other.impl_; } @@ -576,6 +620,9 @@ class any_completion_handler template friend struct associated_executor; + template + friend struct associated_immediate_executor; + const detail::any_completion_handler_fn_table* fn_table_; detail::any_completion_handler_impl_base* impl_; #endif // !defined(GENERATING_DOCUMENTATION) @@ -604,16 +651,16 @@ class any_completion_handler } /// Construct an @c any_completion_handler to contain the specified target. - template ::type> + template > any_completion_handler(H&& h, - typename constraint< - !is_same::type, any_completion_handler>::value - >::type = 0) + constraint_t< + !is_same, any_completion_handler>::value + > = 0) : fn_table_( &detail::any_completion_handler_fn_table_instance< Handler, Signatures...>::value), impl_(detail::any_completion_handler_impl::create( - (get_associated_cancellation_slot)(h), ASIO_MOVE_CAST(H)(h))) + (get_associated_cancellation_slot)(h), static_cast(h))) { } @@ -621,7 +668,7 @@ class any_completion_handler /** * After the operation, the moved-from object @c other has no target. */ - any_completion_handler(any_completion_handler&& other) ASIO_NOEXCEPT + any_completion_handler(any_completion_handler&& other) noexcept : fn_table_(other.fn_table_), impl_(other.impl_) { @@ -634,15 +681,15 @@ class any_completion_handler * After the operation, the moved-from object @c other has no target. */ any_completion_handler& operator=( - any_completion_handler&& other) ASIO_NOEXCEPT + any_completion_handler&& other) noexcept { any_completion_handler( - ASIO_MOVE_CAST(any_completion_handler)(other)).swap(*this); + static_cast(other)).swap(*this); return *this; } /// Assignment operator that sets the polymorphic wrapper to the empty state. - any_completion_handler& operator=(nullptr_t) ASIO_NOEXCEPT + any_completion_handler& operator=(nullptr_t) noexcept { any_completion_handler().swap(*this); return *this; @@ -656,34 +703,34 @@ class any_completion_handler } /// Test if the polymorphic wrapper is empty. - constexpr explicit operator bool() const ASIO_NOEXCEPT + constexpr explicit operator bool() const noexcept { return impl_ != nullptr; } /// Test if the polymorphic wrapper is non-empty. - constexpr bool operator!() const ASIO_NOEXCEPT + constexpr bool operator!() const noexcept { return impl_ == nullptr; } /// Swap the content of an @c any_completion_handler with another. - void swap(any_completion_handler& other) ASIO_NOEXCEPT + void swap(any_completion_handler& other) noexcept { std::swap(fn_table_, other.fn_table_); std::swap(impl_, other.impl_); } /// Get the associated allocator. - allocator_type get_allocator() const ASIO_NOEXCEPT + allocator_type get_allocator() const noexcept { return allocator_type(0, *this); } /// Get the associated cancellation slot. - cancellation_slot_type get_cancellation_slot() const ASIO_NOEXCEPT + cancellation_slot_type get_cancellation_slot() const noexcept { - return impl_->get_cancellation_slot(); + return impl_ ? impl_->get_cancellation_slot() : cancellation_slot_type(); } /// Function call operator. @@ -697,12 +744,12 @@ class any_completion_handler */ template auto operator()(Args&&... args) - -> decltype(fn_table_->call(impl_, ASIO_MOVE_CAST(Args)(args)...)) + -> decltype(fn_table_->call(impl_, static_cast(args)...)) { if (detail::any_completion_handler_impl_base* impl = impl_) { impl_ = nullptr; - return fn_table_->call(impl, ASIO_MOVE_CAST(Args)(args)...); + return fn_table_->call(impl, static_cast(args)...); } std::bad_function_call ex; asio::detail::throw_exception(ex); @@ -710,28 +757,28 @@ class any_completion_handler /// Equality operator. friend constexpr bool operator==( - const any_completion_handler& a, nullptr_t) ASIO_NOEXCEPT + const any_completion_handler& a, nullptr_t) noexcept { return a.impl_ == nullptr; } /// Equality operator. friend constexpr bool operator==( - nullptr_t, const any_completion_handler& b) ASIO_NOEXCEPT + nullptr_t, const any_completion_handler& b) noexcept { return nullptr == b.impl_; } /// Inequality operator. friend constexpr bool operator!=( - const any_completion_handler& a, nullptr_t) ASIO_NOEXCEPT + const any_completion_handler& a, nullptr_t) noexcept { return a.impl_ != nullptr; } /// Inequality operator. friend constexpr bool operator!=( - nullptr_t, const any_completion_handler& b) ASIO_NOEXCEPT + nullptr_t, const any_completion_handler& b) noexcept { return nullptr != b.impl_; } @@ -743,10 +790,28 @@ struct associated_executor, Candidate> using type = any_completion_executor; static type get(const any_completion_handler& handler, - const Candidate& candidate = Candidate()) ASIO_NOEXCEPT + const Candidate& candidate = Candidate()) noexcept { - return handler.fn_table_->executor(handler.impl_, - any_completion_executor(std::nothrow, candidate)); + any_completion_executor any_candidate(std::nothrow, candidate); + return handler.fn_table_ + ? handler.fn_table_->executor(handler.impl_, any_candidate) + : any_candidate; + } +}; + +template +struct associated_immediate_executor< + any_completion_handler, Candidate> +{ + using type = any_completion_executor; + + static type get(const any_completion_handler& handler, + const Candidate& candidate = Candidate()) noexcept + { + any_io_executor any_candidate(std::nothrow, candidate); + return handler.fn_table_ + ? handler.fn_table_->immediate_executor(handler.impl_, any_candidate) + : any_candidate; } }; @@ -754,9 +819,4 @@ struct associated_executor, Candidate> #include "asio/detail/pop_options.hpp" -#endif // (defined(ASIO_HAS_STD_TUPLE) - // && defined(ASIO_HAS_MOVE) - // && defined(ASIO_HAS_VARIADIC_TEMPLATES)) - // || defined(GENERATING_DOCUMENTATION) - #endif // ASIO_ANY_COMPLETION_HANDLER_HPP diff --git a/thirdparty/asio/asio/any_io_executor.hpp b/thirdparty/asio/asio/any_io_executor.hpp index 7a77c90d1..a6c9c8dae 100644 --- a/thirdparty/asio/asio/any_io_executor.hpp +++ b/thirdparty/asio/asio/any_io_executor.hpp @@ -2,7 +2,7 @@ // any_io_executor.hpp // ~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -87,18 +87,16 @@ class any_io_executor : #endif // !defined(GENERATING_DOCUMENTATION) /// Default constructor. - ASIO_DECL any_io_executor() ASIO_NOEXCEPT; + ASIO_DECL any_io_executor() noexcept; /// Construct in an empty state. Equivalent effects to default constructor. - ASIO_DECL any_io_executor(nullptr_t) ASIO_NOEXCEPT; + ASIO_DECL any_io_executor(nullptr_t) noexcept; /// Copy constructor. - ASIO_DECL any_io_executor(const any_io_executor& e) ASIO_NOEXCEPT; + ASIO_DECL any_io_executor(const any_io_executor& e) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move constructor. - ASIO_DECL any_io_executor(any_io_executor&& e) ASIO_NOEXCEPT; -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + ASIO_DECL any_io_executor(any_io_executor&& e) noexcept; /// Construct to point to the same target as another any_executor. #if defined(GENERATING_DOCUMENTATION) @@ -107,8 +105,8 @@ class any_io_executor : #else // defined(GENERATING_DOCUMENTATION) template any_io_executor(OtherAnyExecutor e, - typename constraint< - conditional< + constraint_t< + conditional_t< !is_same::value && is_base_of::value, @@ -116,9 +114,9 @@ class any_io_executor : 0, supportable_properties_type>::template is_valid_target, false_type - >::type::value - >::type = 0) - : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e)) + >::value + > = 0) + : base_type(static_cast(e)) { } #endif // defined(GENERATING_DOCUMENTATION) @@ -131,8 +129,8 @@ class any_io_executor : #else // defined(GENERATING_DOCUMENTATION) template any_io_executor(std::nothrow_t, OtherAnyExecutor e, - typename constraint< - conditional< + constraint_t< + conditional_t< !is_same::value && is_base_of::value, @@ -140,22 +138,19 @@ class any_io_executor : 0, supportable_properties_type>::template is_valid_target, false_type - >::type::value - >::type = 0) ASIO_NOEXCEPT - : base_type(std::nothrow, ASIO_MOVE_CAST(OtherAnyExecutor)(e)) + >::value + > = 0) noexcept + : base_type(std::nothrow, static_cast(e)) { } #endif // defined(GENERATING_DOCUMENTATION) /// Construct to point to the same target as another any_executor. ASIO_DECL any_io_executor(std::nothrow_t, - const any_io_executor& e) ASIO_NOEXCEPT; + const any_io_executor& e) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Construct to point to the same target as another any_executor. - ASIO_DECL any_io_executor(std::nothrow_t, - any_io_executor&& e) ASIO_NOEXCEPT; -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + ASIO_DECL any_io_executor(std::nothrow_t, any_io_executor&& e) noexcept; /// Construct a polymorphic wrapper for the specified executor. #if defined(GENERATING_DOCUMENTATION) @@ -164,17 +159,17 @@ class any_io_executor : #else // defined(GENERATING_DOCUMENTATION) template any_io_executor(Executor e, - typename constraint< - conditional< + constraint_t< + conditional_t< !is_same::value && !is_base_of::value, execution::detail::is_valid_target_executor< Executor, supportable_properties_type>, false_type - >::type::value - >::type = 0) - : base_type(ASIO_MOVE_CAST(Executor)(e)) + >::value + > = 0) + : base_type(static_cast(e)) { } #endif // defined(GENERATING_DOCUMENTATION) @@ -186,30 +181,27 @@ class any_io_executor : #else // defined(GENERATING_DOCUMENTATION) template any_io_executor(std::nothrow_t, Executor e, - typename constraint< - conditional< + constraint_t< + conditional_t< !is_same::value && !is_base_of::value, execution::detail::is_valid_target_executor< Executor, supportable_properties_type>, false_type - >::type::value - >::type = 0) ASIO_NOEXCEPT - : base_type(std::nothrow, ASIO_MOVE_CAST(Executor)(e)) + >::value + > = 0) noexcept + : base_type(std::nothrow, static_cast(e)) { } #endif // defined(GENERATING_DOCUMENTATION) /// Assignment operator. ASIO_DECL any_io_executor& operator=( - const any_io_executor& e) ASIO_NOEXCEPT; + const any_io_executor& e) noexcept; -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) /// Move assignment operator. - ASIO_DECL any_io_executor& operator=( - any_io_executor&& e) ASIO_NOEXCEPT; -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) + ASIO_DECL any_io_executor& operator=(any_io_executor&& e) noexcept; /// Assignment operator that sets the polymorphic wrapper to the empty state. ASIO_DECL any_io_executor& operator=(nullptr_t); @@ -218,7 +210,7 @@ class any_io_executor : ASIO_DECL ~any_io_executor(); /// Swap targets with another polymorphic wrapper. - ASIO_DECL void swap(any_io_executor& other) ASIO_NOEXCEPT; + ASIO_DECL void swap(any_io_executor& other) noexcept; /// Obtain a polymorphic wrapper with the specified property. /** @@ -231,9 +223,9 @@ class any_io_executor : */ template any_io_executor require(const Property& p, - typename constraint< + constraint_t< traits::require_member::is_valid - >::type = 0) const + > = 0) const { return static_cast(*this).require(p); } @@ -249,9 +241,9 @@ class any_io_executor : */ template any_io_executor prefer(const Property& p, - typename constraint< + constraint_t< traits::prefer_member::is_valid - >::type = 0) const + > = 0) const { return static_cast(*this).prefer(p); } diff --git a/thirdparty/asio/asio/append.hpp b/thirdparty/asio/asio/append.hpp index 9ac4a9504..e0167e13b 100644 --- a/thirdparty/asio/asio/append.hpp +++ b/thirdparty/asio/asio/append.hpp @@ -2,7 +2,7 @@ // append.hpp // ~~~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -16,11 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" - -#if (defined(ASIO_HAS_STD_TUPLE) \ - && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \ - || defined(GENERATING_DOCUMENTATION) - #include #include "asio/detail/type_traits.hpp" @@ -37,11 +32,9 @@ class append_t public: /// Constructor. template - ASIO_CONSTEXPR explicit append_t( - ASIO_MOVE_ARG(T) completion_token, - ASIO_MOVE_ARG(V)... values) - : token_(ASIO_MOVE_CAST(T)(completion_token)), - values_(ASIO_MOVE_CAST(V)(values)...) + constexpr explicit append_t(T&& completion_token, V&&... values) + : token_(static_cast(completion_token)), + values_(static_cast(values)...) { } @@ -54,15 +47,13 @@ class append_t /// arguments should be passed additional values after the results of the /// operation. template -ASIO_NODISCARD inline ASIO_CONSTEXPR append_t< - typename decay::type, typename decay::type...> -append(ASIO_MOVE_ARG(CompletionToken) completion_token, - ASIO_MOVE_ARG(Values)... values) +ASIO_NODISCARD inline constexpr +append_t, decay_t...> +append(CompletionToken&& completion_token, Values&&... values) { - return append_t< - typename decay::type, typename decay::type...>( - ASIO_MOVE_CAST(CompletionToken)(completion_token), - ASIO_MOVE_CAST(Values)(values)...); + return append_t, decay_t...>( + static_cast(completion_token), + static_cast(values)...); } } // namespace asio @@ -71,8 +62,4 @@ append(ASIO_MOVE_ARG(CompletionToken) completion_token, #include "asio/impl/append.hpp" -#endif // (defined(ASIO_HAS_STD_TUPLE) - // && defined(ASIO_HAS_VARIADIC_TEMPLATES)) - // || defined(GENERATING_DOCUMENTATION) - #endif // ASIO_APPEND_HPP diff --git a/thirdparty/asio/asio/as_tuple.hpp b/thirdparty/asio/asio/as_tuple.hpp index 96ac47c82..d3250b75e 100644 --- a/thirdparty/asio/asio/as_tuple.hpp +++ b/thirdparty/asio/asio/as_tuple.hpp @@ -2,7 +2,7 @@ // as_tuple.hpp // ~~~~~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -16,11 +16,6 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" - -#if (defined(ASIO_HAS_STD_TUPLE) \ - && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \ - || defined(GENERATING_DOCUMENTATION) - #include "asio/detail/type_traits.hpp" #include "asio/detail/push_options.hpp" @@ -50,18 +45,18 @@ class as_tuple_t * token is itself defaulted as an argument to allow it to capture a source * location. */ - ASIO_CONSTEXPR as_tuple_t( + constexpr as_tuple_t( default_constructor_tag = default_constructor_tag(), CompletionToken token = CompletionToken()) - : token_(ASIO_MOVE_CAST(CompletionToken)(token)) + : token_(static_cast(token)) { } /// Constructor. template - ASIO_CONSTEXPR explicit as_tuple_t( - ASIO_MOVE_ARG(T) completion_token) - : token_(ASIO_MOVE_CAST(T)(completion_token)) + constexpr explicit as_tuple_t( + T&& completion_token) + : token_(static_cast(completion_token)) { } @@ -76,13 +71,13 @@ class as_tuple_t /// Construct the adapted executor from the inner executor type. template executor_with_default(const InnerExecutor1& ex, - typename constraint< - conditional< + constraint_t< + conditional_t< !is_same::value, is_convertible, false_type - >::type::value - >::type = 0) ASIO_NOEXCEPT + >::value + > = 0) noexcept : InnerExecutor(ex) { } @@ -90,41 +85,63 @@ class as_tuple_t /// Type alias to adapt an I/O object to use @c as_tuple_t as its /// default completion token type. -#if defined(ASIO_HAS_ALIAS_TEMPLATES) \ - || defined(GENERATING_DOCUMENTATION) template using as_default_on_t = typename T::template rebind_executor< - executor_with_default >::other; -#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) - // || defined(GENERATING_DOCUMENTATION) + executor_with_default>::other; /// Function helper to adapt an I/O object to use @c as_tuple_t as its /// default completion token type. template - static typename decay::type::template rebind_executor< - executor_with_default::type::executor_type> + static typename decay_t::template rebind_executor< + executor_with_default::executor_type> >::other - as_default_on(ASIO_MOVE_ARG(T) object) + as_default_on(T&& object) { - return typename decay::type::template rebind_executor< - executor_with_default::type::executor_type> - >::other(ASIO_MOVE_CAST(T)(object)); + return typename decay_t::template rebind_executor< + executor_with_default::executor_type> + >::other(static_cast(object)); } //private: CompletionToken token_; }; -/// Adapt a @ref completion_token to specify that the completion handler -/// arguments should be combined into a single tuple argument. -template -ASIO_NODISCARD inline -ASIO_CONSTEXPR as_tuple_t::type> -as_tuple(ASIO_MOVE_ARG(CompletionToken) completion_token) +/// A function object type that adapts a @ref completion_token to specify that +/// the completion handler arguments should be combined into a single tuple +/// argument. +/** + * May also be used directly as a completion token, in which case it adapts the + * asynchronous operation's default completion token (or asio::deferred + * if no default is available). + */ +struct partial_as_tuple { - return as_tuple_t::type>( - ASIO_MOVE_CAST(CompletionToken)(completion_token)); -} + /// Default constructor. + constexpr partial_as_tuple() + { + } + + /// Adapt a @ref completion_token to specify that the completion handler + /// arguments should be combined into a single tuple argument. + template + ASIO_NODISCARD inline + constexpr as_tuple_t> + operator()(CompletionToken&& completion_token) const + { + return as_tuple_t>( + static_cast(completion_token)); + } +}; + +/// A function object that adapts a @ref completion_token to specify that the +/// completion handler arguments should be combined into a single tuple +/// argument. +/** + * May also be used directly as a completion token, in which case it adapts the + * asynchronous operation's default completion token (or asio::deferred + * if no default is available). + */ +ASIO_INLINE_VARIABLE constexpr partial_as_tuple as_tuple; } // namespace asio @@ -132,8 +149,4 @@ as_tuple(ASIO_MOVE_ARG(CompletionToken) completion_token) #include "asio/impl/as_tuple.hpp" -#endif // (defined(ASIO_HAS_STD_TUPLE) - // && defined(ASIO_HAS_VARIADIC_TEMPLATES)) - // || defined(GENERATING_DOCUMENTATION) - #endif // ASIO_AS_TUPLE_HPP diff --git a/thirdparty/asio/asio/associated_allocator.hpp b/thirdparty/asio/asio/associated_allocator.hpp index 8e864673c..c15ff6dc5 100644 --- a/thirdparty/asio/asio/associated_allocator.hpp +++ b/thirdparty/asio/asio/associated_allocator.hpp @@ -2,7 +2,7 @@ // associated_allocator.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -36,9 +36,7 @@ struct has_allocator_type : false_type }; template -struct has_allocator_type::type> - : true_type +struct has_allocator_type> : true_type { }; @@ -49,33 +47,30 @@ struct associated_allocator_impl typedef A type; - static type get(const T&) ASIO_NOEXCEPT + static type get(const T&) noexcept { return type(); } - static const type& get(const T&, const A& a) ASIO_NOEXCEPT + static const type& get(const T&, const A& a) noexcept { return a; } }; template -struct associated_allocator_impl::type> +struct associated_allocator_impl> { typedef typename T::allocator_type type; - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - const T& t) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_allocator())) + static auto get(const T& t) noexcept + -> decltype(t.get_allocator()) { return t.get_allocator(); } - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - const T& t, const A&) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_allocator())) + static auto get(const T& t, const A&) noexcept + -> decltype(t.get_allocator()) { return t.get_allocator(); } @@ -83,12 +78,12 @@ struct associated_allocator_impl struct associated_allocator_impl::value - >::type, - typename void_type< + >, + void_t< typename associator::type - >::type> : associator + >> : associator { }; @@ -115,7 +110,7 @@ struct associated_allocator_impl > +template > struct associated_allocator #if !defined(GENERATING_DOCUMENTATION) : detail::associated_allocator_impl @@ -128,11 +123,11 @@ struct associated_allocator /// If @c T has a nested type @c allocator_type, returns /// t.get_allocator(). Otherwise returns @c type(). - static decltype(auto) get(const T& t) ASIO_NOEXCEPT; + static decltype(auto) get(const T& t) noexcept; /// If @c T has a nested type @c allocator_type, returns /// t.get_allocator(). Otherwise returns @c a. - static decltype(auto) get(const T& t, const Allocator& a) ASIO_NOEXCEPT; + static decltype(auto) get(const T& t, const Allocator& a) noexcept; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -142,7 +137,7 @@ struct associated_allocator */ template ASIO_NODISCARD inline typename associated_allocator::type -get_associated_allocator(const T& t) ASIO_NOEXCEPT +get_associated_allocator(const T& t) noexcept { return associated_allocator::get(t); } @@ -152,23 +147,17 @@ get_associated_allocator(const T& t) ASIO_NOEXCEPT * @returns associated_allocator::get(t, a) */ template -ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2( - typename associated_allocator::type) -get_associated_allocator(const T& t, const Allocator& a) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX(( - associated_allocator::get(t, a))) +ASIO_NODISCARD inline auto get_associated_allocator( + const T& t, const Allocator& a) noexcept + -> decltype(associated_allocator::get(t, a)) { return associated_allocator::get(t, a); } -#if defined(ASIO_HAS_ALIAS_TEMPLATES) - -template > +template > using associated_allocator_t = typename associated_allocator::type; -#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) - namespace detail { template @@ -178,22 +167,19 @@ struct associated_allocator_forwarding_base template struct associated_allocator_forwarding_base::asio_associated_allocator_is_unspecialised, void >::value - >::type> + >> { typedef void asio_associated_allocator_is_unspecialised; }; } // namespace detail -#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \ - || defined(GENERATING_DOCUMENTATION) - /// Specialisation of associated_allocator for @c std::reference_wrapper. template struct associated_allocator, Allocator> @@ -207,25 +193,20 @@ struct associated_allocator, Allocator> /// Forwards the request to get the allocator to the associator specialisation /// for the unwrapped type @c T. - static type get(reference_wrapper t) ASIO_NOEXCEPT + static type get(reference_wrapper t) noexcept { return associated_allocator::get(t.get()); } /// Forwards the request to get the allocator to the associator specialisation /// for the unwrapped type @c T. - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - reference_wrapper t, const Allocator& a) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX(( - associated_allocator::get(t.get(), a))) + static auto get(reference_wrapper t, const Allocator& a) noexcept + -> decltype(associated_allocator::get(t.get(), a)) { return associated_allocator::get(t.get(), a); } }; -#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER) - // || defined(GENERATING_DOCUMENTATION) - } // namespace asio #include "asio/detail/pop_options.hpp" diff --git a/thirdparty/asio/asio/associated_cancellation_slot.hpp b/thirdparty/asio/asio/associated_cancellation_slot.hpp index 65d82b646..79dccecd4 100644 --- a/thirdparty/asio/asio/associated_cancellation_slot.hpp +++ b/thirdparty/asio/asio/associated_cancellation_slot.hpp @@ -2,7 +2,7 @@ // associated_cancellation_slot.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -36,9 +36,8 @@ struct has_cancellation_slot_type : false_type }; template -struct has_cancellation_slot_type::type> - : true_type +struct has_cancellation_slot_type> + : true_type { }; @@ -49,12 +48,12 @@ struct associated_cancellation_slot_impl typedef S type; - static type get(const T&) ASIO_NOEXCEPT + static type get(const T&) noexcept { return type(); } - static const type& get(const T&, const S& s) ASIO_NOEXCEPT + static const type& get(const T&, const S& s) noexcept { return s; } @@ -62,20 +61,18 @@ struct associated_cancellation_slot_impl template struct associated_cancellation_slot_impl::type> + void_t> { typedef typename T::cancellation_slot_type type; - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - const T& t) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_cancellation_slot())) + static auto get(const T& t) noexcept + -> decltype(t.get_cancellation_slot()) { return t.get_cancellation_slot(); } - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - const T& t, const S&) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_cancellation_slot())) + static auto get(const T& t, const S&) noexcept + -> decltype(t.get_cancellation_slot()) { return t.get_cancellation_slot(); } @@ -83,12 +80,12 @@ struct associated_cancellation_slot_impl struct associated_cancellation_slot_impl::value - >::type, - typename void_type< + >, + void_t< typename associator::type - >::type> : associator + >> : associator { }; @@ -129,12 +126,12 @@ struct associated_cancellation_slot /// If @c T has a nested type @c cancellation_slot_type, returns /// t.get_cancellation_slot(). Otherwise returns @c type(). - static decltype(auto) get(const T& t) ASIO_NOEXCEPT; + static decltype(auto) get(const T& t) noexcept; /// If @c T has a nested type @c cancellation_slot_type, returns /// t.get_cancellation_slot(). Otherwise returns @c s. static decltype(auto) get(const T& t, - const CancellationSlot& s) ASIO_NOEXCEPT; + const CancellationSlot& s) noexcept; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -144,7 +141,7 @@ struct associated_cancellation_slot */ template ASIO_NODISCARD inline typename associated_cancellation_slot::type -get_associated_cancellation_slot(const T& t) ASIO_NOEXCEPT +get_associated_cancellation_slot(const T& t) noexcept { return associated_cancellation_slot::get(t); } @@ -155,24 +152,17 @@ get_associated_cancellation_slot(const T& t) ASIO_NOEXCEPT * CancellationSlot>::get(t, st) */ template -ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2( - typename associated_cancellation_slot::type) -get_associated_cancellation_slot(const T& t, - const CancellationSlot& st) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX(( - associated_cancellation_slot::get(t, st))) +ASIO_NODISCARD inline auto get_associated_cancellation_slot( + const T& t, const CancellationSlot& st) noexcept + -> decltype(associated_cancellation_slot::get(t, st)) { return associated_cancellation_slot::get(t, st); } -#if defined(ASIO_HAS_ALIAS_TEMPLATES) - template using associated_cancellation_slot_t = typename associated_cancellation_slot::type; -#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) - namespace detail { template @@ -182,22 +172,19 @@ struct associated_cancellation_slot_forwarding_base template struct associated_cancellation_slot_forwarding_base::asio_associated_cancellation_slot_is_unspecialised, void >::value - >::type> + >> { typedef void asio_associated_cancellation_slot_is_unspecialised; }; } // namespace detail -#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \ - || defined(GENERATING_DOCUMENTATION) - /// Specialisation of associated_cancellation_slot for @c /// std::reference_wrapper. template @@ -212,25 +199,21 @@ struct associated_cancellation_slot, CancellationSlot> /// Forwards the request to get the cancellation slot to the associator /// specialisation for the unwrapped type @c T. - static type get(reference_wrapper t) ASIO_NOEXCEPT + static type get(reference_wrapper t) noexcept { return associated_cancellation_slot::get(t.get()); } /// Forwards the request to get the cancellation slot to the associator /// specialisation for the unwrapped type @c T. - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get(reference_wrapper t, - const CancellationSlot& s) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX(( - associated_cancellation_slot::get(t.get(), s))) + static auto get(reference_wrapper t, const CancellationSlot& s) noexcept + -> decltype( + associated_cancellation_slot::get(t.get(), s)) { return associated_cancellation_slot::get(t.get(), s); } }; -#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER) - // || defined(GENERATING_DOCUMENTATION) - } // namespace asio #include "asio/detail/pop_options.hpp" diff --git a/thirdparty/asio/asio/associated_executor.hpp b/thirdparty/asio/asio/associated_executor.hpp index 92279891d..5e0746f6b 100644 --- a/thirdparty/asio/asio/associated_executor.hpp +++ b/thirdparty/asio/asio/associated_executor.hpp @@ -2,7 +2,7 @@ // associated_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -38,8 +38,7 @@ struct has_executor_type : false_type }; template -struct has_executor_type::type> +struct has_executor_type> : true_type { }; @@ -51,33 +50,30 @@ struct associated_executor_impl typedef E type; - static type get(const T&) ASIO_NOEXCEPT + static type get(const T&) noexcept { return type(); } - static const type& get(const T&, const E& e) ASIO_NOEXCEPT + static const type& get(const T&, const E& e) noexcept { return e; } }; template -struct associated_executor_impl::type> +struct associated_executor_impl> { typedef typename T::executor_type type; - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - const T& t) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor())) + static auto get(const T& t) noexcept + -> decltype(t.get_executor()) { return t.get_executor(); } - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - const T& t, const E&) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_executor())) + static auto get(const T& t, const E&) noexcept + -> decltype(t.get_executor()) { return t.get_executor(); } @@ -85,12 +81,12 @@ struct associated_executor_impl struct associated_executor_impl::value - >::type, - typename void_type< + >, + void_t< typename associator::type - >::type> : associator + >> : associator { }; @@ -130,11 +126,11 @@ struct associated_executor /// If @c T has a nested type @c executor_type, returns /// t.get_executor(). Otherwise returns @c type(). - static decltype(auto) get(const T& t) ASIO_NOEXCEPT; + static decltype(auto) get(const T& t) noexcept; /// If @c T has a nested type @c executor_type, returns /// t.get_executor(). Otherwise returns @c ex. - static decltype(auto) get(const T& t, const Executor& ex) ASIO_NOEXCEPT; + static decltype(auto) get(const T& t, const Executor& ex) noexcept; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -144,7 +140,7 @@ struct associated_executor */ template ASIO_NODISCARD inline typename associated_executor::type -get_associated_executor(const T& t) ASIO_NOEXCEPT +get_associated_executor(const T& t) noexcept { return associated_executor::get(t); } @@ -154,14 +150,12 @@ get_associated_executor(const T& t) ASIO_NOEXCEPT * @returns associated_executor::get(t, ex) */ template -ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2( - typename associated_executor::type) -get_associated_executor(const T& t, const Executor& ex, - typename constraint< +ASIO_NODISCARD inline auto get_associated_executor( + const T& t, const Executor& ex, + constraint_t< is_executor::value || execution::is_executor::value - >::type = 0) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX(( - associated_executor::get(t, ex))) + > = 0) noexcept + -> decltype(associated_executor::get(t, ex)) { return associated_executor::get(t, ex); } @@ -175,20 +169,16 @@ template ASIO_NODISCARD inline typename associated_executor::type get_associated_executor(const T& t, ExecutionContext& ctx, - typename constraint::value>::type = 0) ASIO_NOEXCEPT + constraint_t::value> = 0) noexcept { return associated_executor::get(t, ctx.get_executor()); } -#if defined(ASIO_HAS_ALIAS_TEMPLATES) - template using associated_executor_t = typename associated_executor::type; -#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) - namespace detail { template @@ -198,22 +188,19 @@ struct associated_executor_forwarding_base template struct associated_executor_forwarding_base::asio_associated_executor_is_unspecialised, void >::value - >::type> + >> { typedef void asio_associated_executor_is_unspecialised; }; } // namespace detail -#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \ - || defined(GENERATING_DOCUMENTATION) - /// Specialisation of associated_executor for @c std::reference_wrapper. template struct associated_executor, Executor> @@ -227,25 +214,20 @@ struct associated_executor, Executor> /// Forwards the request to get the executor to the associator specialisation /// for the unwrapped type @c T. - static type get(reference_wrapper t) ASIO_NOEXCEPT + static type get(reference_wrapper t) noexcept { return associated_executor::get(t.get()); } /// Forwards the request to get the executor to the associator specialisation /// for the unwrapped type @c T. - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - reference_wrapper t, const Executor& ex) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX(( - associated_executor::get(t.get(), ex))) + static auto get(reference_wrapper t, const Executor& ex) noexcept + -> decltype(associated_executor::get(t.get(), ex)) { return associated_executor::get(t.get(), ex); } }; -#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER) - // || defined(GENERATING_DOCUMENTATION) - } // namespace asio #include "asio/detail/pop_options.hpp" diff --git a/thirdparty/asio/asio/associated_immediate_executor.hpp b/thirdparty/asio/asio/associated_immediate_executor.hpp index 54bced17a..9b1e0c637 100644 --- a/thirdparty/asio/asio/associated_immediate_executor.hpp +++ b/thirdparty/asio/asio/associated_immediate_executor.hpp @@ -2,7 +2,7 @@ // associated_immediate_executor.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -41,7 +41,7 @@ struct has_immediate_executor_type : false_type template struct has_immediate_executor_type::type> + void_t> : true_type { }; @@ -49,9 +49,10 @@ struct has_immediate_executor_type struct default_immediate_executor { - typedef typename require_result::type type; + typedef decay_t> type; - static type get(const E& e) ASIO_NOEXCEPT + static auto get(const E& e) noexcept + -> decltype(asio::require(e, execution::blocking.never)) { return asio::require(e, execution::blocking.never); } @@ -59,59 +60,57 @@ struct default_immediate_executor template struct default_immediate_executor::value - >::type, - typename enable_if< + >, + enable_if_t< is_executor::value - >::type> + >> { class type : public E { public: template explicit type(const Executor1& e, - typename constraint< - conditional< + constraint_t< + conditional_t< !is_same::value, is_convertible, false_type - >::type::value - >::type = 0) ASIO_NOEXCEPT + >::value + > = 0) noexcept : E(e) { } - type(const type& other) ASIO_NOEXCEPT + type(const type& other) noexcept : E(static_cast(other)) { } -#if defined(ASIO_HAS_MOVE) - type(type&& other) ASIO_NOEXCEPT - : E(ASIO_MOVE_CAST(E)(other)) + type(type&& other) noexcept + : E(static_cast(other)) { } -#endif // defined(ASIO_HAS_MOVE) template - void dispatch(ASIO_MOVE_ARG(Function) f, const Allocator& a) const + void dispatch(Function&& f, const Allocator& a) const { - this->post(ASIO_MOVE_CAST(Function)(f), a); + this->post(static_cast(f), a); } - friend bool operator==(const type& a, const type& b) ASIO_NOEXCEPT + friend bool operator==(const type& a, const type& b) noexcept { return static_cast(a) == static_cast(b); } - friend bool operator!=(const type& a, const type& b) ASIO_NOEXCEPT + friend bool operator!=(const type& a, const type& b) noexcept { return static_cast(a) != static_cast(b); } }; - static type get(const E& e) ASIO_NOEXCEPT + static type get(const E& e) noexcept { return type(e); } @@ -124,9 +123,8 @@ struct associated_immediate_executor_impl typedef typename default_immediate_executor::type type; - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - const T&, const E& e) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX((default_immediate_executor::get(e))) + static auto get(const T&, const E& e) noexcept + -> decltype(default_immediate_executor::get(e)) { return default_immediate_executor::get(e); } @@ -134,13 +132,12 @@ struct associated_immediate_executor_impl template struct associated_immediate_executor_impl::type> + void_t> { typedef typename T::immediate_executor_type type; - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - const T& t, const E&) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX((t.get_immediate_executor())) + static auto get(const T& t, const E&) noexcept + -> decltype(t.get_immediate_executor()) { return t.get_immediate_executor(); } @@ -148,12 +145,12 @@ struct associated_immediate_executor_impl struct associated_immediate_executor_impl::value - >::type, - typename void_type< + >, + void_t< typename associator::type - >::type> : associator + >> : associator { }; @@ -194,7 +191,7 @@ struct associated_immediate_executor /// If @c T has a nested type @c immediate_executor_type, returns /// t.get_immediate_executor(). Otherwise returns /// asio::require(ex, asio::execution::blocking.never). - static decltype(auto) get(const T& t, const Executor& ex) ASIO_NOEXCEPT; + static decltype(auto) get(const T& t, const Executor& ex) noexcept; #endif // defined(GENERATING_DOCUMENTATION) }; @@ -203,14 +200,12 @@ struct associated_immediate_executor * @returns associated_immediate_executor::get(t, ex) */ template -ASIO_NODISCARD inline ASIO_AUTO_RETURN_TYPE_PREFIX2( - typename associated_immediate_executor::type) -get_associated_immediate_executor(const T& t, const Executor& ex, - typename constraint< +ASIO_NODISCARD inline auto get_associated_immediate_executor( + const T& t, const Executor& ex, + constraint_t< is_executor::value || execution::is_executor::value - >::type = 0) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX(( - associated_immediate_executor::get(t, ex))) + > = 0) noexcept + -> decltype(associated_immediate_executor::get(t, ex)) { return associated_immediate_executor::get(t, ex); } @@ -224,21 +219,18 @@ template ASIO_NODISCARD inline typename associated_immediate_executor::type get_associated_immediate_executor(const T& t, ExecutionContext& ctx, - typename constraint::value>::type = 0) ASIO_NOEXCEPT + constraint_t< + is_convertible::value + > = 0) noexcept { return associated_immediate_executor::get(t, ctx.get_executor()); } -#if defined(ASIO_HAS_ALIAS_TEMPLATES) - template using associated_immediate_executor_t = typename associated_immediate_executor::type; -#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) - namespace detail { template @@ -248,22 +240,19 @@ struct associated_immediate_executor_forwarding_base template struct associated_immediate_executor_forwarding_base::asio_associated_immediate_executor_is_unspecialised, void >::value - >::type> + >> { typedef void asio_associated_immediate_executor_is_unspecialised; }; } // namespace detail -#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \ - || defined(GENERATING_DOCUMENTATION) - /// Specialisation of associated_immediate_executor for /// @c std::reference_wrapper. template @@ -278,18 +267,13 @@ struct associated_immediate_executor, Executor> /// Forwards the request to get the executor to the associator specialisation /// for the unwrapped type @c T. - static ASIO_AUTO_RETURN_TYPE_PREFIX(type) get( - reference_wrapper t, const Executor& ex) ASIO_NOEXCEPT - ASIO_AUTO_RETURN_TYPE_SUFFIX(( - associated_immediate_executor::get(t.get(), ex))) + static auto get(reference_wrapper t, const Executor& ex) noexcept + -> decltype(associated_immediate_executor::get(t.get(), ex)) { return associated_immediate_executor::get(t.get(), ex); } }; -#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER) - // || defined(GENERATING_DOCUMENTATION) - } // namespace asio #include "asio/detail/pop_options.hpp" diff --git a/thirdparty/asio/asio/associator.hpp b/thirdparty/asio/asio/associator.hpp index e954c4428..5c4f382c1 100644 --- a/thirdparty/asio/asio/associator.hpp +++ b/thirdparty/asio/asio/associator.hpp @@ -2,7 +2,7 @@ // associator.hpp // ~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2025 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -23,7 +23,7 @@ namespace asio { /// Used to generically specialise associators for a type. template