diff --git a/renderdoc/android/android.cpp b/renderdoc/android/android.cpp index 7c134e8e0..778180edf 100644 --- a/renderdoc/android/android.cpp +++ b/renderdoc/android/android.cpp @@ -416,6 +416,7 @@ ReplayStatus InstallRenderDocServer(const std::string &deviceID) paths.push_back(libDir + "/plugins/android/"); // Windows install paths.push_back(libDir + "/../share/renderdoc/plugins/android/"); // Linux install + paths.push_back(libDir + "/../plugins/android/"); // macOS install paths.push_back(libDir + "/../../build-android/bin/"); // Local build paths.push_back(libDir + "/../../build-android" + suff + "/bin/"); // Local ABI build paths.push_back(libDir + "/../../../../../build-android/bin/"); // macOS build diff --git a/renderdoc/driver/vulkan/vk_apple.cpp b/renderdoc/driver/vulkan/vk_apple.cpp index f2e4d68b3..65d7a51c6 100644 --- a/renderdoc/driver/vulkan/vk_apple.cpp +++ b/renderdoc/driver/vulkan/vk_apple.cpp @@ -104,7 +104,7 @@ void *LoadVulkanLibrary() // if not, we fall back to our embedded libvulkan and also force use of our embedded ICD. std::string libpath; FileIO::GetLibraryFilename(libpath); - libpath = dirname(libpath) + "/../MoltenVK/"; + libpath = dirname(libpath) + "/../plugins/MoltenVK/"; RDCLOG("Couldn't load global libvulkan.1.dylib, falling back to bundled MoltenVK in %s", libpath.c_str()); diff --git a/util/buildscripts/build.sh b/util/buildscripts/build.sh index 1df2c892d..9363e25f6 100755 --- a/util/buildscripts/build.sh +++ b/util/buildscripts/build.sh @@ -1,11 +1,149 @@ #!/bin/bash +#### realpath.sh from https://github.com/mkropat/sh-realpath/ +# +# The MIT License (MIT) +# +# Copyright (c) 2014 Michael Kropat +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# +#### + +realpath() { + canonicalize_path "$(resolve_symlinks "$1")" +} + +resolve_symlinks() { + _resolve_symlinks "$1" +} + +_resolve_symlinks() { + _assert_no_path_cycles "$@" || return + + local dir_context path + path=$(readlink -- "$1") + if [ $? -eq 0 ]; then + dir_context=$(dirname -- "$1") + _resolve_symlinks "$(_prepend_dir_context_if_necessary "$dir_context" "$path")" "$@" + else + printf '%s\n' "$1" + fi +} + +_prepend_dir_context_if_necessary() { + if [ "$1" = . ]; then + printf '%s\n' "$2" + else + _prepend_path_if_relative "$1" "$2" + fi +} + +_prepend_path_if_relative() { + case "$2" in + /* ) printf '%s\n' "$2" ;; + * ) printf '%s\n' "$1/$2" ;; + esac +} + +_assert_no_path_cycles() { + local target path + + target=$1 + shift + + for path in "$@"; do + if [ "$path" = "$target" ]; then + return 1 + fi + done +} + +canonicalize_path() { + if [ -d "$1" ]; then + _canonicalize_dir_path "$1" + else + _canonicalize_file_path "$1" + fi +} + +_canonicalize_dir_path() { + (cd "$1" 2>/dev/null && pwd -P) +} + +_canonicalize_file_path() { + local dir file + dir=$(dirname -- "$1") + file=$(basename -- "$1") + (cd "$dir" 2>/dev/null && printf '%s/%s\n' "$(pwd -P)" "$file") +} + +# Optionally, you may also want to include: + +### readlink emulation ### + +readlink() { + if _has_command readlink; then + _system_readlink "$@" + else + _emulated_readlink "$@" + fi +} + +_has_command() { + hash -- "$1" 2>/dev/null +} + +_system_readlink() { + command readlink "$@" +} + +_emulated_readlink() { + if [ "$1" = -- ]; then + shift + fi + + _gnu_stat_readlink "$@" || _bsd_stat_readlink "$@" +} + +_gnu_stat_readlink() { + local output + output=$(stat -c %N -- "$1" 2>/dev/null) && + + printf '%s\n' "$output" | + sed "s/^‘[^’]*’ -> ‘\(.*\)’/\1/ + s/^'[^']*' -> '\(.*\)'/\1/" + # FIXME: handle newlines +} + +_bsd_stat_readlink() { + stat -f %Y -- "$1" 2>/dev/null +} + +#### + TYPE="" SNAPNAME="" SYMSTORE="" SKIPCOMPILE="" -LLVM_ARM32=$(readlink -f $(dirname $0)/support/llvm_arm32) -LLVM_ARM64=$(readlink -f $(dirname $0)/support/llvm_arm64) +LLVM_ARM32=$(realpath $(dirname $0)/support/llvm_arm32) +LLVM_ARM64=$(realpath $(dirname $0)/support/llvm_arm64) native_path() { if echo "${1}" | grep -q :; then @@ -52,12 +190,12 @@ while [[ $# -gt 0 ]]; do ;; --llvm_arm32) - LLVM_ARM32="$(readlink -f "$2")" + LLVM_ARM32="$(realpath "$2")" shift shift ;; --llvm_arm64) - LLVM_ARM64="$(readlink -f "$2")" + LLVM_ARM64="$(realpath "$2")" shift shift ;; @@ -108,11 +246,11 @@ export LLVM_ARM32; export LLVM_ARM64; # Ensure we're in the root directory where this script is -export BUILD_ROOT=$(dirname $(readlink -f $0)) +export BUILD_ROOT=$(dirname $(realpath $0)) cd "${BUILD_ROOT}" -export REPO_ROOT=$(readlink -f "$(pwd)/../..") +export REPO_ROOT=$(realpath "$(pwd)/../..") if [ ! -f "${REPO_ROOT}"/renderdoc.sln ]; then echo "Script misconfiguration - expected root of repository in '$REPO_ROOT'"; @@ -136,6 +274,10 @@ if uname -a | grep -qiE 'msys|cygwin|microsoft'; then fi fi +if [[ "$PLATFORM" == "Darwin" ]]; then + PLATFORM=macOS +fi + export PLATFORM; export WIN_ROOT; @@ -171,7 +313,7 @@ fi cd "${BUILD_ROOT}" # Do some windows-specific build steps, like binary signing and symbol server processing -if [ "$PLATFORM" != "Linux" ]; then +if [[ "$PLATFORM" == "Windows" ]]; then cd "${BUILD_ROOT}" diff --git a/util/buildscripts/scripts/compile.sh b/util/buildscripts/scripts/compile.sh index 474cc4186..adb485d6b 100755 --- a/util/buildscripts/scripts/compile.sh +++ b/util/buildscripts/scripts/compile.sh @@ -6,6 +6,10 @@ if [ "$PLATFORM" == "Linux" ]; then ./scripts/compile_linux.sh +elif [ "$PLATFORM" == "macOS" ]; then + + ./scripts/compile_macos.sh + else ./scripts/compile_win32.sh diff --git a/util/buildscripts/scripts/compile_linux.sh b/util/buildscripts/scripts/compile_linux.sh index bc6881262..840d5fcb3 100755 --- a/util/buildscripts/scripts/compile_linux.sh +++ b/util/buildscripts/scripts/compile_linux.sh @@ -64,31 +64,53 @@ if [ ! -d $LLVM_ARM32 ] || [ ! -d $LLVM_ARM64 ] ; then exit 0; fi -# Build the arm32 variant -mkdir build-android-arm32 -pushd build-android-arm32 +AAPT=$(ls $ANDROID_SDK/build-tools/*/aapt 2>/dev/null | tail -n 1) -cmake -DBUILD_ANDROID=1 -DANDROID_ABI=armeabi-v7a -DANDROID_NATIVE_API_LEVEL=23 -DCMAKE_BUILD_TYPE=Release -DSTRIP_ANDROID_LIBRARY=On -DLLVM_DIR=$LLVM_ARM32/lib/cmake/llvm -DUSE_INTERCEPTOR_LIB=On -DCMAKE_MAKE_PROGRAM=make .. -make -j8 +# Check to see if we already have this built, and don't rebuild +VERSION32=$($AAPT dump badging build-android-arm32/bin/*apk 2>/dev/null | grep -Eo "versionName='[0-9a-f]*'" | grep -Eo "'.*'" | tr -d "'") +VERSION64=$($AAPT dump badging build-android-arm64/bin/*apk 2>/dev/null | grep -Eo "versionName='[0-9a-f]*'" | grep -Eo "'.*'" | tr -d "'") + +if [ "$VERSION32" == "$GITTAG" ]; then + + echo "Found existing compatible arm32 build at $GITTAG, not rebuilding"; + +else + + # Build the arm32 variant + mkdir build-android-arm32 + pushd build-android-arm32 + + cmake -DBUILD_ANDROID=1 -DANDROID_ABI=armeabi-v7a -DANDROID_NATIVE_API_LEVEL=23 -DCMAKE_BUILD_TYPE=Release -DSTRIP_ANDROID_LIBRARY=On -DLLVM_DIR=$LLVM_ARM32/lib/cmake/llvm -DUSE_INTERCEPTOR_LIB=On -DCMAKE_MAKE_PROGRAM=make .. + make -j8 + + if ! ls bin/*.apk; then + echo "Android build failed" + exit 0; + fi + + popd # build-android-arm32 -if ! ls bin/*.apk; then - echo "Android build failed" - exit 0; fi -popd # build-android-arm32 +if [ "$VERSION64" == "$GITTAG" ]; then -mkdir build-android-arm64 -pushd build-android-arm64 + echo "Found existing compatible arm64 build at $GITTAG, not rebuilding"; -cmake -DBUILD_ANDROID=1 -DANDROID_ABI=arm64-v8a -DANDROID_NATIVE_API_LEVEL=23 -DCMAKE_BUILD_TYPE=Release -DSTRIP_ANDROID_LIBRARY=On -DLLVM_DIR=$LLVM_ARM64/lib/cmake/llvm -DUSE_INTERCEPTOR_LIB=On -DCMAKE_MAKE_PROGRAM=make .. -make -j8 +else + + mkdir build-android-arm64 + pushd build-android-arm64 + + cmake -DBUILD_ANDROID=1 -DANDROID_ABI=arm64-v8a -DANDROID_NATIVE_API_LEVEL=23 -DCMAKE_BUILD_TYPE=Release -DSTRIP_ANDROID_LIBRARY=On -DLLVM_DIR=$LLVM_ARM64/lib/cmake/llvm -DUSE_INTERCEPTOR_LIB=On -DCMAKE_MAKE_PROGRAM=make .. + make -j8 + + if ! ls bin/*.apk; then + echo "Android build failed" + exit 0; + fi + + popd # build-android-arm64 -if ! ls bin/*.apk; then - echo "Android build failed" - exit 0; fi -popd # build-android-arm64 - popd # $REPO_ROOT diff --git a/util/buildscripts/scripts/compile_macos.sh b/util/buildscripts/scripts/compile_macos.sh new file mode 100755 index 000000000..daa3002d3 --- /dev/null +++ b/util/buildscripts/scripts/compile_macos.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +# create pushd into the build folder +pushd "${REPO_ROOT}" + +mkdir -p build +pushd build + +cmake -DCMAKE_BUILD_TYPE=Release .. +make -j4 + +popd # build + +# Build android libraries and apks +export PATH=$PATH:$ANDROID_SDK/tools/ + +# Check that we're set up to build for android +if [ ! -d $ANDROID_SDK/tools ] ; then + echo "\$ANDROID_SDK is not correctly configured: '$ANDROID_SDK'" + exit 0; +fi + +if [ ! -d $LLVM_ARM32 ] || [ ! -d $LLVM_ARM64 ] ; then + echo "llvm is not available, expected $LLVM_ARM32 and $LLVM_ARM64 respectively." + exit 0; +fi + +AAPT=$(ls $ANDROID_SDK/build-tools/*/aapt 2>/dev/null | tail -n 1) + +# Check to see if we already have this built, and don't rebuild +VERSION32=$($AAPT dump badging build-android-arm32/bin/*apk 2>/dev/null | grep -Eo "versionName='[0-9a-f]*'" | grep -Eo "'.*'" | tr -d "'") +VERSION64=$($AAPT dump badging build-android-arm64/bin/*apk 2>/dev/null | grep -Eo "versionName='[0-9a-f]*'" | grep -Eo "'.*'" | tr -d "'") + +if [ "$VERSION32" == "$GITTAG" ]; then + + echo "Found existing compatible arm32 build at $GITTAG, not rebuilding"; + +else + + # Build the arm32 variant + mkdir build-android-arm32 + pushd build-android-arm32 + + cmake -DBUILD_ANDROID=1 -DANDROID_ABI=armeabi-v7a -DANDROID_NATIVE_API_LEVEL=23 -DCMAKE_BUILD_TYPE=Release -DSTRIP_ANDROID_LIBRARY=On -DLLVM_DIR=$LLVM_ARM32/lib/cmake/llvm -DUSE_INTERCEPTOR_LIB=On -DCMAKE_MAKE_PROGRAM=make .. + make -j4 + + if ! ls bin/*.apk; then + echo "Android build failed" + exit 0; + fi + + popd # build-android-arm32 + +fi + +if [ "$VERSION64" == "$GITTAG" ]; then + + echo "Found existing compatible arm64 build at $GITTAG, not rebuilding"; + +else + + mkdir build-android-arm64 + pushd build-android-arm64 + + cmake -DBUILD_ANDROID=1 -DANDROID_ABI=arm64-v8a -DANDROID_NATIVE_API_LEVEL=23 -DCMAKE_BUILD_TYPE=Release -DSTRIP_ANDROID_LIBRARY=On -DLLVM_DIR=$LLVM_ARM64/lib/cmake/llvm -DUSE_INTERCEPTOR_LIB=On -DCMAKE_MAKE_PROGRAM=make .. + make -j4 + + if ! ls bin/*.apk; then + echo "Android build failed" + exit 0; + fi + + popd # build-android-arm64 + +fi + +popd # $REPO_ROOT/build diff --git a/util/buildscripts/scripts/make_package.sh b/util/buildscripts/scripts/make_package.sh index 2da2c0e1c..3531f7b52 100755 --- a/util/buildscripts/scripts/make_package.sh +++ b/util/buildscripts/scripts/make_package.sh @@ -6,6 +6,10 @@ if [ "$PLATFORM" == "Linux" ]; then ./scripts/make_package_linux.sh $1 +elif [ "$PLATFORM" == "macOS" ]; then + + ./scripts/make_package_macos.sh $1 + else ./scripts/make_package_win32.sh $1 diff --git a/util/buildscripts/scripts/make_package_macos.sh b/util/buildscripts/scripts/make_package_macos.sh new file mode 100755 index 000000000..01950c416 --- /dev/null +++ b/util/buildscripts/scripts/make_package_macos.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +FILENAME="$1" + +if [ $# -ne 1 ]; then + echo "Usage: $0 FILENAME"; + exit; +fi + +if [ ! -f "${REPO_ROOT}"/build/bin/qrenderdoc.app/Contents/MacOS/qrenderdoc ] || [ ! -f "${REPO_ROOT}"/build/bin/renderdoccmd ]; then + echo "ERROR: Missing qrenderdoc.app or renderdoccmd builds"; + exit 1; +fi + +if ! which convert > /dev/null 2>&1; then + echo "ERROR: Require imagemagick for packaging step"; + echo " brew install imagemagick"; + exit 1; +fi + +if ! which create-dmg > /dev/null 2>&1; then + echo "ERROR: Require create-dmg for packaging step"; + echo " brew install create-dmg"; + exit 1; +fi + +# create final bundle folder +mkdir -p "${REPO_ROOT}"/dist/RenderDoc.app + +# copy in qrenderdoc bundle +cp -R "${REPO_ROOT}"/build/bin/qrenderdoc.app/* "${REPO_ROOT}"/dist/RenderDoc.app/ + +# copy in renderdoccmd +cp "${REPO_ROOT}"/build/bin/renderdoccmd "${REPO_ROOT}"/dist/RenderDoc.app/Contents/MacOS/ + +# copy in plugins +if [ -d "${REPO_ROOT}"/plugins-macos ]; then + cp -R "${REPO_ROOT}"/plugins-macos "${REPO_ROOT}/dist/RenderDoc.app/Contents/plugins" +else + echo "WARNING: Plugins not present. Download and extract https://renderdoc.org/plugins.tgz in root folder"; +fi + +# copy in all of the android files. +mkdir -p "${REPO_ROOT}/dist/RenderDoc.app/Contents/plugins/android/" + +if ls "${REPO_ROOT}"/build-android*/bin/*.apk; then + cp "${REPO_ROOT}"/build-android*/bin/*.apk "${REPO_ROOT}/dist/RenderDoc.app/Contents/plugins/android/" +else + echo "WARNING: Android build not present. Build arm32 and arm64 apks in build-android-arm{32,64} folders"; +fi + +# Create dmg background image +convert -size 600x300 xc:white \ + -fill '#3BB779' -draw "rectangle 0,0 600,100" \ + -fill white -pointsize 24 -gravity north \ + -annotate +0+50 "Drag qrenderdoc to your Applications folder." \ + /tmp/rdbackground.png + +rm -rf "${REPO_ROOT}"/package +mkdir "${REPO_ROOT}"/package + +create-dmg --volname "$FILENAME" \ + --volicon "${REPO_ROOT}"/dist/RenderDoc.app/Contents/Resources/RenderDoc.icns \ + --background /tmp/rdbackground.png \ + --window-pos 200 120 --window-size 600 350 --icon-size 100 \ + --icon RenderDoc.app 200 190 \ + --app-drop-link 400 185 \ + "${REPO_ROOT}"/package/"${FILENAME}".dmg "${REPO_ROOT}"/dist/ +