diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fdfe9eaf..7d220a032 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ IF(POLICY CMP0067) CMAKE_POLICY(SET CMP0067 NEW) ENDIF() +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version") + PROJECT(fish) # We are C++11. @@ -163,10 +165,26 @@ ADD_DEFINITIONS(-D_REENTRANT) # Set up PCRE2 INCLUDE(cmake/PCRE2.cmake) +# Code signing ID on Mac. A default '-' is ad-hoc codesign. +SET(MAC_CODESIGN_ID "-" CACHE STRING "Mac code-signing identity") + +FUNCTION(CODESIGN_ON_MAC target) + IF(APPLE) + ADD_CUSTOM_COMMAND( + TARGET ${target} + POST_BUILD + COMMAND codesign --force --deep --options runtime --sign "${MAC_CODESIGN_ID}" $ + VERBATIM + ) + ENDIF() +ENDFUNCTION(CODESIGN_ON_MAC target) + + # Define a function to link dependencies. -FUNCTION(FISH_LINK_DEPS target) +FUNCTION(FISH_LINK_DEPS_AND_SIGN target) TARGET_LINK_LIBRARIES(${target} fishlib) -ENDFUNCTION(FISH_LINK_DEPS) + CODESIGN_ON_MAC(${target}) +ENDFUNCTION(FISH_LINK_DEPS_AND_SIGN) # Define libfish.a. ADD_LIBRARY(fishlib STATIC ${FISH_SRCS}) @@ -177,17 +195,17 @@ TARGET_LINK_LIBRARIES(fishlib # Define fish. ADD_EXECUTABLE(fish src/fish.cpp) -FISH_LINK_DEPS(fish) +FISH_LINK_DEPS_AND_SIGN(fish) # Define fish_indent. ADD_EXECUTABLE(fish_indent src/fish_indent.cpp src/print_help.cpp) -FISH_LINK_DEPS(fish_indent) +FISH_LINK_DEPS_AND_SIGN(fish_indent) # Define fish_key_reader. ADD_EXECUTABLE(fish_key_reader src/fish_key_reader.cpp src/print_help.cpp) -FISH_LINK_DEPS(fish_key_reader) +FISH_LINK_DEPS_AND_SIGN(fish_key_reader) # Set up the docs. INCLUDE(cmake/Docs.cmake) diff --git a/build_tools/mac_notarize.sh b/build_tools/mac_notarize.sh new file mode 100755 index 000000000..c58b7b47b --- /dev/null +++ b/build_tools/mac_notarize.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash + +# Helper to notarize an .app.zip or .pkg file. +# Based on https://www.logcg.com/en/archives/3222.html + +set -e + +die() { echo "$*" 1>&2 ; exit 1; } + +check_status() { + echo "STATUS" $1 +} + +get_req_uuid() { + RESPONSE=$(&1 | + tee -a "$LOGFILE" | + get_req_uuid) + +test -z "$NOTARIZE_UUID" && cat "$LOGFILE" && die "Could not get RequestUUID" +echo "RequestUUID: $NOTARIZE_UUID" + +success=0 +for i in $(seq 20); do + echo "Checking progress..." + PROGRESS=$(xcrun altool --notarization-info "${NOTARIZE_UUID}" \ + -u "$AC_USER" \ + -p "$AC_PASS" 2>&1 | + tee -a "$LOGFILE") + echo "${PROGRESS}" | tail -n 1 + + if [ $? -ne 0 ] || [[ "${PROGRESS}" =~ "Invalid" ]] ; then + echo "Error with notarization. Exiting" + break + fi + + if ! [[ "${PROGRESS}" =~ "in progress" ]]; then + success=1 + break + else + echo "Not completed yet. Sleeping for 30 seconds." + fi + sleep 30 +done + +if [ $success -eq 1 ] ; then + if test "$ext" = "zip"; then + TMPDIR=$(mktemp -d) + echo "Extracting to $TMPDIR" + unzip -q "$INPUT" -d "$TMPDIR" + # Force glob expansion. + STAPLE_TARGET="$TMPDIR"/* + STAPLE_TARGET=$(echo $STAPLE_TARGET) + else + STAPLE_TARGET="$INPUT" + fi + echo "Stapling $STAPLE_TARGET" + xcrun stapler staple "$STAPLE_TARGET" + + if test "$ext" = "zip"; then + # Zip it back up. + INPUT_FULL=$(realpath "$INPUT") + rm -f "$INPUT" + cd "$(dirname "$STAPLE_TARGET")" + zip -r -q "$INPUT_FULL" $(basename "$STAPLE_TARGET") + fi +fi +echo "Processed $INPUT" + +if test "$ext" = "zip"; then + spctl -a -v "$STAPLE_TARGET" +fi diff --git a/build_tools/make_pkg.sh b/build_tools/make_pkg.sh index 8d07562db..edd17747a 100755 --- a/build_tools/make_pkg.sh +++ b/build_tools/make_pkg.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # Script to produce an OS X installer .pkg and .app(.zip) @@ -17,19 +17,23 @@ set -x #Exit on error set -e +# Respect MAC_CODESIGN_ID and MAC_PRODUCTSIGN_ID, or default for ad-hoc. +# Note the :- means "or default" and the following - is the value. +MAC_CODESIGN_ID=${MAC_CODESIGN_ID:--} +MAC_PRODUCTSIGN_ID=${MAC_PRODUCTSIGN_ID:--} + PKGDIR=$(mktemp -d) SRC_DIR=$PWD OUTPUT_PATH=${FISH_ARTEFACT_PATH:-~/fish_built} mkdir -p "$PKGDIR/build" "$PKGDIR/root" "$PKGDIR/intermediates" "$PKGDIR/dst" -{ cd "$PKGDIR/build" && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo "$SRC_DIR" && make -j 4 && env DESTDIR="$PKGDIR/root/" make install; } +{ cd "$PKGDIR/build" && cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DMAC_CODESIGN_ID="${MAC_CODESIGN_ID}" "$SRC_DIR" && make -j 12 && env DESTDIR="$PKGDIR/root/" make install; } pkgbuild --scripts "$SRC_DIR/build_tools/osx_package_scripts" --root "$PKGDIR/root/" --identifier 'com.ridiculousfish.fish-shell-pkg' --version "$VERSION" "$PKGDIR/intermediates/fish.pkg" - productbuild --package-path "$PKGDIR/intermediates" --distribution "$SRC_DIR/build_tools/osx_distribution.xml" --resources "$SRC_DIR/build_tools/osx_package_resources/" "$OUTPUT_PATH/fish-$VERSION.pkg" - +productsign --sign "${MAC_PRODUCTSIGN_ID}" "$OUTPUT_PATH/fish-$VERSION.pkg" "$OUTPUT_PATH/fish-$VERSION-signed.pkg" && mv "$OUTPUT_PATH/fish-$VERSION-signed.pkg" "$OUTPUT_PATH/fish-$VERSION.pkg" # Make the app -{ cd "$PKGDIR/build" && make fish_macapp && zip -r "$OUTPUT_PATH/fish-$VERSION.app.zip" fish.app; } +{ cd "$PKGDIR/build" && make signed_fish_macapp && zip -r "$OUTPUT_PATH/fish-$VERSION.app.zip" fish.app; } rm -r "$PKGDIR" diff --git a/cmake/MacApp.cmake b/cmake/MacApp.cmake index 6ae1622e7..e2959f84e 100644 --- a/cmake/MacApp.cmake +++ b/cmake/MacApp.cmake @@ -55,4 +55,21 @@ ADD_CUSTOM_COMMAND(TARGET fish_macapp POST_BUILD --build ${CMAKE_CURRENT_BINARY_DIR} --target install COMMAND ${CMAKE_COMMAND} -E copy_directory ${MACAPP_FISH_BUILDROOT}/.. $/Resources/ + VERBATIM +) + +# The entitlements file. +SET(MACAPP_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/osx/MacApp.entitlements") + +# Target to sign the macapp. +# Note that a POST_BUILD step happens before resources are copied, +# and therefore would be too early. +ADD_CUSTOM_TARGET(signed_fish_macapp + DEPENDS fish_macapp "${MACAPP_ENTITLEMENTS}" + COMMAND codesign --force --deep + --options runtime + --entitlements "${MACAPP_ENTITLEMENTS}" + --sign "${MAC_CODESIGN_ID}" + $ + VERBATIM ) diff --git a/cmake/PCRE2.cmake b/cmake/PCRE2.cmake index 23f483551..9121916d0 100644 --- a/cmake/PCRE2.cmake +++ b/cmake/PCRE2.cmake @@ -7,8 +7,10 @@ SET(PCRE2_BUILD_PCRE2GREP OFF CACHE BOOL "Build pcre2grep") SET(PCRE2_MIN_VERSION 10.21) -FIND_LIBRARY(PCRE2_LIB pcre2-${PCRE2_WIDTH}) -FIND_PATH(PCRE2_INCLUDE_DIR pcre2.h) +IF (NOT APPLE) + FIND_LIBRARY(PCRE2_LIB pcre2-${PCRE2_WIDTH}) + FIND_PATH(PCRE2_INCLUDE_DIR pcre2.h) +ENDIF() IF (PCRE2_LIB AND PCRE2_INCLUDE_DIR) MESSAGE(STATUS "Found system PCRE2 library ${PCRE2_INCLUDE_DIR}") ELSE() @@ -16,5 +18,5 @@ ELSE() ADD_SUBDIRECTORY(pcre2-10.32 EXCLUDE_FROM_ALL) SET(PCRE2_INCLUDE_DIR ${CMAKE_BINARY_DIR}/pcre2-10.32/) SET(PCRE2_LIB pcre2-${PCRE2_WIDTH}) -endif(PCRE2_LIB AND PCRE2_INCLUDE_DIR) +ENDIF(PCRE2_LIB AND PCRE2_INCLUDE_DIR) INCLUDE_DIRECTORIES(${PCRE2_INCLUDE_DIR}) diff --git a/cmake/Tests.cmake b/cmake/Tests.cmake index cc61bc837..f12465133 100644 --- a/cmake/Tests.cmake +++ b/cmake/Tests.cmake @@ -1,7 +1,7 @@ # Define fish_tests. ADD_EXECUTABLE(fish_tests EXCLUDE_FROM_ALL src/fish_tests.cpp) -FISH_LINK_DEPS(fish_tests) +FISH_LINK_DEPS_AND_SIGN(fish_tests) # The "test" directory. SET(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/test) diff --git a/osx/MacApp.entitlements b/osx/MacApp.entitlements new file mode 100644 index 000000000..49ad0bb09 --- /dev/null +++ b/osx/MacApp.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.automation.apple-events + + +