diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b440f4581..0ba34dd65 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,13 +28,17 @@ jobs: python3 -m pip install mako - name: Generate build files with cmake run: | - cmake -DCMAKE_BUILD_TYPE=Debug -G "Visual Studio 17 2022" -A x64 -Bbuild . + cmake -DCMAKE_BUILD_TYPE=Debug -G "Visual Studio 17 2022" -A x64 -Bbuild/host . - name: Build Dive host tools with VS 2022 run: | - cmake --build build --config Debug + cmake --build build/host --config Debug - name: Run tests run: | - ctest --output-on-failure -C Debug --test-dir build + ctest --output-on-failure -C Debug --test-dir build/host + - name: Install under build dir + run: | + cmake --install build/host --prefix build/pkg/host --config Debug + build_Windows_Release: name: "Windows release build" runs-on: windows-2022 @@ -55,14 +59,16 @@ jobs: python3 -m pip install mako - name: Generate build files with cmake run: | - cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 17 2022" -A x64 -Bbuild . + cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 17 2022" -A x64 -Bbuild/host . - name: Build Dive host tools with VS 2022 run: | - cmake --build build --config Release + cmake --build build/host --config Release - name: Run tests run: | - ctest --output-on-failure -C Release --test-dir build - + ctest --output-on-failure -C Release --test-dir build/host + - name: Install under build dir + run: | + cmake --install build/host --prefix build/pkg/host --config Release build_Linux_Gcc_Debug: name: "Linux gcc debug build" @@ -96,26 +102,27 @@ jobs: - name: Generate build files with cmake run: | cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc-14 \ -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++-14 \ - -GNinja \ - -Bbuild . + -G "Ninja Multi-Config" \ + -Bbuild/host . - name: Build Dive host tools with ninja with gcc-14 run: | - ninja -C build + cmake --build build/host --config Debug - name: Ninja log run: | - cat build/.ninja_log + cat build/host/.ninja_log - name: Start Xvfb run: | Xvfb :99 -screen 0 1024x768x24 & export DISPLAY=:99 - - name: Run tests run: | export DISPLAY=:99 - ctest --output-on-failure -C Debug --test-dir build + ctest --output-on-failure -C Debug --test-dir build/host + - name: Install under build dir + run: | + cmake --install build/host --prefix build/pkg/host --config Debug build_Linux_Gcc_Release: name: "Linux gcc release build" @@ -148,26 +155,27 @@ jobs: - name: Generate build files with cmake run: | cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc-14 \ -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++-14 \ - -GNinja \ - -Bbuild . + -G"Ninja Multi-Config" \ + -Bbuild/host . - name: Build Dive host tools with ninja with gcc-14 run: | - ninja -C build + cmake --build build/host --config Release - name: Ninja log run: | - cat build/.ninja_log + cat build/host/.ninja_log - name: Start Xvfb run: | Xvfb :99 -screen 0 1024x768x24 & export DISPLAY=:99 - - name: Run tests run: | export DISPLAY=:99 - ctest --output-on-failure -C Release --test-dir build + ctest --output-on-failure -C Release --test-dir build/host + - name: Install under build dir + run: | + cmake --install build/host --prefix build/pkg/host --config Release build_Linux_Clang_Debug: name: "Linux clang debug build" @@ -200,26 +208,27 @@ jobs: - name: Generate build files with cmake run: | cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-19 \ -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-19 \ - -GNinja \ - -Bbuild . + -G"Ninja Multi-Config" \ + -Bbuild/host . - name: Build Dive host tools with ninja with clang-19 run: | - ninja -C build + cmake --build build/host --config Debug - name: Ninja log run: | - cat build/.ninja_log + cat build/host/.ninja_log - name: Start Xvfb run: | Xvfb :99 -screen 0 1024x768x24 & export DISPLAY=:99 - - name: Run tests run: | export DISPLAY=:99 - ctest --output-on-failure -C Debug --test-dir build + ctest --output-on-failure -C Debug --test-dir build/host + - name: Install under build dir + run: | + cmake --install build/host --prefix build/pkg/host --config Debug build_Linux_Clang_Release: name: "Linux clang release build" @@ -252,26 +261,27 @@ jobs: - name: Generate build files with cmake run: | cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-19 \ -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-19 \ - -GNinja \ - -Bbuild . + -G"Ninja Multi-Config" \ + -Bbuild/host . - name: Build Dive host tools with ninja with clang-19 run: | - ninja -C build + cmake --build build/host --config Release - name: Ninja log run: | - cat build/.ninja_log + cat build/host/.ninja_log - name: Start Xvfb run: | Xvfb :99 -screen 0 1024x768x24 & export DISPLAY=:99 - - name: Run tests run: | export DISPLAY=:99 - ctest --output-on-failure -C Release --test-dir build + ctest --output-on-failure -C Release --test-dir build/host + - name: Install under build dir + run: | + cmake --install build/host --prefix build/pkg/host --config Release build_MacOS_Debug: name: "MacOS debug build" @@ -300,24 +310,27 @@ jobs: run: ccache -z - name: Generate build files with cmake run: | - time cmake -DCMAKE_BUILD_TYPE=Debug \ + time cmake \ -DCMAKE_C_COMPILER_LAUNCHER="cmake;-E;time;ccache" \ -DCMAKE_CXX_COMPILER_LAUNCHER="cmake;-E;time;ccache" \ -DCMAKE_C_LINKER_LAUNCHER="cmake;-E;time" \ -DCMAKE_CXX_LINKER_LAUNCHER="cmake;-E;time" \ - -GNinja \ - -Bbuild . + -G"Ninja Multi-Config" \ + -Bbuild/host . - name: Build Dive host tools with ninja run: | - time ninja -C build -d stats + time cmake --build build/host --config Debug - name: Show ccache stats run: ccache -s - name: Ninja log run: | - cat build/.ninja_log + cat build/host/.ninja_log - name: Run tests run: | - ctest --output-on-failure -C Debug --test-dir build + ctest --output-on-failure -C Debug --test-dir build/host + - name: Install under build dir + run: | + cmake --install build/host --prefix build/pkg/host --config Debug - name: Upload cache uses: actions/cache/save@v4 with: @@ -351,24 +364,27 @@ jobs: run: ccache -z - name: Generate build files with cmake run: | - time cmake -DCMAKE_BUILD_TYPE=Release \ + time cmake \ -DCMAKE_C_COMPILER_LAUNCHER="cmake;-E;time;ccache" \ -DCMAKE_CXX_COMPILER_LAUNCHER="cmake;-E;time;ccache" \ -DCMAKE_C_LINKER_LAUNCHER="cmake;-E;time" \ -DCMAKE_CXX_LINKER_LAUNCHER="cmake;-E;time" \ - -GNinja \ - -Bbuild . + -G"Ninja Multi-Config" \ + -Bbuild/host . - name: Build Dive host tools with ninja run: | - time ninja -C build -d stats + time cmake --build build/host --config Release - name: Show ccache stats run: ccache -s - name: Ninja log run: | - cat build/.ninja_log + cat build/host/.ninja_log - name: Run tests run: | - ctest --output-on-failure -C Release --test-dir build + ctest --output-on-failure -C Release --test-dir build/host + - name: Install under build dir + run: | + cmake --install build/host --prefix build/pkg/host --config Release - name: Upload cache uses: actions/cache/save@v4 with: @@ -400,14 +416,67 @@ jobs: with: ndk-version: r25 add-to-path: true + - name: Generate build files with cmake + run: | + # DIVE_GFXR_GRADLE_CONSOLE=plain produces more readable output in CI + cmake -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \ + -G "Ninja Multi-Config" \ + -DCMAKE_MAKE_PROGRAM="ninja" \ + -DCMAKE_SYSTEM_NAME=Android \ + -DANDROID_ABI=arm64-v8a \ + -DANDROID_PLATFORM=android-26 \ + -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \ + -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER \ + -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ + -DDIVE_GFXR_GRADLE_CONSOLE=plain \ + -Bbuild/device . + env: + ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} + JAVA_HOME: ${{ steps.setup-java.outputs.java-home }} + - name: Build lib with NDK + run: | + cmake --build build/device --config Debug + env: + ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} + JAVA_HOME: ${{ steps.setup-java.outputs.java-home }} + - name: Install under build dir + run: | + cmake --install build/device --prefix build/pkg/device --config Debug + - name: Ninja log + run: | + cat build/device/.ninja_log - - name: Gemerate build files with cmake + build_Android_from_Linux_Release: + name: "Android Release build on Linux platform" + runs-on: ubuntu-24.04 + steps: + - name: Set up Java 17 + uses: actions/setup-java@v3 + id: setup-java + with: + java-version: '17' + distribution: 'temurin' + - name: Check out code + uses: actions/checkout@v3 + with: + submodules: recursive + - name: Install dependency + run: | + sudo apt-get update --yes + sudo apt-get install --yes cmake ninja-build + sudo apt-get install python3-mako --yes + sudo apt-get install libxcb-glx0-dev + - uses: nttld/setup-ndk@v1 + id: setup-ndk + with: + ndk-version: r25 + add-to-path: true + - name: Generate build files with cmake run: | # DIVE_GFXR_GRADLE_CONSOLE=plain produces more readable output in CI cmake -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \ - -G "Ninja" \ + -G "Ninja Multi-Config" \ -DCMAKE_MAKE_PROGRAM="ninja" \ - -DCMAKE_BUILD_TYPE=Debug \ -DCMAKE_SYSTEM_NAME=Android \ -DANDROID_ABI=arm64-v8a \ -DANDROID_PLATFORM=android-26 \ @@ -415,16 +484,19 @@ jobs: -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER \ -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ -DDIVE_GFXR_GRADLE_CONSOLE=plain \ - -Bbuild . + -Bbuild/device . env: ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} JAVA_HOME: ${{ steps.setup-java.outputs.java-home }} - name: Build lib with NDK run: | - ninja -C build + cmake --build build/device --config Release env: ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} JAVA_HOME: ${{ steps.setup-java.outputs.java-home }} + - name: Install under build dir + run: | + cmake --install build/device --prefix build/pkg/device --config Release - name: Ninja log run: | - cat build/.ninja_log + cat build/device/.ninja_log diff --git a/.github/workflows/presubmit.yml b/.github/workflows/presubmit.yml index cae9fb215..b4ea8bf6a 100644 --- a/.github/workflows/presubmit.yml +++ b/.github/workflows/presubmit.yml @@ -13,9 +13,12 @@ concurrency: cancel-in-progress: true jobs: - build_Windows_Debug: - name: "Windows debug build" + build_Windows: + name: "Windows ${{ matrix.build_type }} build" runs-on: windows-2022 + strategy: + matrix: + build_type: [Debug, Release] steps: - name: Check out code uses: actions/checkout@v3 @@ -28,55 +31,39 @@ jobs: target: desktop arch: win64_msvc2019_64 - uses: ilammy/setup-nasm@v1 - - name: Install dependency + - name: Install Dive dependencies run: | python3 -m pip install mako - name: Generate build files with cmake run: | - cmake -DCMAKE_BUILD_TYPE=Debug -G "Visual Studio 17 2022" -A x64 -Bbuild . + cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -G "Visual Studio 17 2022" -A x64 -Bbuild/host . - name: Build Dive host tools with VS 2022 run: | - cmake --build build --config Debug + cmake --build build/host --config ${{ matrix.build_type }} - name: Run tests run: | - ctest --output-on-failure -C Debug --test-dir build - build_Windows_Release: - name: "Windows release build" - runs-on: windows-2022 - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install Qt - uses: jurplel/install-qt-action@v3 - with: - version: 5.15.2 - target: desktop - arch: win64_msvc2019_64 - - uses: ilammy/setup-nasm@v1 - - name: Install dependency - run: | - python3 -m pip install mako - - name: Generate build files with cmake + ctest --output-on-failure -C ${{ matrix.build_type }} --test-dir build/host + - name: Install under build dir run: | - cmake -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 17 2022" -A x64 -Bbuild . - - name: Build Dive host tools with VS 2022 - run: | - cmake --build build --config Release - - name: Run tests - run: | - ctest --output-on-failure -C Release --test-dir build + cmake --install build/host --prefix build/pkg/host --config ${{ matrix.build_type }} - name: Upload test output uses: actions/upload-artifact@v4 with: name: test_output_windows - path: build/test_output + path: build/host/test_output - - build_Linux_Gcc_Debug: - name: "Linux gcc debug build" + build_Linux: + name: "Windows ${{ matrix.build_type }} ${{ matrix.compiler }} build" runs-on: ubuntu-24.04 + strategy: + matrix: + build_type: [Debug, Release] + compiler: [gcc-14, clang-19] + include: + - cxx_compiler: g++-14 + compiler: gcc-14 + - cxx_compiler: clang++-19 + compiler: clang-19 steps: - name: Check out code uses: actions/checkout@v3 @@ -85,370 +72,54 @@ jobs: - name: Install Qt dependencies (including xcb) run: | sudo apt-get update - sudo apt-get install -y libxcb-xinerama0 libxcb-xinerama0-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxkbcommon-x11-0 libxcb1 libx11-xcb1 + sudo apt-get install -y \ + libxcb-xinerama0 \ + libxcb-xinerama0-dev \ + libxcb-icccm4 \ + libxcb-image0 \ + libxcb-keysyms1 \ + libxcb-render-util0 \ + libxkbcommon-x11-0 \ + libxcb1 \ + libx11-xcb1 - name: Install Qt uses: jurplel/install-qt-action@v3 with: # Minimize the number of Python installations so that CMake chooses the system Python with python3-mako. setup-python: false - - name: Install dependency + - name: Install Dive dependencies run: | sudo apt-get update --yes sudo apt-get install --yes \ cmake \ - gcc-14 \ - libsystemd-dev \ - libbsd-dev \ - ninja-build \ - python3-mako \ - libxcb-glx0-dev - which gcc-14 - - name: Generate build files with cmake - run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc-14 \ - -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++-14 \ - -GNinja \ - -Bbuild . - - name: Build Dive host tools with ninja with gcc-14 - run: | - ninja -C build - - name: Ninja log - run: | - cat build/.ninja_log - - name: Start Xvfb - run: | - Xvfb :99 -screen 0 1024x768x24 & - export DISPLAY=:99 - - - name: Run tests - run: | - export DISPLAY=:99 - ctest --output-on-failure -C Debug --test-dir build - - build_Linux_Gcc_Release: - name: "Linux gcc release build" - runs-on: ubuntu-24.04 - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install Qt dependencies (including xcb) - run: | - sudo apt-get update - sudo apt-get install -y libxcb-xinerama0 libxcb-xinerama0-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxkbcommon-x11-0 libxcb1 libx11-xcb1 - - name: Install Qt - uses: jurplel/install-qt-action@v3 - with: - # Minimize the number of Python installations so that CMake chooses the system Python with python3-mako. - setup-python: false - - name: Install dependency - run: | - sudo apt-get update --yes - sudo apt-get install --yes \ - cmake gcc-14 \ + ${{ matrix.compiler }} \ libsystemd-dev \ libbsd-dev \ ninja-build \ python3-mako \ libxcb-glx0-dev - which gcc-14 - - name: Generate build files with cmake - run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/gcc-14 \ - -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/g++-14 \ - -GNinja \ - -Bbuild . - - name: Build Dive host tools with ninja with gcc-14 - run: | - ninja -C build - - name: Ninja log - run: | - cat build/.ninja_log - - name: Start Xvfb - run: | - Xvfb :99 -screen 0 1024x768x24 & - export DISPLAY=:99 - - - name: Run tests - run: | - export DISPLAY=:99 - ctest --output-on-failure -C Release --test-dir build - - build_Linux_Clang_Debug: - name: "Linux clang debug build" - runs-on: ubuntu-24.04 - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install Qt dependencies (including xcb) - run: | - sudo apt-get update - sudo apt-get install -y libxcb-xinerama0 libxcb-xinerama0-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxkbcommon-x11-0 libxcb1 libx11-xcb1 - - name: Install Qt - uses: jurplel/install-qt-action@v3 - with: - # Minimize the number of Python installations so that CMake chooses the system Python with python3-mako. - setup-python: false - - name: Install dependency - run: | - sudo apt-get update --yes - sudo apt-get install --yes \ - cmake clang-19 \ - libsystemd-dev \ - libbsd-dev \ - ninja-build \ - python3-mako \ - libxcb-glx0-dev - which clang-19 - - name: Generate build files with cmake - run: | - cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-19 \ - -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-19 \ - -GNinja \ - -Bbuild . - - name: Build Dive host tools with ninja with clang-19 - run: | - ninja -C build - - name: Ninja log - run: | - cat build/.ninja_log - - name: Start Xvfb - run: | - Xvfb :99 -screen 0 1024x768x24 & - export DISPLAY=:99 - - - name: Run tests - run: | - export DISPLAY=:99 - ctest --output-on-failure -C Debug --test-dir build - - build_Linux_Clang_Release: - name: "Linux clang release build" - runs-on: ubuntu-24.04 - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install Qt dependencies (including xcb) - run: | - sudo apt-get update - sudo apt-get install -y libxcb-xinerama0 libxcb-xinerama0-dev libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-render-util0 libxkbcommon-x11-0 libxcb1 libx11-xcb1 - - name: Install Qt - uses: jurplel/install-qt-action@v3 - with: - # Minimize the number of Python installations so that CMake chooses the system Python with python3-mako. - setup-python: false - - name: Install dependency - run: | - sudo apt-get update --yes - sudo apt-get install --yes \ - cmake clang-19 \ - libsystemd-dev \ - libbsd-dev \ - ninja-build \ - python3-mako \ - libxcb-glx0-dev - which clang-19 + which ${{ matrix.compiler }} - name: Generate build files with cmake run: | cmake -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-19 \ - -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-19 \ - -GNinja \ - -Bbuild . - - name: Build Dive host tools with ninja with clang-19 + -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/${{ matrix.compiler }} \ + -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/${{ matrix.cxx_compiler }} \ + -G "Ninja Multi-Config" \ + -Bbuild/host . + - name: Build Dive host tools with ninja with ${{ matrix.compiler }} run: | - ninja -C build + cmake --build build/host --config ${{ matrix.build_type }} - name: Ninja log run: | - cat build/.ninja_log + cat build/host/.ninja_log - name: Start Xvfb run: | Xvfb :99 -screen 0 1024x768x24 & export DISPLAY=:99 - - name: Run tests run: | export DISPLAY=:99 - ctest --output-on-failure -C Release --test-dir build - - name: Upload test output - uses: actions/upload-artifact@v4 - with: - name: test_output_linux - path: build/test_output - - build_MacOS_Debug: - name: "MacOS debug build" - runs-on: macos-latest - env: - CCACHE_DIR: ${{ github.workspace }}/.ccache - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install Qt 5.15 via Homebrew - run: | - brew install qt@5 - # Link it so standard commands might find it, or just set env vars below - echo "Qt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5" >> $GITHUB_ENV - echo "PATH=$(brew --prefix qt@5)/bin:$PATH" >> $GITHUB_ENV - - name: Check Qt Version - run: qmake --version - - name: Install ccache - run: brew install ccache - - name: Cache ccache - uses: actions/cache@v4 - with: - path: ${{ env.CCACHE_DIR }} - key: ${{ runner.os }}-Debug-ccache-presubmit-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-Debug-ccache- - - name: Install dependency - run: | - python3 -m pip install --break-system-packages mako - - name: Zero ccache stats - run: ccache -z - - name: Generate build files with cmake - run: | - time cmake -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_C_COMPILER_LAUNCHER="cmake;-E;time;ccache" \ - -DCMAKE_CXX_COMPILER_LAUNCHER="cmake;-E;time;ccache" \ - -DCMAKE_C_LINKER_LAUNCHER="cmake;-E;time" \ - -DCMAKE_CXX_LINKER_LAUNCHER="cmake;-E;time" \ - -GNinja \ - -Bbuild . - - name: Build Dive host tools with ninja - run: | - time ninja -C build -d stats - - name: Show ccache stats - run: ccache -s - - name: Ninja log - run: | - cat build/.ninja_log - - name: Run tests - run: | - ctest --output-on-failure -C Debug --test-dir build - - build_MacOS_Release: - name: "MacOS release build" - runs-on: macos-latest - env: - CCACHE_DIR: ${{ github.workspace }}/.ccache - steps: - - name: Check out code - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install Qt 5.15 via Homebrew - run: | - brew install qt@5 - # Link it so standard commands might find it, or just set env vars below - echo "Qt5_DIR=$(brew --prefix qt@5)/lib/cmake/Qt5" >> $GITHUB_ENV - echo "PATH=$(brew --prefix qt@5)/bin:$PATH" >> $GITHUB_ENV - - name: Check Qt Version - run: qmake --version - - name: Install ccache - run: brew install ccache - - name: Cache ccache - uses: actions/cache@v4 - with: - path: ${{ env.CCACHE_DIR }} - key: ${{ runner.os }}-Release-ccache-presubmit-${{ github.sha }} - restore-keys: | - ${{ runner.os }}-Release-ccache- - - name: Install dependency - run: | - python3 -m pip install --break-system-packages mako - - name: Zero ccache stats - run: ccache -z - - name: Generate build files with cmake - run: | - time cmake -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_C_COMPILER_LAUNCHER="cmake;-E;time;ccache" \ - -DCMAKE_CXX_COMPILER_LAUNCHER="cmake;-E;time;ccache" \ - -DCMAKE_C_LINKER_LAUNCHER="cmake;-E;time" \ - -DCMAKE_CXX_LINKER_LAUNCHER="cmake;-E;time" \ - -GNinja \ - -Bbuild . - - name: Build Dive host tools with ninja - run: | - time ninja -C build -d stats - - name: Show ccache stats - run: ccache -s - - name: Ninja log - run: | - cat build/.ninja_log - - name: Run tests - run: | - ctest --output-on-failure -C Release --test-dir build - - name: Upload test output - uses: actions/upload-artifact@v4 - with: - name: test_output_macos - path: build/test_output - - build_Android_from_Linux_Debug: - name: "Android Debug build on Linux platform" - runs-on: ubuntu-24.04 - steps: - - name: Set up Java 17 - uses: actions/setup-java@v3 - id: setup-java - with: - java-version: '17' - distribution: 'temurin' - - name: Check out code - uses: actions/checkout@v3 - with: - submodules: recursive - - name: Install dependency - run: | - sudo apt-get update --yes - sudo apt-get install --yes cmake ninja-build - sudo apt-get install python3-mako --yes - sudo apt-get install libxcb-glx0-dev - - uses: nttld/setup-ndk@v1 - id: setup-ndk - with: - ndk-version: r25 - add-to-path: true - - - name: Gemerate build files with cmake - run: | - # DIVE_GFXR_GRADLE_CONSOLE=plain produces more readable output in CI - cmake -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \ - -G "Ninja" \ - -DCMAKE_MAKE_PROGRAM="ninja" \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_SYSTEM_NAME=Android \ - -DANDROID_ABI=arm64-v8a \ - -DANDROID_PLATFORM=android-26 \ - -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \ - -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER \ - -DCMAKE_POLICY_VERSION_MINIMUM=3.5 \ - -DDIVE_GFXR_GRADLE_CONSOLE=plain \ - -Bbuild . - env: - ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} - JAVA_HOME: ${{ steps.setup-java.outputs.java-home }} - - name: Build lib with NDK - run: | - ninja -C build - env: - ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }} - JAVA_HOME: ${{ steps.setup-java.outputs.java-home }} - - name: Ninja log + ctest --output-on-failure -C ${{ matrix.build_type }} --test-dir build/host + - name: Install under build dir run: | - cat build/.ninja_log + cmake --install build/host --prefix build/pkg/host --config ${{ matrix.build_type }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index b6ba41e60..15aee74da 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,6 @@ # Build-related directories build/ -build_android/ third_party/freedreno/libs/ third_party/freedreno/obj .gradle/ @@ -24,7 +23,6 @@ g_*.cpp .env -install/ gfxr_capture/ gfxr_capture_*/ **/.DS_Store diff --git a/BUILD.md b/BUILD.md index 6508a1101..8d7c730c5 100644 --- a/BUILD.md +++ b/BUILD.md @@ -62,103 +62,113 @@ set DIVE_ROOT_PATH=C:\path\to\dive ### Linux -```sh -# Assumes python is on the path - -cd $DIVE_ROOT_PATH -rm -rf build - -cmake . -GNinja -DCMAKE_BUILD_TYPE=Debug -Bbuild - -ninja -C build +1. Configure + ```sh + # Assumes python is on the path -cmake --install build -``` + cd $DIVE_ROOT_PATH + rm -rf build/host + rm -rf build/pkg/host -You can specify the build type for release as well -with `-DCMAKE_BUILD_TYPE=Release` instead. + cmake . -G "Ninja Multi-Config" -Bbuild/host + ``` +1. Build + ```sh + cmake --build build/host --config=Debug + ``` + You can specify the build type for release as well + with `--config=Release` instead. +1. Install in a predetermined location so that the host tools can locate the device libraries + ```sh + cmake --install build/host --prefix build/pkg/host --config Debug + ``` ### Windows -```bat -REM Assumes python is on the path +1. Configure + ```bat + REM Assumes python is on the path -cd %DIVE_ROOT_PATH% -rmdir /s build + cd %DIVE_ROOT_PATH% + rmdir /s build\host + rmdir /s build\pkg\host -cmake . -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE=Debug -Bbuild -``` - -You can specify other build types as well with `-DCMAKE_BUILD_TYPE=`. If you are opening the VS IDE to build, make sure the selected build type in the dropdown matches the type specified earlier, to ensure proper version info is reflected by the built host tools. - -TODO(b/460765024): Support multi-configuration generator (VS) for Windows build and disallow `-DCMAKE_BUILD_TYPE=` flag - -Open `dive.sln` in Visual Studio and build. - -Or run: -```bat -cmake --build build -``` - -TODO(b/462767957): Fix Windows build host tools install + cmake . -G "Visual Studio 17 2022" -Bbuild\host + ``` +1. Build with Visual Studio by opening `dive.sln` using IDE and selecting the appropriate build type, or build using cmake: + ```sh + cmake --build build\host --config=Debug + ``` + You can specify other build types as well + with `--config=` instead. +1. Install in a predetermined location so that the host tools can locate the device libraries + ```sh + cmake --install build\host --prefix build\pkg\host --config Debug + ``` ## Dive Device Libraries -### Linux - -Warning: Release build is not supported +Warning: We only support "Debug" for the gradle build for GFXR portion, so it will be hardcoded and not depend on the `--config` below. Provide the appropriate `ANDROID_ABI` depending on your device. -```sh -cd $DIVE_ROOT_PATH - -rm -rf build_android - -cmake . -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \ - -G "Ninja" \ - -Bbuild_android \ - -DCMAKE_MAKE_PROGRAM="ninja" \ - -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_SYSTEM_NAME=Android \ - -DANDROID_ABI=arm64-v8a \ - -DANDROID_PLATFORM=android-26 \ - -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \ - -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER - -cmake --build build_android --config=Debug +### Linux -cmake --install build_android -``` +1. Configure + ```sh + cd $DIVE_ROOT_PATH + + rm -rf build/device + rm -rf build/pkg/device + + cmake . -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \ + -G "Ninja Multi-Config" \ + -Bbuild/device \ + -DCMAKE_MAKE_PROGRAM="ninja" \ + -DCMAKE_SYSTEM_NAME=Android \ + -DANDROID_ABI=arm64-v8a \ + -DANDROID_PLATFORM=android-26 \ + -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \ + -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER + ``` +1. Build + ```sh + cmake --build build/device --config=Debug + ``` +1. Install in a predetermined location so that the host tools can locate the device libraries + ```sh + cmake --install build/device --prefix build/pkg/device --config Debug + ``` ### Windows -Warning: Release build is not supported - -Provide the appropriate `ANDROID_ABI` depending on your device. - -Note: On Windows, run the following in the Visual Studio Developer Command Prompt for VS 2022 (or 2019) - -```bat -cd %DIVE_ROOT_PATH% - -rmdir /s build_android +Run the following in the Visual Studio Developer Command Prompt for VS 2022 (or 2019) -cmake . -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK_HOME%/build/cmake/android.toolchain.cmake ^ - -G "Ninja" ^ - -Bbuild_android ^ - -DCMAKE_MAKE_PROGRAM="ninja" ^ - -DCMAKE_BUILD_TYPE=Debug ^ - -DCMAKE_SYSTEM_NAME=Android ^ - -DANDROID_ABI=arm64-v8a ^ - -DANDROID_PLATFORM=android-26 ^ - -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER ^ - -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER +1. Configure + ```bat + cd %DIVE_ROOT_PATH% -cmake --build build_android --config=Debug + rmdir /s build\device + rmdir /s build\pkg\device -cmake --install build_android -``` + cmake . -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK_HOME%/build/cmake/android.toolchain.cmake ^ + -G "Ninja Multi-Config" ^ + -Bbuild\device ^ + -DCMAKE_MAKE_PROGRAM="ninja" ^ + -DCMAKE_SYSTEM_NAME=Android ^ + -DANDROID_ABI=arm64-v8a ^ + -DANDROID_PLATFORM=android-26 ^ + -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER ^ + -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER + ``` +1. Build + ```bat + cmake --build build\device --config=Debug + ``` +1. Install + ```bat + cmake --install build\device --prefix build\pkg\device --config Debug + ``` ### Troubleshooting Tips diff --git a/CMakeLists.txt b/CMakeLists.txt index ec5a774e2..8413869e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,6 @@ if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") endif() set(THIRDPARTY_DIRECTORY "${CMAKE_SOURCE_DIR}/third_party") -set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/install") # Add an option to allow users to easily toggle the runtime layer build option( @@ -40,6 +39,15 @@ option( option(DIVE_BUILD_WITH_SANITIZER "Build Dive with sanitizers" OFF) +set(DIVE_INSTALL_DESTINATION + "." # Replace this with "dive-profiler" + CACHE STRING + "Dive install location" +) + +# Disable gtest for install +set(INSTALL_GTEST OFF) + # Ignore Qt5.15 deprecations. # TODO(b/463357129): evaluate if this add_definitions() follows cmake best practices add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050eff) @@ -81,21 +89,15 @@ if(ANDROID) message(CHECK_START "Make version file for Dive device libraries") list(APPEND CMAKE_MESSAGE_INDENT " ") file( - WRITE ${CMAKE_BINARY_DIR}/${DEVICE_LIBRARIES_VERSION_FILENAME} - "sha," - ${DIVE_VERSION_SHA1} - "\nversion," - ${CMAKE_PROJECT_VERSION} - "\nbuild_type," - ${CMAKE_BUILD_TYPE} - "\nrelease_type," - ${DIVE_RELEASE_TYPE} - "\nabi," - ${ANDROID_ABI} + GENERATE OUTPUT + "${CMAKE_CURRENT_BINARY_DIR}/$/${DEVICE_LIBRARIES_VERSION_FILENAME}" + CONTENT + "sha,${DIVE_VERSION_SHA1}\nversion,${CMAKE_PROJECT_VERSION}\nbuild_type,$\nrelease_type,${DIVE_RELEASE_TYPE}\nabi,${ANDROID_ABI}" ) install( - FILES ${CMAKE_BINARY_DIR}/${DEVICE_LIBRARIES_VERSION_FILENAME} - DESTINATION ${CMAKE_INSTALL_PREFIX} + FILES + ${CMAKE_CURRENT_BINARY_DIR}/$/${DEVICE_LIBRARIES_VERSION_FILENAME} + DESTINATION ${DIVE_INSTALL_DESTINATION} ) list(POP_BACK CMAKE_MESSAGE_INDENT) message(CHECK_PASS "done") @@ -136,7 +138,7 @@ if(NOT ANDROID) message(CHECK_START "Generate build files for third_party/gfxreconstruct") list(APPEND CMAKE_MESSAGE_INDENT " ") - add_subdirectory(third_party/gfxreconstruct) + add_subdirectory(third_party/gfxreconstruct EXCLUDE_FROM_ALL) list(POP_BACK CMAKE_MESSAGE_INDENT) message(CHECK_PASS "done") else() @@ -145,7 +147,8 @@ else() "Generate build files for third_party/freedreno (libwrap)" ) list(APPEND CMAKE_MESSAGE_INDENT " ") - add_subdirectory(third_party/freedreno) + add_subdirectory(third_party/freedreno EXCLUDE_FROM_ALL) + install(TARGETS wrap DESTINATION ${DIVE_INSTALL_DESTINATION}) list(POP_BACK CMAKE_MESSAGE_INDENT) message(CHECK_PASS "done") @@ -154,14 +157,14 @@ else() "Generate build files for third_party/Vulkan-ValidationLayers" ) list(APPEND CMAKE_MESSAGE_INDENT " ") - add_subdirectory(third_party/Vulkan-ValidationLayers) + add_subdirectory(third_party/Vulkan-ValidationLayers) # This is a prebuilt list(POP_BACK CMAKE_MESSAGE_INDENT) message(CHECK_PASS "done") endif() message(CHECK_START "Generate build files for third_party/abseil-cpp") list(APPEND CMAKE_MESSAGE_INDENT " ") -add_subdirectory(third_party/abseil-cpp) +add_subdirectory(third_party/abseil-cpp EXCLUDE_FROM_ALL) list(POP_BACK CMAKE_MESSAGE_INDENT) message(CHECK_PASS "done") @@ -209,20 +212,6 @@ if(ANDROID) "Value of --console to use when building GFXR with Gradle" ) - # TODO(b/460765024): Prefer $ to CMAKE_BUILD_TYPE to support multi-config generators - if(CMAKE_BUILD_TYPE STREQUAL "Release") - set(CMAKE_BUILD_TYPE_LOWERCASE "release") - set(GFXR_REPLAY_APK_NAME "replay-release-unsigned.apk") - elseif(CMAKE_BUILD_TYPE STREQUAL "Debug") - set(CMAKE_BUILD_TYPE_LOWERCASE "debug") - set(GFXR_REPLAY_APK_NAME "replay-debug.apk") - else() - message( - FATAL_ERROR - "Must set -DCMAKE_BUILD_TYPE when targetting Android" - ) - endif() - if(CMAKE_HOST_WIN32) set(GRADLE_EXEC "gradlew.bat") else() @@ -231,8 +220,7 @@ if(ANDROID) execute_process( COMMAND - ${GRADLE_EXEC} layer:assemble${CMAKE_BUILD_TYPE} - replay:assemble${CMAKE_BUILD_TYPE} + ${GRADLE_EXEC} layer:assembleDebug replay:assembleDebug --console=${DIVE_GFXR_GRADLE_CONSOLE} -P${ANDROID_ABI} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gfxreconstruct/android @@ -241,33 +229,35 @@ if(ANDROID) list(POP_BACK CMAKE_MESSAGE_INDENT) message(CHECK_PASS "done") - message(CHECK_START "Extract GFXR files and prepare install") + message(CHECK_START "Extract GFXR files") list(APPEND CMAKE_MESSAGE_INDENT " ") + # Force usage of debug build of GFXR layer and replay apk file( ARCHIVE_EXTRACT INPUT - "${CMAKE_CURRENT_SOURCE_DIR}/third_party/gfxreconstruct/android/layer/build/outputs/aar/layer-${CMAKE_BUILD_TYPE_LOWERCASE}.aar" - DESTINATION "${CMAKE_BINARY_DIR}/gfxr_layer" + "${CMAKE_CURRENT_SOURCE_DIR}/third_party/gfxreconstruct/android/layer/build/outputs/aar/layer-debug.aar" + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/gfxr_layer" ) - install( - CODE - "file(REMOVE \"\${CMAKE_INSTALL_PREFIX}/libVkLayer_gfxreconstruct.so\")" + # Indicates expected location of extracted libVkLayer_gfxreconstruct.so during the cmake configuration phase + file( + TOUCH_NOCREATE + "${CMAKE_CURRENT_BINARY_DIR}/gfxr_layer/jni/${ANDROID_ABI}/libVkLayer_gfxreconstruct.so" ) install( FILES - ${CMAKE_BINARY_DIR}/gfxr_layer/jni/${ANDROID_ABI}/libVkLayer_gfxreconstruct.so - DESTINATION ${CMAKE_INSTALL_PREFIX} + ${CMAKE_CURRENT_BINARY_DIR}/gfxr_layer/jni/${ANDROID_ABI}/libVkLayer_gfxreconstruct.so + DESTINATION ${DIVE_INSTALL_DESTINATION} ) install( FILES - ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gfxreconstruct/android/tools/replay/build/outputs/apk/${CMAKE_BUILD_TYPE_LOWERCASE}/${GFXR_REPLAY_APK_NAME} - DESTINATION ${CMAKE_INSTALL_PREFIX} + ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gfxreconstruct/android/tools/replay/build/outputs/apk/debug/replay-debug.apk + DESTINATION ${DIVE_INSTALL_DESTINATION} RENAME "gfxr-replay.apk" ) install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/third_party/gfxreconstruct/android/scripts/gfxrecon.py - DESTINATION ${CMAKE_INSTALL_PREFIX} + DESTINATION ${DIVE_INSTALL_DESTINATION} ) list(POP_BACK CMAKE_MESSAGE_INDENT) message(CHECK_PASS "done") diff --git a/README.md b/README.md index a2fd502d9..4e28a11c3 100644 --- a/README.md +++ b/README.md @@ -13,40 +13,36 @@ Follow the instructions in [BUILD.md](BUILD.md) to build # UI -The recommended way of using Dive. Refer to [BUILD.md](BUILD.md) to first build the Dive host tools and the device libraries. +The recommended way of using Dive. Refer to [BUILD.md](BUILD.md) to first build the Dive host tools and the device libraries, and have them installed under `build/` ```sh # On Linux -$DIVE_ROOT_PATH/build/ui/dive +$DIVE_ROOT_PATH/build/pkg/host/dive ``` ```bat REM On Windows -%DIVE_ROOT_PATH%\build\ui\DIVE_HOST_TOOLS_BUILD_TYPE_HERE\dive.exe +%DIVE_ROOT_PATH%\build\pkg\host\dive.exe ``` -TODO(b/462767957): Figure out where these binaries are expected with the install flow - # CLI Tools -Refer to [BUILD.md](BUILD.md) to first build the Dive host tools and the device libraries. +Refer to [BUILD.md](BUILD.md) to first build the Dive host tools and the device libraries, and have them installed under `build/` ```sh # On Linux -$DIVE_ROOT_PATH/build/bin/dive_client_cli -$DIVE_ROOT_PATH/build/bin/divecli -$DIVE_ROOT_PATH/build/bin/host_cli +$DIVE_ROOT_PATH/build/pkg/host/dive_client_cli +$DIVE_ROOT_PATH/build/pkg/host/divecli +$DIVE_ROOT_PATH/build/pkg/host/host_cli ``` ```bat REM On Windows -%DIVE_ROOT_PATH%\build\bin\DIVE_HOST_TOOLS_BUILD_TYPE_HERE\dive_client_cli.exe -%DIVE_ROOT_PATH%\build\bin\DIVE_HOST_TOOLS_BUILD_TYPE_HERE\divecli.exe -%DIVE_ROOT_PATH%\build\bin\DIVE_HOST_TOOLS_BUILD_TYPE_HERE\host_cli.exe +%DIVE_ROOT_PATH%\build\pkg\host\dive_client_cli.exe +%DIVE_ROOT_PATH%\build\pkg\host\divecli.exe +%DIVE_ROOT_PATH%\build\pkg\host\host_cli.exe ``` -TODO(b/462767957): Figure out where these binaries are expected with the install flow - ## `divecli` Supports manipulation of PM4-related files and raw strings diff --git a/capture_service/CMakeLists.txt b/capture_service/CMakeLists.txt index 5ae91fb0f..76f4bb401 100644 --- a/capture_service/CMakeLists.txt +++ b/capture_service/CMakeLists.txt @@ -71,6 +71,7 @@ else() absl::strings absl::statusor component_files + resolve_device_path version_info command_utils ) @@ -91,7 +92,7 @@ else() PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/.. ) - install(TARGETS dive_client_cli DESTINATION ${CMAKE_INSTALL_PREFIX}) + install(TARGETS dive_client_cli DESTINATION ${DIVE_INSTALL_DESTINATION}) enable_testing() include(GoogleTest) diff --git a/capture_service/android_application.cc b/capture_service/android_application.cc index 4d3031976..2ca83067a 100644 --- a/capture_service/android_application.cc +++ b/capture_service/android_application.cc @@ -26,6 +26,7 @@ limitations under the License. #include "device_mgr.h" #include "common/log.h" #include "common/macros.h" +#include "dive/utils/resolve_device_path.h" namespace Dive { @@ -393,10 +394,17 @@ absl::Status AndroidApplication::CreateGfxrDirectory(const std::string directory absl::Status AndroidApplication::GfxrSetup() { - RETURN_IF_ERROR( - m_dev.Adb().Run(absl::StrFormat(R"(push "%s" "%s")", - ResolveAndroidLibPath(kVkGfxrLayerLibName).generic_string(), - kTargetPath))); + std::filesystem::path local_gfxr_layer_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath(kVkGfxrLayerLibName); + if (!ret.ok()) + { + return ret.status(); + } + local_gfxr_layer_path = *ret; + } + RETURN_IF_ERROR(m_dev.Adb().Run( + absl::StrFormat(R"(push "%s" "%s")", local_gfxr_layer_path.generic_string(), kTargetPath))); RETURN_IF_ERROR(m_dev.Adb().Run( absl::StrFormat("shell run-as %s cp %s/%s .", m_package, kTargetPath, kVkGfxrLayerLibName))); @@ -510,10 +518,18 @@ absl::Status OpenXRApplication::Pm4CaptureSetup() { RETURN_IF_ERROR(m_dev.Adb().Run("remount")); RETURN_IF_ERROR(m_dev.Adb().Run(absl::StrFormat("shell mkdir -p %s", kManifestFilePath))); + + std::filesystem::path local_manifest_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath(kManifestFileName); + if (!ret.ok()) + { + return ret.status(); + } + local_manifest_path = *ret; + } RETURN_IF_ERROR(m_dev.Adb().Run( - absl::StrFormat(R"(push "%s" "%s")", - ResolveAndroidLibPath(kManifestFileName).generic_string().c_str(), - kManifestFilePath))); + absl::StrFormat(R"(push "%s" "%s")", local_manifest_path.generic_string(), kManifestFilePath))); RETURN_IF_ERROR(m_dev.Adb().Run(absl::StrFormat("shell setprop wrap.%s LD_PRELOAD=%s/%s", m_package, kTargetPath, @@ -609,10 +625,19 @@ absl::Status VulkanCliApplication::Setup() absl::Status VulkanCliApplication::Pm4CaptureSetup() { RETURN_IF_ERROR(m_dev.Adb().Run(absl::StrFormat("shell mkdir -p %s", kVulkanGlobalPath))); - RETURN_IF_ERROR( - m_dev.Adb().Run(absl::StrFormat(R"(push "%s" "%s")", - ResolveAndroidLibPath(kVkLayerLibName).generic_string(), - kVulkanGlobalPath))); + + std::filesystem::path local_vulkan_layer_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath(kVkLayerLibName); + if (!ret.ok()) + { + return ret.status(); + } + local_vulkan_layer_path = *ret; + } + RETURN_IF_ERROR(m_dev.Adb().Run(absl::StrFormat(R"(push "%s" "%s")", + local_vulkan_layer_path.generic_string(), + kVulkanGlobalPath))); RETURN_IF_ERROR( m_dev.Adb().Run(absl::StrFormat("shell setprop debug.vulkan.layers %s", kVkLayerName))); return absl::OkStatus(); @@ -671,10 +696,19 @@ absl::Status VulkanCliApplication::Stop() absl::Status VulkanCliApplication::GfxrSetup() { RETURN_IF_ERROR(m_dev.Adb().Run(absl::StrFormat("shell mkdir -p %s", kVulkanGlobalPath))); - RETURN_IF_ERROR( - m_dev.Adb().Run(absl::StrFormat(R"(push "%s" "%s")", - ResolveAndroidLibPath(kVkGfxrLayerLibName).generic_string(), - kVulkanGlobalPath))); + + std::filesystem::path local_gfxr_layer_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath(kVkGfxrLayerLibName); + if (!ret.ok()) + { + return ret.status(); + } + local_gfxr_layer_path = *ret; + } + RETURN_IF_ERROR(m_dev.Adb().Run(absl::StrFormat(R"(push "%s" "%s")", + local_gfxr_layer_path.generic_string(), + kVulkanGlobalPath))); RETURN_IF_ERROR(m_dev.Adb().Run("shell setprop cpm.gfxr_layer 1")); RETURN_IF_ERROR( m_dev.Adb().Run(absl::StrFormat("shell setprop debug.vulkan.layers %s", kVkGfxrLayerName))); diff --git a/capture_service/device_mgr.cc b/capture_service/device_mgr.cc index 99a48711a..7b7e0560b 100644 --- a/capture_service/device_mgr.cc +++ b/capture_service/device_mgr.cc @@ -34,9 +34,10 @@ limitations under the License. #include "constants.h" #include "common/log.h" #include "common/macros.h" +#include "dive/utils/component_files.h" +#include "dive/utils/version_info.h" +#include "dive/utils/resolve_device_path.h" #include "remote_files.h" -#include "utils/component_files.h" -#include "utils/version_info.h" namespace Dive { @@ -176,10 +177,18 @@ absl::Status InstallVulkanLayer(const AdbSession &adb, std::string_view package, std::string_view layer_filename) { + std::filesystem::path local_layer_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath( + std::string(layer_filename)); + if (!ret.ok()) + { + return ret.status(); + } + local_layer_path = *ret; + } RETURN_IF_ERROR( - adb.Run(absl::StrFormat(R"(push "%s" "%s")", - ResolveAndroidLibPath(std::string(layer_filename)).generic_string(), - kTargetPath))); + adb.Run(absl::StrFormat(R"(push "%s" "%s")", local_layer_path.generic_string(), kTargetPath))); RETURN_IF_ERROR(adb.Run( absl::StrFormat(R"(shell run-as %s cp "%s/%s" .)", package, kTargetPath, layer_filename))); return absl::OkStatus(); @@ -552,41 +561,6 @@ absl::StatusOr> AndroidDevice::ListPackage(PackageListO return package_list; } -std::filesystem::path ResolveAndroidLibPath(const std::string &name) -{ - std::filesystem::path exe_dir; - absl::StatusOr ret = GetExecutableDirectory(); - if (ret.ok()) - { - exe_dir = *ret; - } - else - { - LOGW("Could not determine executable directory: %s. Search will not include " - "executable-relative paths.", - ret.status().message().data()); - } - - std::vector search_paths{ - exe_dir / "install", exe_dir / "../Resources", - "./install", "../../build_android/Release/bin", - "../../install", "./" - }; - - for (const auto &p : search_paths) - { - const auto potential_path = p / name; - if (std::filesystem::exists(potential_path)) - { - auto canonical_path = std::filesystem::canonical(potential_path); - LOGD("Found %s at %s \n", name.c_str(), canonical_path.generic_string().c_str()); - return canonical_path; - } - } - LOGE("Could not find '%s' in any of the search paths. \n", name.c_str()); - return {}; -} - absl::Status AndroidDevice::ForwardFirstAvailablePort() { for (int p = kFirstPort; p <= kFirstPort + kPortRange; p++) @@ -607,20 +581,44 @@ absl::Status AndroidDevice::ForwardFirstAvailablePort() absl::Status AndroidDevice::SetupDevice() { - RETURN_IF_ERROR(Adb().Run(absl::StrFormat(R"(push "%s" "%s")", - ResolveAndroidLibPath(kWrapLibName).generic_string(), - kTargetPath))); + std::filesystem::path local_wrap_lib_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath(kWrapLibName); + if (!ret.ok()) + { + return ret.status(); + } + local_wrap_lib_path = *ret; + } + RETURN_IF_ERROR(Adb().Run( + absl::StrFormat(R"(push "%s" "%s")", local_wrap_lib_path.generic_string(), kTargetPath))); if (!m_gfxr_enabled) { RETURN_IF_ERROR(RequestRootAccess()); - RETURN_IF_ERROR( - Adb().Run(absl::StrFormat(R"(push "%s" "%s")", - ResolveAndroidLibPath(kVkLayerLibName).generic_string(), - kTargetPath))); - RETURN_IF_ERROR( - Adb().Run(absl::StrFormat(R"(push "%s" "%s")", - ResolveAndroidLibPath(kXrLayerLibName).generic_string(), - kTargetPath))); + std::filesystem::path local_vulkan_layer_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath(kVkLayerLibName); + if (!ret.ok()) + { + return ret.status(); + } + local_vulkan_layer_path = *ret; + } + RETURN_IF_ERROR(Adb().Run(absl::StrFormat(R"(push "%s" "%s")", + local_vulkan_layer_path.generic_string(), + kTargetPath))); + + std::filesystem::path local_xr_layer_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath(kXrLayerLibName); + if (!ret.ok()) + { + return ret.status(); + } + local_xr_layer_path = *ret; + } + RETURN_IF_ERROR(Adb().Run( + absl::StrFormat(R"(push "%s" "%s")", local_xr_layer_path.generic_string(), kTargetPath))); RETURN_IF_ERROR(ForwardFirstAvailablePort()); } @@ -931,17 +929,33 @@ absl::Status DeviceManager::DeployReplayApk(const std::string &serial) } }; - std::string replay_apk_path = ResolveAndroidLibPath(kGfxrReplayApkName).generic_string(); - std::string recon_py_path = ResolveAndroidLibPath(kGfxrReconPyPath).generic_string(); - std::string cmd = absl::StrFormat("%s %s install-apk %s -s %s", + std::filesystem::path local_replay_apk_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath(kGfxrReplayApkName); + if (!ret.ok()) + { + return ret.status(); + } + local_replay_apk_path = *ret; + } + std::filesystem::path local_recon_py_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath(kGfxrReconPyPath); + if (!ret.ok()) + { + return ret.status(); + } + local_recon_py_path = *ret; + } + std::string cmd = absl::StrFormat("%s %s install-apk %s -s %s", python_path, - recon_py_path, - replay_apk_path, + local_recon_py_path.generic_string(), + local_replay_apk_path.generic_string(), serial); absl::StatusOr res = RunCommand(cmd); if (!res.ok()) { - LOGD("ERROR: DeployReplayApk(): deploying apk at: %s\n", replay_apk_path.c_str()); + LOGD("ERROR: DeployReplayApk(): deploying apk at: %s\n", local_replay_apk_path.c_str()); return res.status(); } @@ -1039,10 +1053,19 @@ absl::Status DeviceManager::RunReplayGfxrScript(const GfxrReplaySettings &settin LOGD("RunReplayGfxrScript(): RUN\n"); std::string python_path = GetPythonPath(); RETURN_IF_ERROR(ValidatePythonPath(python_path)); - std::string local_recon_py_path = ResolveAndroidLibPath(kGfxrReconPyPath).generic_string(); + + std::filesystem::path local_recon_py_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath(kGfxrReconPyPath); + if (!ret.ok()) + { + return ret.status(); + } + local_recon_py_path = *ret; + } std::string cmd = absl::StrFormat("%s %s replay %s %s", python_path, - local_recon_py_path, + local_recon_py_path.generic_string(), settings.remote_capture_path, settings.replay_flags_str); if (absl::StatusOr res = RunCommand(cmd); !res.ok()) @@ -1136,8 +1159,19 @@ absl::Status DeviceManager::RunReplayProfilingBinary(const GfxrReplaySettings &s LOGD("RunReplayProfilingBinary(): SETUP\n"); LOGD("RunReplayProfilingBinary(): Deploy libraries and binaries\n"); + + std::filesystem::path local_plugin_folder_path; + { + absl::StatusOr ret = Dive::ResolveDevicePath( + kProfilingPluginFolderName); + if (!ret.ok()) + { + return ret.status(); + } + local_plugin_folder_path = *ret; + } std::string copy_cmd = absl::StrFormat(R"(push "%s" "%s")", - ResolveAndroidLibPath(kProfilingPluginFolderName), + local_plugin_folder_path.generic_string(), kTargetPath); RETURN_IF_ERROR(adb.Run(copy_cmd)); std::string remote_profiling_dir = absl::StrFormat("%s/%s", diff --git a/capture_service/device_mgr.h b/capture_service/device_mgr.h index 117214a48..07f754baa 100644 --- a/capture_service/device_mgr.h +++ b/capture_service/device_mgr.h @@ -225,7 +225,5 @@ class DeviceManager std::unique_ptr m_device{ nullptr }; }; -std::filesystem::path ResolveAndroidLibPath(const std::string &name); - DeviceManager &GetDeviceManager(); } // namespace Dive \ No newline at end of file diff --git a/layer/CMakeLists.txt b/layer/CMakeLists.txt index 1791c25e7..3c41fd3d7 100644 --- a/layer/CMakeLists.txt +++ b/layer/CMakeLists.txt @@ -71,7 +71,7 @@ target_link_directories( PRIVATE ${CMAKE_SOURCE_DIR}/capture_service ) -if(CMAKE_BUILD_TYPE STREQUAL "Release") +if($) set_target_properties(${target_name} PROPERTIES LINK_FLAGS_RELEASE -s) endif() @@ -95,10 +95,10 @@ configure_file( "${CMAKE_BINARY_DIR}/bin/VkLayer_dive_capture.json" COPYONLY ) -install(TARGETS ${target_name} DESTINATION ${CMAKE_INSTALL_PREFIX}) +install(TARGETS ${target_name} DESTINATION ${DIVE_INSTALL_DESTINATION}) install( FILES "${CMAKE_CURRENT_SOURCE_DIR}/manifest/XrApiLayer_dive.json" - DESTINATION ${CMAKE_INSTALL_PREFIX} + DESTINATION ${DIVE_INSTALL_DESTINATION} ) set(target_name XrApiLayer_dive) @@ -120,15 +120,16 @@ target_include_directories( ${CMAKE_SOURCE_DIR}/third_party/OpenXR-SDK/src ${CMAKE_SOURCE_DIR}/third_party/OpenXR-SDK/src/common ) -if(CMAKE_BUILD_TYPE STREQUAL "Release") + +if($) set_target_properties(${target_name} PROPERTIES LINK_FLAGS_RELEASE -s) endif() target_link_libraries(${target_name} ${TARGET_LINK_LIBS}) -install(TARGETS ${target_name} DESTINATION ${CMAKE_INSTALL_PREFIX}) +install(TARGETS ${target_name} DESTINATION ${DIVE_INSTALL_DESTINATION}) install( FILES "${CMAKE_CURRENT_SOURCE_DIR}/manifest/XrApiLayer_dive.json" - DESTINATION ${CMAKE_INSTALL_PREFIX} + DESTINATION ${DIVE_INSTALL_DESTINATION} ) list(POP_BACK CMAKE_MESSAGE_INDENT) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index cd5afcff1..09f1d5ba6 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -24,7 +24,7 @@ list(APPEND CMAKE_MESSAGE_INDENT " ") # For each new plugin, you can add an add_subdirectory call here. add_subdirectory(plugin_sample) -install(CODE "file(MAKE_DIRECTORY ${CMAKE_INSTALL_PREFIX}/plugins)") +install(CODE "file(MAKE_DIRECTORY ${DIVE_INSTALL_DESTINATION}/plugins)") list(POP_BACK CMAKE_MESSAGE_INDENT) message(CHECK_PASS "done") diff --git a/plugins/plugin_sample/CMakeLists.txt b/plugins/plugin_sample/CMakeLists.txt index d35daf93b..d9aa6eedc 100644 --- a/plugins/plugin_sample/CMakeLists.txt +++ b/plugins/plugin_sample/CMakeLists.txt @@ -58,5 +58,5 @@ target_include_directories( # This ensures that when Dive is installed, its plugins are correctly placed. install( TARGETS dive_plugin_sample - DESTINATION ${CMAKE_INSTALL_PREFIX}/bin/plugins + DESTINATION ${DIVE_INSTALL_DESTINATION}/bin/plugins ) diff --git a/runtime_layer/CMakeLists.txt b/runtime_layer/CMakeLists.txt index edb6d1458..7ceacbff8 100644 --- a/runtime_layer/CMakeLists.txt +++ b/runtime_layer/CMakeLists.txt @@ -51,7 +51,7 @@ target_link_libraries(${target_name} dive_legacy_includes gpu_time) add_definitions(-DVK_USE_PLATFORM_ANDROID_KHR) target_link_libraries(${target_name} -lm -ldl -llog -landroid) -if(CMAKE_BUILD_TYPE STREQUAL "Release") +if($) set_target_properties(${target_name} PROPERTIES LINK_FLAGS_RELEASE -s) endif() @@ -71,7 +71,7 @@ set_target_properties( PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/" ) -install(TARGETS ${target_name} DESTINATION ${CMAKE_INSTALL_PREFIX}) +install(TARGETS ${target_name} DESTINATION ${DIVE_INSTALL_DESTINATION}) list(POP_BACK CMAKE_MESSAGE_INDENT) message(CHECK_PASS "done") diff --git a/scripts/build_android.bat b/scripts/build_android.bat index f466db695..4e2acd1d8 100644 --- a/scripts/build_android.bat +++ b/scripts/build_android.bat @@ -18,8 +18,6 @@ setlocal enabledelayedexpansion set PROJECT_ROOT=%~dp0\.. set BUILD_TYPE=Debug -set SRC_DIR=%PROJECT_ROOT% -set GFXR_ROOT_DIR=%PROJECT_ROOT%\\third_party\\gfxreconstruct\\android set startTime=%time% if "%~1"=="" goto parsingdone @@ -33,36 +31,33 @@ if not !BUILD_TYPE!==%1 ( :parsingdone echo Building all the following types: !BUILD_TYPE! +pushd %PROJECT_ROOT% + +cmake . -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK_HOME%/build/cmake/android.toolchain.cmake ^ + -G "Ninja Multi-Config"^ + -Bbuild/device ^ + -DCMAKE_MAKE_PROGRAM="ninja" ^ + -DCMAKE_SYSTEM_NAME=Android ^ + -DANDROID_ABI=arm64-v8a ^ + -DANDROID_PLATFORM=android-26 ^ + -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER ^ + -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER ^ + +if not !ERRORLEVEL!==0 exit /b 1 + (for %%b in (!BUILD_TYPE!) do ( setlocal enabledelayedexpansion echo. set build=%%b - set BUILD_DIR=%PROJECT_ROOT%\\build_android\\!build! - echo BUILD_DIR: !BUILD_DIR! - md !BUILD_DIR! - - pushd !BUILD_DIR! - cmake -DCMAKE_TOOLCHAIN_FILE=%ANDROID_NDK_HOME%/build/cmake/android.toolchain.cmake ^ - -G "Ninja"^ - -DCMAKE_MAKE_PROGRAM="ninja" ^ - -DCMAKE_BUILD_TYPE=!build! ^ - -DCMAKE_SYSTEM_NAME=Android ^ - -DANDROID_ABI=arm64-v8a ^ - -DANDROID_PLATFORM=android-26 ^ - -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER ^ - -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER ^ - %SRC_DIR% + cmake --build build/device --config=!build! if not !ERRORLEVEL!==0 exit /b 1 - cmake --build . --config=!build! -j + cmake --install build/device --prefix build/pkg/device --config=!build! if not !ERRORLEVEL!==0 exit /b 1 - - cmake --install . - if not !ERRORLEVEL!==0 exit /b 1 - - popd )) +popd + echo Start Time: %startTime% echo Finish Time: %time% \ No newline at end of file diff --git a/scripts/build_android.sh b/scripts/build_android.sh index 2750f4d2b..f74e637c5 100755 --- a/scripts/build_android.sh +++ b/scripts/build_android.sh @@ -19,8 +19,6 @@ PROJECT_ROOT="$(readlink -f $0)" PROJECT_ROOT="${PROJECT_ROOT%/*}/.." readonly PROJECT_ROOT="$(readlink -f ${PROJECT_ROOT})" -readonly BUILD_DIR_ROOT=${PROJECT_ROOT}/build_android -readonly SRC_DIR=${PROJECT_ROOT} BUILD_TYPE=(Debug) readonly START_TIME=`date +%r` @@ -35,31 +33,29 @@ if [ $# -ne 0 ]; then fi echo "Building all the following types: $BUILD_TYPE" -for build in "${BUILD_TYPE}" -do - BUILD_DIR=${BUILD_DIR_ROOT}/${build} - mkdir -p ${BUILD_DIR} - pushd ${BUILD_DIR} - echo "SRC_DIR " ${SRC_DIR} - echo "current dir " `pwd` +pushd ${PROJECT_ROOT} - cmake -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \ - -G "Ninja" \ - -DCMAKE_MAKE_PROGRAM="ninja" \ - -DCMAKE_BUILD_TYPE=${build} \ - -DCMAKE_SYSTEM_NAME=Android \ - -DANDROID_ABI=arm64-v8a \ - -DANDROID_PLATFORM=android-26 \ - -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \ - -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER \ - ${SRC_DIR} || exit 1 +echo "current dir " `pwd` - cmake --build . --config=${build} -j || exit 1 +cmake . -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK_HOME}/build/cmake/android.toolchain.cmake \ + -G "Ninja Multi-Config" \ + -Bbuild/device \ + -DCMAKE_MAKE_PROGRAM="ninja" \ + -DCMAKE_SYSTEM_NAME=Android \ + -DANDROID_ABI=arm64-v8a \ + -DANDROID_PLATFORM=android-26 \ + -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=NEVER \ + -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=NEVER \ + || exit 1 - cmake --install . || exit 1 +for build in "${BUILD_TYPE}" +do + cmake --build build/device --config=${build} || exit 1 - popd + cmake --install build/device --prefix build/pkg/device --config=${build} || exit 1 done +popd + echo "Start Time:" ${START_TIME} echo "Finish Time:" `date +%r` \ No newline at end of file diff --git a/src/dive/build_defs/dive_cmake_generated.h.in b/src/dive/build_defs/dive_cmake_generated.h.in index 60110d1f0..f74d14d21 100644 --- a/src/dive/build_defs/dive_cmake_generated.h.in +++ b/src/dive/build_defs/dive_cmake_generated.h.in @@ -28,7 +28,6 @@ limitations under the License. // clang-format on #define CMAKE_GENERATED_HOST_PLATFORM "@HOST_PLATFORM_STRING@" -#define CMAKE_GENERATED_INSTALL_DIR_PATH "@CMAKE_INSTALL_PREFIX@" #define CMAKE_GENERATED_BUILD_TYPE "$" #define CMAKE_GENERATED_RELEASE_TYPE "@DIVE_RELEASE_TYPE@" #define CMAKE_GENERATED_DEVICE_LIBRARIES_VERSION_FILENAME "@DEVICE_LIBRARIES_VERSION_FILENAME@" diff --git a/src/dive/build_defs/version_defs.h b/src/dive/build_defs/version_defs.h index 98b2b5d66..7c331521b 100644 --- a/src/dive/build_defs/version_defs.h +++ b/src/dive/build_defs/version_defs.h @@ -38,5 +38,4 @@ limitations under the License. // (dev|release|internal|canary) #define DIVE_RELEASE_TYPE CMAKE_GENERATED_RELEASE_TYPE -#define DIVE_INSTALL_DIR_PATH CMAKE_GENERATED_INSTALL_DIR_PATH #define DIVE_DEVICE_LIBRARIES_VERSION_FILENAME CMAKE_GENERATED_DEVICE_LIBRARIES_VERSION_FILENAME diff --git a/src/dive/utils/CMakeLists.txt b/src/dive/utils/CMakeLists.txt index 01a3799cf..354b9823e 100644 --- a/src/dive/utils/CMakeLists.txt +++ b/src/dive/utils/CMakeLists.txt @@ -27,6 +27,21 @@ if(NOT ANDROID) ) endif() +# === resolve_device_path ====================================================== + +if(NOT ANDROID) + add_library( + resolve_device_path + resolve_device_path.h + resolve_device_path.cpp + ) + target_link_libraries( + resolve_device_path + PUBLIC absl::statusor absl::strings + PRIVATE dive_src_includes command_utils + ) +endif() + # === version_info ============================================================= if(NOT ANDROID) @@ -34,8 +49,7 @@ if(NOT ANDROID) target_link_libraries( version_info PUBLIC absl::statusor absl::strings - PRIVATE dive_build_defs dive_src_includes - PRIVATE command_utils + PRIVATE dive_build_defs dive_src_includes resolve_device_path ) endif() diff --git a/src/dive/utils/resolve_device_path.cpp b/src/dive/utils/resolve_device_path.cpp new file mode 100644 index 000000000..1a3142037 --- /dev/null +++ b/src/dive/utils/resolve_device_path.cpp @@ -0,0 +1,93 @@ +/* + Copyright 2025 Google LLC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "dive/utils/resolve_device_path.h" + +#include + +#include "absl/status/statusor.h" +#include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" +#include "dive/os/command_utils.h" + +namespace Dive +{ + +// Returns potential positions of the device libraries relative to the executable, which can vary +// depending on the host platform and the release type. +absl::StatusOr> GetPotentialDeviceLibraryDirs() +{ + std::vector search_paths; + + absl::StatusOr ret = Dive::GetExecutableDirectory(); + if (!ret.ok()) + { + std::string warn_msg = absl:: + StrFormat("Could not determine executable directory: %s. Search will not include " + "executable-relative paths.", + ret.status().message().data()); + return absl::NotFoundError(warn_msg); + } + + std::filesystem::path exe_dir = *ret; + + // The host tool and device libraries have both been installed under pkg/ + search_paths.push_back(exe_dir / "../device/"); + + // For dev builds, when the host tool is being launched from: build/host/// (a + // common VS use case) + // + // And the device libraries have been installed under build/pkg/device/ + search_paths.push_back(exe_dir / "../../../pkg/device"); + + return search_paths; +} + +absl::StatusOr ResolveDevicePath(std::filesystem::path file_name) +{ + std::vector search_paths; + { + auto ret = GetPotentialDeviceLibraryDirs(); + if (!ret.ok()) + { + return ret.status(); + } + search_paths = *ret; + } + + std::vector searched_paths_strings; + + assert(!search_paths.empty()); + + for (const auto &p : search_paths) + { + const auto potential_path = p / file_name; + if (std::filesystem::exists(potential_path)) + { + auto canonical_path = std::filesystem::canonical(potential_path); + return canonical_path; + } + searched_paths_strings.push_back(potential_path.generic_string()); + } + + std::string + err_msg = absl::StrFormat("Cannot find file in deployment dir: %s, searched here: \n%s", + file_name, + absl::StrJoin(searched_paths_strings, ", \n")); + return absl::NotFoundError(err_msg); +} + +} // namespace Dive \ No newline at end of file diff --git a/src/dive/utils/resolve_device_path.h b/src/dive/utils/resolve_device_path.h new file mode 100644 index 000000000..e899d180b --- /dev/null +++ b/src/dive/utils/resolve_device_path.h @@ -0,0 +1,29 @@ +/* + Copyright 2025 Google LLC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#pragma once + +#include + +#include "absl/status/statusor.h" + +namespace Dive +{ +// Returns the full path of an Android library-related file, searching for it within the device +// library directory (which is predicted relative to the executable directory) +absl::StatusOr ResolveDevicePath(std::filesystem::path file_path); + +} // namespace Dive \ No newline at end of file diff --git a/src/dive/utils/version_info.cpp b/src/dive/utils/version_info.cpp index f3269a4ab..fc8082bb3 100644 --- a/src/dive/utils/version_info.cpp +++ b/src/dive/utils/version_info.cpp @@ -24,7 +24,7 @@ limitations under the License. #include "absl/strings/str_format.h" #include "absl/strings/str_split.h" #include "dive/build_defs/version_defs.h" -#include "dive/os/command_utils.h" +#include "dive/utils/resolve_device_path.h" namespace { @@ -32,7 +32,7 @@ namespace constexpr size_t kShortSha = 7; constexpr size_t kLongSha = 40; -// This is relative to install/ +// This is relative to the device library dir constexpr std::string_view kProfilingPluginShaPath = "dive_profiling_plugin/SHA"; // Upper bound of file size to avoid reading long files @@ -41,12 +41,6 @@ constexpr size_t kMaxCharactersDeviceLibraryFile = 200; absl::StatusOr ReadFileCapped(const std::filesystem::path& file_path, size_t max_characters) { - if (!std::filesystem::exists(file_path)) - { - return absl::FailedPreconditionError( - absl::StrFormat("File does not exist: %s", file_path.generic_string())); - } - std::ifstream file(file_path); if (!file.is_open()) { @@ -195,57 +189,40 @@ std::string GetDeviceLibrariesVersionInfo(const std::string& csv_content) GetSHAString(device_info_map[VersionInfoConstants::kNameSha], kLongSha)); } -std::filesystem::path ResolvePath(std::string_view file_name) -{ - std::vector search_paths; - if (auto exe_dir = Dive::GetExecutableDirectory(); exe_dir.ok()) - { - search_paths.push_back(*exe_dir); - search_paths.push_back(*exe_dir / "install"); - } - else - { - std::cerr << exe_dir.status().message() << std::endl; - } - search_paths.push_back(DIVE_INSTALL_DIR_PATH); - - for (const auto& p : search_paths) - { - const auto potential_path = p / file_name; - if (std::filesystem::exists(potential_path)) - { - auto canonical_path = std::filesystem::canonical(potential_path); - std::cout << "Found " << file_name << " at " << canonical_path << "\n"; - return canonical_path; - } - } - std::cerr << "Could not find '" << file_name << "' in any of the search paths.\n"; - return {}; -} - std::string GetLongVersionString() { std::string summary = GetHostToolsVersionInfo(); - std::filesystem::path device_libraries_version_path = ResolvePath( - DIVE_DEVICE_LIBRARIES_VERSION_FILENAME); - if (absl::StatusOr ret = ReadFileCapped(device_libraries_version_path, - kMaxCharactersDeviceLibraryFile); - ret.ok()) + if (auto ret = Dive::ResolveDevicePath(DIVE_DEVICE_LIBRARIES_VERSION_FILENAME); ret.ok()) { - summary += "\n" + GetDeviceLibrariesVersionInfo(*ret); + std::filesystem::path device_libraries_version_path = *ret; + if (absl::StatusOr ret = ReadFileCapped(device_libraries_version_path, + kMaxCharactersDeviceLibraryFile); + ret.ok()) + { + summary += "\n" + GetDeviceLibrariesVersionInfo(*ret); + } + else + { + std::cerr << ret.status().message() << std::endl; + } } else { std::cerr << ret.status().message() << std::endl; } - std::filesystem::path profiling_plugin_version_path = ResolvePath(kProfilingPluginShaPath); - if (absl::StatusOr ret = ReadFileCapped(profiling_plugin_version_path, kLongSha); - ret.ok()) + if (auto ret = Dive::ResolveDevicePath(kProfilingPluginShaPath); ret.ok()) { - std::string profiling_plugin_section = absl::StrFormat("Profiling Plugin SHA: %s\n", *ret); - summary += "\n" + profiling_plugin_section; + std::filesystem::path profiling_plugin_version_path = *ret; + if (absl::StatusOr ret = ReadFileCapped(profiling_plugin_version_path, + kLongSha); + ret.ok()) + { + std::string profiling_plugin_section = absl::StrFormat("Profiling Plugin SHA: %s\n", + *ret); + summary += "\n" + profiling_plugin_section; + } } // Want silent failure for profiling plugin or else the CLI stdout can confuse users @@ -259,8 +236,16 @@ std::string GetCompleteVersionString() absl::StatusOr GetDeviceLibraryInfo(std::string_view key) { - std::filesystem::path device_libraries_version_path = ResolvePath( - DIVE_DEVICE_LIBRARIES_VERSION_FILENAME); + std::filesystem::path device_libraries_version_path; + { + auto ret = Dive::ResolveDevicePath(DIVE_DEVICE_LIBRARIES_VERSION_FILENAME); + if (!ret.ok()) + { + return ret.status(); + } + device_libraries_version_path = *ret; + } + std::string csv_content; { absl::StatusOr ret = ReadFileCapped(device_libraries_version_path, diff --git a/src/dive/utils/version_info.h b/src/dive/utils/version_info.h index 7aeba8cc4..5f91d2310 100644 --- a/src/dive/utils/version_info.h +++ b/src/dive/utils/version_info.h @@ -70,7 +70,6 @@ std::string GetDiveDescription(); // ----- // clang-format on // -// NOTE: Other than host tools info, info is retrieved from within DIVE_INSTALL_DIR_PATH std::string GetLongVersionString(); // Returns both the host short version string and long version string diff --git a/third_party/Vulkan-ValidationLayers/CMakeLists.txt b/third_party/Vulkan-ValidationLayers/CMakeLists.txt index cd71c0914..cd59247b3 100644 --- a/third_party/Vulkan-ValidationLayers/CMakeLists.txt +++ b/third_party/Vulkan-ValidationLayers/CMakeLists.txt @@ -17,5 +17,5 @@ # License is handled by ui/CMakeLists.txt install( FILES ${CMAKE_CURRENT_SOURCE_DIR}/android/${ANDROID_ABI}/libVkLayer_khronos_validation.so - DESTINATION ${CMAKE_INSTALL_PREFIX} + DESTINATION ${DIVE_INSTALL_DESTINATION} ) diff --git a/third_party/freedreno/CMakeLists.txt b/third_party/freedreno/CMakeLists.txt index ea5b60743..02d86185f 100644 --- a/third_party/freedreno/CMakeLists.txt +++ b/third_party/freedreno/CMakeLists.txt @@ -54,7 +54,7 @@ endif() add_custom_command(TARGET ${target_name} POST_BUILD COMMAND "${ANDROID_TOOLCHAIN_ROOT}/bin/llvm-strip" --strip-unneeded - "${CMAKE_BINARY_DIR}/bin/lib${target_name}.so" + "${CMAKE_BINARY_DIR}/bin/$/lib${target_name}.so" COMMENT "Strip debug symbols done on final binary.") install(TARGETS ${target_name} DESTINATION ${CMAKE_INSTALL_PREFIX}) \ No newline at end of file diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index aba8dfa8a..e7b3e27e7 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -116,6 +116,7 @@ target_link_libraries( device_mgr dive_plugin_loader component_files + resolve_device_path version_info dive_build_defs ) @@ -214,43 +215,43 @@ if(APPLE) CODE " message(STATUS \"Running macdeployqt...\") - execute_process(COMMAND \"macdeployqt\" \"${CMAKE_INSTALL_PREFIX}/dive.app\") + execute_process(COMMAND \"macdeployqt\" \"${DIVE_INSTALL_DESTINATION}/dive.app\") message(STATUS \"Creating install directory in app bundle\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E make_directory \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E make_directory \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/\") message(STATUS \"Copying Android files to app bundle\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/gfxr-replay.apk\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/gfxrecon.py\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/libVkLayer_dive.so\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/libVkLayer_khronos_validation.so\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/libXrApiLayer_dive.so\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/XrApiLayer_dive.json\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/libVkLayer_rt_dive.so\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/libwrap.so\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/libVkLayer_gfxreconstruct.so\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/gfxr-replay.apk\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/gfxrecon.py\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/libVkLayer_dive.so\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/libVkLayer_khronos_validation.so\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/libXrApiLayer_dive.so\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/XrApiLayer_dive.json\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/libVkLayer_rt_dive.so\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/libwrap.so\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/libVkLayer_gfxreconstruct.so\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/\") message(STATUS \"Copying dive_client_cli to app bundle\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/dive_client_cli\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/MacOS/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/dive_client_cli\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/MacOS/\") - if(IS_DIRECTORY \"${CMAKE_INSTALL_PREFIX}/dive_profiling_plugin\") + if(IS_DIRECTORY \"${DIVE_INSTALL_DESTINATION}/dive_profiling_plugin\") message(STATUS \"Copying dive_profiling_plugin to app bundle\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy_directory \"${CMAKE_INSTALL_PREFIX}/dive_profiling_plugin/\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/Resources/dive_profiling_plugin\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy_directory \"${DIVE_INSTALL_DESTINATION}/dive_profiling_plugin/\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/Resources/dive_profiling_plugin\") endif() - if(EXISTS \"${CMAKE_INSTALL_PREFIX}/dive_compositor_capture.sh\") + if(EXISTS \"${DIVE_INSTALL_DESTINATION}/dive_compositor_capture.sh\") message(STATUS \"Copying dive_compositor_capture.sh to app bundle\") - execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${CMAKE_INSTALL_PREFIX}/dive_compositor_capture.sh\" \"${CMAKE_INSTALL_PREFIX}/dive.app/Contents/MacOS/\") + execute_process(COMMAND \"${CMAKE_COMMAND}\" -E copy \"${DIVE_INSTALL_DESTINATION}/dive_compositor_capture.sh\" \"${DIVE_INSTALL_DESTINATION}/dive.app/Contents/MacOS/\") endif() if(${DIVE_ENABLE_SIGNING}) message(STATUS \"Ad-hoc signing the application bundle\") - execute_process(COMMAND \"codesign\" --force --deep --sign - \"${CMAKE_INSTALL_PREFIX}/dive.app\") + execute_process(COMMAND \"codesign\" --force --deep --sign - \"${DIVE_INSTALL_DESTINATION}/dive.app\") endif() " ) else() - install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}) + install(TARGETS ${PROJECT_NAME} DESTINATION ${DIVE_INSTALL_DESTINATION}) endif() install( FILES "${CMAKE_CURRENT_BINARY_DIR}/NOTICE" - DESTINATION "${CMAKE_INSTALL_PREFIX}" + DESTINATION "${DIVE_INSTALL_DESTINATION}" ) add_dependencies(${PROJECT_NAME} notice_file) diff --git a/ui/main_window.cpp b/ui/main_window.cpp index 3d00e8ed7..d1b49128c 100644 --- a/ui/main_window.cpp +++ b/ui/main_window.cpp @@ -54,6 +54,7 @@ #include "absl/status/statusor.h" #include "absl/types/span.h" #include "capture_service/constants.h" +#include "dive/utils/resolve_device_path.h" #include "dive_core/command_hierarchy.h" #include "dive_core/common/common.h" #include "dive_core/data_core.h" @@ -168,41 +169,6 @@ QString ToQString(DrawCallContextMenuOption opt) return "Unknown"; } -std::optional ResolveAssetPath(const std::string &name) -{ - std::vector search_paths; - absl::StatusOr ret = Dive::GetExecutableDirectory(); - if (ret.ok()) - { - const auto &exe_dir = *ret; - search_paths.push_back(exe_dir / "install"); - search_paths.push_back(exe_dir); -#if defined(__APPLE__) - search_paths.push_back(exe_dir / "../Resources/"); -#endif - } - else - { - qDebug() << "Could not determine executable directory: " << ret.status().message().data() - << ". Search will not include executable-relative paths."; - } - - search_paths.push_back(std::filesystem::path{ "./install" }); - search_paths.push_back(std::filesystem::path{ "../../build_android/Release/bin" }); - search_paths.push_back(std::filesystem::path{ "../../install" }); - search_paths.push_back(std::filesystem::path{ "./" }); - - for (const auto &p : search_paths) - { - auto result_path = p / name; - if (std::filesystem::exists(result_path)) - { - return std::filesystem::canonical(result_path); - } - } - return std::nullopt; -} - } // namespace void SetTabAvailable(QTabWidget *widget, int index, bool available) @@ -1619,9 +1585,11 @@ void MainWindow::OnSearchTrigger() void MainWindow::LoadAvailableMetrics() { std::optional metrics_description_file_path = std::nullopt; - if (auto profile_plugin_folder = ResolveAssetPath(Dive::kProfilingPluginFolderName)) + if (absl::StatusOr ret = Dive::ResolveDevicePath( + Dive::kProfilingPluginFolderName); + ret.ok()) { - auto file_path = *profile_plugin_folder / kMetricsFileName; + auto file_path = *ret / kMetricsFileName; if (std::filesystem::exists(file_path)) { metrics_description_file_path = file_path;