Support Apple Silicon on macOS
As part of supporting Apple Silicon, we've got to upgrade our embedded Python to a version that comes with an Apple Silicon build. Python 3.9 suffices. This means we ignore python3.9 while fixing up bundles. Apple requires all code to be signed on Apple Silicon. We've added signing to the build. This has to be run after anything that adds to or modifies the installed files. As of Cmake 3.14 (CMP0082), the install rules are run in the order declared, so we are able to do this just by adding the signing subdirectory last in the main CMakeLists.txt. By default, the build will be signed "ad hoc", which does not require a developer to create keys or get keys from Apple. We added some CMake variables to control signing, KICAD_OSX_CODESIGN and KICAD_OSX_SIGNING_*. In order to better support development, we've added some necessary cleanup steps to KiCad that were performed externally in the release and nightly build process, like removing any .pyc files and extra Python symlinks erroneously introduced by fixup_bundle. We also adjusted "refix_rpaths" to be more accurate. We should not need "wrangle_bundle" when building and installing a local development copy of KiCad.
This commit is contained in:
parent
91290e8f75
commit
98775afcba
|
@ -1059,3 +1059,24 @@ endif ( KICAD_INSTALL_DEMOS )
|
||||||
if( KICAD_BUILD_I18N )
|
if( KICAD_BUILD_I18N )
|
||||||
add_subdirectory( translation )
|
add_subdirectory( translation )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if( APPLE )
|
||||||
|
set( KICAD_OSX_CODESIGN ON
|
||||||
|
CACHE BOOL "Sign KiCad.app on macOS" FORCE )
|
||||||
|
set( KICAD_OSX_SIGNING_ID "-"
|
||||||
|
CACHE STRING "macOS Signing ID, defaults to ad-hoc" FORCE )
|
||||||
|
set( KICAD_OSX_SIGNING_USE_SECURE_TIMESTAMP OFF
|
||||||
|
CACHE BOOL "When signing on macOS, add a secure timestamp" FORCE )
|
||||||
|
set( KICAD_OSX_SIGNING_USE_HARDENED_RUNTIME OFF
|
||||||
|
CACHE BOOL "When signing on macOS, use the Hardened Runtime" FORCE )
|
||||||
|
set( KICAD_OSX_SIGNING_ENTITLEMENTS_FILE ""
|
||||||
|
CACHE FILEPATH "Path to entitlements file for macOS signing" FORCE )
|
||||||
|
|
||||||
|
# We have to sign the app bundle after *all* the files are copied in the bundle
|
||||||
|
# otherwise the signature will be invalid.
|
||||||
|
|
||||||
|
# As of CMP0082 (CMake 3.14), the install rules are run in order, so we can just
|
||||||
|
# declare it last.
|
||||||
|
|
||||||
|
add_subdirectory( signing )
|
||||||
|
endif()
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
# This is not intended to make an install completely
|
# This is not intended to make an install completely
|
||||||
# redistributable and relocatable.
|
# redistributable and relocatable.
|
||||||
|
|
||||||
# TODO: Check style things
|
|
||||||
|
|
||||||
function( refix_kicad_bundle target )
|
function( refix_kicad_bundle target )
|
||||||
# target should be the path to the kicad.app directory
|
# target should be the path to the kicad.app directory
|
||||||
|
|
||||||
|
@ -56,6 +54,10 @@ function( refix_kicad_bundle target )
|
||||||
refix_prereqs( ${binary} )
|
refix_prereqs( ${binary} )
|
||||||
endforeach( )
|
endforeach( )
|
||||||
|
|
||||||
|
message( "Removing Python pyc files" )
|
||||||
|
file( GLOB_RECURSE pycs ${target}/*.pyc )
|
||||||
|
file( REMOVE ${pycs} )
|
||||||
|
|
||||||
string( TIMESTAMP end_time )
|
string( TIMESTAMP end_time )
|
||||||
# message( "Refixing start time: ${start_time}\nRefixing end time: ${end_time}" )
|
# message( "Refixing start time: ${start_time}\nRefixing end time: ${end_time}" )
|
||||||
endfunction( )
|
endfunction( )
|
||||||
|
@ -63,6 +65,10 @@ endfunction( )
|
||||||
function( cleanup_python bundle)
|
function( cleanup_python bundle)
|
||||||
# Remove extra Python
|
# Remove extra Python
|
||||||
file( REMOVE_RECURSE ${bundle}/Contents/MacOS/Python )
|
file( REMOVE_RECURSE ${bundle}/Contents/MacOS/Python )
|
||||||
|
file( GLOB extra_pythons LIST_DIRECTORIES true ${bundle}/Contents/Applications/*/Contents/MacOS/Python )
|
||||||
|
message( "Removing extra Pythons copied into Contents/MacOS: ${extra_pythons}" )
|
||||||
|
file( REMOVE_RECURSE ${extra_pythons} )
|
||||||
|
|
||||||
# Make sure Python's Current is a symlink to 3.x
|
# Make sure Python's Current is a symlink to 3.x
|
||||||
file( REMOVE_RECURSE ${bundle}/Contents/Frameworks/Python.framework/Versions/Current )
|
file( REMOVE_RECURSE ${bundle}/Contents/Frameworks/Python.framework/Versions/Current )
|
||||||
file( GLOB python_version LIST_DIRECTORIES true RELATIVE ${bundle}/Contents/Frameworks/Python.framework/Versions ${bundle}/Contents/Frameworks/Python.framework/Versions/3* )
|
file( GLOB python_version LIST_DIRECTORIES true RELATIVE ${bundle}/Contents/Frameworks/Python.framework/Versions ${bundle}/Contents/Frameworks/Python.framework/Versions/3* )
|
||||||
|
@ -135,7 +141,7 @@ function( refix_prereqs target )
|
||||||
if( "${candidate}" MATCHES "${gp_regex}" )
|
if( "${candidate}" MATCHES "${gp_regex}" )
|
||||||
string( REGEX REPLACE "${otool_regex}" "\\1" raw_prereq "${candidate}" )
|
string( REGEX REPLACE "${otool_regex}" "\\1" raw_prereq "${candidate}" )
|
||||||
|
|
||||||
if ( raw_prereq MATCHES "^@executable_path/\\.\\./\\.\\./.*/Contents/MacOS/Python$" )
|
if ( raw_prereq MATCHES "^@executable_path/\\.\\./\\.\\./Contents/MacOS/Python$" )
|
||||||
set( changed_prereq "@rpath/Versions/Current/Python" )
|
set( changed_prereq "@rpath/Versions/Current/Python" )
|
||||||
elseif ( raw_prereq MATCHES "^@executable_path/\\.\\./Frameworks/" )
|
elseif ( raw_prereq MATCHES "^@executable_path/\\.\\./Frameworks/" )
|
||||||
string( REPLACE "@executable_path/../Frameworks/"
|
string( REPLACE "@executable_path/../Frameworks/"
|
||||||
|
@ -177,4 +183,4 @@ function( refix_prereqs target )
|
||||||
message( FATAL_ERROR "Command failed:\n ${msg}" )
|
message( FATAL_ERROR "Command failed:\n ${msg}" )
|
||||||
endif( )
|
endif( )
|
||||||
endif( )
|
endif( )
|
||||||
endfunction( )
|
endfunction( )
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
|
||||||
|
function( sign_kicad_bundle target signing_id use_secure_timestamp use_hardened_runtime entitlements_file)
|
||||||
|
|
||||||
|
# If the signing ID wasn't passed in, use - which means adhoc signing
|
||||||
|
if ( NOT signing_id )
|
||||||
|
set( signing_id "-")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
MESSAGE( STATUS "Signing ${target} with ${signing_id}, hardened runtime: ${use_hardened_runtime}, secure timestamp: ${use_secure_timestamp}, entitlements file: ${entitlements_file}" )
|
||||||
|
|
||||||
|
# --deep doesn't really work and is officially deprecated as of macos 13
|
||||||
|
# https://developer.apple.com/library/archive/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG201
|
||||||
|
|
||||||
|
# collect a list of things to sign, in order
|
||||||
|
set( sign_list "${target}/Contents/Applications/eeschema.app/Contents/MacOS/eeschema"
|
||||||
|
"${target}/Contents/Applications/eeschema.app"
|
||||||
|
"${target}/Contents/Applications/gerbview.app/Contents/MacOS/gerbview"
|
||||||
|
"${target}/Contents/Applications/gerbview.app" "${target}/Contents/Applications/pcbnew.app/Contents/MacOS/pcbnew" "${target}/Contents/Applications/pcbnew.app" "${target}/Contents/Applications/bitmap2component.app/Contents/MacOS/bitmap2component" "${target}/Contents/Applications/bitmap2component.app" "${target}/Contents/Applications/pcb_calculator.app/Contents/MacOS/pcb_calculator" "${target}/Contents/Applications/pcb_calculator.app" "${target}/Contents/Applications/pl_editor.app/Contents/MacOS/pl_editor" "${target}/Contents/Applications/pl_editor.app")
|
||||||
|
|
||||||
|
# Python things!
|
||||||
|
if( EXISTS "${target}/Contents/Frameworks/Python.framework" )
|
||||||
|
set( sign_list ${sign_list} "${target}/Contents/Frameworks/Python.framework/Versions/Current/share/doc/python3.9/examples/Tools/pynche"
|
||||||
|
"${target}/Contents/Frameworks/Python.framework/Versions/Current/Resources/Python.app/Contents/MacOS/Python")
|
||||||
|
file( GLOB python_bins "${target}/Contents/Frameworks/Python.framework/Versions/Current/bin/*" )
|
||||||
|
|
||||||
|
# add dylib, .so and .a files from Contents/Frameworks/Python.framework/Versions/Current/lib/ and recursively
|
||||||
|
file( GLOB_RECURSE python_libs ${sign_list} "${target}/Contents/Frameworks/Python.framework/Versions/Current/lib/*.dylib"
|
||||||
|
"${target}/Contents/Frameworks/Python.framework/Versions/Current/lib/*.so"
|
||||||
|
"${target}/Contents/Frameworks/Python.framework/Versions/Current/lib/*.a"
|
||||||
|
"${target}/Contents/Frameworks/Python.framework/Versions/Current/lib/*.o" )
|
||||||
|
|
||||||
|
set( sign_list ${sign_list} ${python_bins} ${python_libs} )
|
||||||
|
endif( )
|
||||||
|
|
||||||
|
set( sign_list ${sign_list} "${target}/Contents/Frameworks/Python.framework/Versions/Current/Resources/Python.app"
|
||||||
|
"${target}/Contents/Frameworks/Python.framework" )
|
||||||
|
|
||||||
|
# add all the dylibs from contents/frameworks
|
||||||
|
file( GLOB framework_dylibs "${target}/Contents/Frameworks/*.dylib" )
|
||||||
|
|
||||||
|
# add all the files in Contents/PlugIns
|
||||||
|
file( GLOB_RECURSE plugins "${target}/Contents/PlugIns/*" )
|
||||||
|
|
||||||
|
file( GLOB_RECURSE translations "${target}/Contents/SharedSupport/internat/*.mo" )
|
||||||
|
|
||||||
|
# add all the files in Contents/MacOS/
|
||||||
|
# But we've gotta sign kicad-cli before signing kicad, at least on x86_64
|
||||||
|
set( kicad_bins "${target}/Contents/MacOS/dxf2idf"
|
||||||
|
"${target}/Contents/MacOS/idf2vrml"
|
||||||
|
"${target}/Contents/MacOS/idfcyl"
|
||||||
|
"${target}/Contents/MacOS/idfrect"
|
||||||
|
"${target}/Contents/MacOS/kicad-cli"
|
||||||
|
"${target}/Contents/MacOS/kicad")
|
||||||
|
|
||||||
|
set( sign_list ${sign_list} ${framework_dylibs} ${plugins} ${translations} ${kicad_bins} ) # do i need to quote this differently?
|
||||||
|
|
||||||
|
# add kicad.app!
|
||||||
|
set( sign_list ${sign_list} "${target}" )
|
||||||
|
|
||||||
|
# build the command used for signing
|
||||||
|
set( command codesign --force --sign "${signing_id}" )
|
||||||
|
|
||||||
|
if( use_secure_timestamp )
|
||||||
|
set( command ${command} --timestamp )
|
||||||
|
endif( )
|
||||||
|
|
||||||
|
if( use_hardened_runtime )
|
||||||
|
if ( signing_id STREQUAL "-" )
|
||||||
|
message( FATAL_ERROR "Hardened runtime requires a (non-ad-hoc) signing identity." )
|
||||||
|
endif( )
|
||||||
|
|
||||||
|
set( command ${command} --options runtime )
|
||||||
|
endif( )
|
||||||
|
|
||||||
|
if( entitlements_file )
|
||||||
|
set( command ${command} --entitlements "${entitlements_file}" )
|
||||||
|
endif( )
|
||||||
|
|
||||||
|
foreach( item ${sign_list} )
|
||||||
|
set( cmd ${command} "${item}" )
|
||||||
|
|
||||||
|
# MESSAGE( STATUS "Running ${cmd}")
|
||||||
|
execute_process( COMMAND ${cmd}
|
||||||
|
RESULT_VARIABLE codesign_result)
|
||||||
|
|
||||||
|
if( NOT codesign_result EQUAL 0 )
|
||||||
|
message( FATAL_ERROR "macOS signing failed; ran ${cmd}" )
|
||||||
|
endif( )
|
||||||
|
endforeach( )
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
|
||||||
|
function( verify_signing target )
|
||||||
|
set( cmd codesign --verify --deep --strict --verbose=3 "${target}" )
|
||||||
|
|
||||||
|
execute_process( COMMAND ${cmd} RESULT_VARIABLE verify_result )
|
||||||
|
if( NOT verify_result EQUAL 0 )
|
||||||
|
message( FATAL_ERROR "macOS signing verification failed; ran ${cmd}" )
|
||||||
|
endif( )
|
||||||
|
endfunction( )
|
|
@ -248,7 +248,7 @@ if( APPLE )
|
||||||
fixup_bundle( ${OSX_BUNDLE_INSTALL_BIN_DIR}/kicad
|
fixup_bundle( ${OSX_BUNDLE_INSTALL_BIN_DIR}/kicad
|
||||||
\"\${BUNDLE_FIX_LIBS}\"
|
\"\${BUNDLE_FIX_LIBS}\"
|
||||||
\"\${BUNDLE_FIX_DIRS};${PYTHON_FRAMEWORK}\"
|
\"\${BUNDLE_FIX_DIRS};${PYTHON_FRAMEWORK}\"
|
||||||
IGNORE_ITEM \"Python;python;python3;python3.8;pythonw;pythonw3;pythonw3.8\"
|
IGNORE_ITEM \"Python;python;pythonw;python3;pythonw3;python3.8;pythonw3.8;python3.9;python3.9-intel64\"
|
||||||
)
|
)
|
||||||
|
|
||||||
# BundleUtilities clobbers the rpaths and install_names that we carefully setup in Python.framework, even if
|
# BundleUtilities clobbers the rpaths and install_names that we carefully setup in Python.framework, even if
|
||||||
|
@ -295,7 +295,7 @@ if( APPLE )
|
||||||
|
|
||||||
if ( ${PYTHON_FRAMEWORK_HELPER} )
|
if ( ${PYTHON_FRAMEWORK_HELPER} )
|
||||||
include( ${CMAKE_MODULE_PATH}/RefixupMacOS.cmake )
|
include( ${CMAKE_MODULE_PATH}/RefixupMacOS.cmake )
|
||||||
refix_kicad_bundle(${OSX_BUNDLE_INSTALL_DIR})
|
refix_kicad_bundle( ${OSX_BUNDLE_INSTALL_DIR} )
|
||||||
endif( )
|
endif( )
|
||||||
|
|
||||||
" COMPONENT Runtime
|
" COMPONENT Runtime
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
if (APPLE AND KICAD_OSX_CODESIGN )
|
||||||
|
install( CODE "
|
||||||
|
include( ${CMAKE_MODULE_PATH}/SignMacOS.cmake )
|
||||||
|
|
||||||
|
message( STATUS \"Signing bundles...\" )
|
||||||
|
sign_kicad_bundle( \"${OSX_BUNDLE_INSTALL_DIR}\" \"\${KICAD_OSX_SIGNING_ID}\" \"\${KICAD_OSX_SIGNING_USE_SECURE_TIMESTAMP}\" \"\${KICAD_OSX_SIGNING_USE_HARDENED_RUNTIME}\" \"\${KICAD_OSX_SIGNING_ENTITLEMENTS_FILE}\" )
|
||||||
|
" COMPONENT Runtime )
|
||||||
|
endif()
|
Loading…
Reference in New Issue