diff --git a/CMakeLists.txt b/CMakeLists.txt index fa6f691161..cb671e7bc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,6 +147,10 @@ cmake_dependent_option( KICAD_BUILD_SMALL_DEBUG_FILES OFF "NOT MSVC" OFF ) +cmake_dependent_option( KICAD_APPLE_MAKE_RELOCATEABLE_BUNDLE + "On macOS, post-process the build to make it relocateable (default ON)" + ON "APPLE" OFF ) + #################################### # Installation options #################################### @@ -662,29 +666,6 @@ else() # RPATH settings for building shared libraries set( CMAKE_MACOSX_RPATH FALSE ) - - # Override default paths for fixup_bundle - set( OSX_BUNDLE_OVERRIDE_PATHS " - function( gp_item_default_embedded_path_override item default_embedded_path_var ) - # by default, embed things right next to the main bundle executable: - set( path \"@executable_path/../../Contents/MacOS\" ) - set( overridden 0 ) - - # embed .dylibs right next to the main bundle executable: - if( item MATCHES \"\\\\.dylib$\" ) - set( path \"@executable_path/../Frameworks\" ) - set( overridden 1 ) - endif() - - set( \${default_embedded_path_var} \"\${path}\" PARENT_SCOPE ) - endfunction(gp_item_default_embedded_path_override) - - # If `BU_CHMOD_BUNDLE_ITEMS` is not set, `install_name_tool` will fail to re-write some - # loader paths due to lack of writable permissions if the build dependencies were installed - # by brew (or didn't have writable permissions) - set ( BU_CHMOD_BUNDLE_ITEMS ON ) - " - ) endif() mark_as_advanced( KICAD_BIN diff --git a/bitmap2component/CMakeLists.txt b/bitmap2component/CMakeLists.txt index a9a0aa6408..4c33940d45 100644 --- a/bitmap2component/CMakeLists.txt +++ b/bitmap2component/CMakeLists.txt @@ -61,24 +61,32 @@ if( APPLE ) MACOSX_BUNDLE_INFO_PLIST ${PROJECT_BINARY_DIR}/bitmap2component/Info.plist ) + set_target_properties( bitmap2component PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + # put individual bundle outside of main bundle as a first step # will be pulled into the main bundle when creating main bundle install( TARGETS bitmap2component DESTINATION ${KICAD_BIN} COMPONENT binary ) - install( CODE " - # override default embedded path settings - ${OSX_BUNDLE_OVERRIDE_PATHS} - # do all the work - include( BundleUtilities ) - fixup_bundle( ${KICAD_BIN}/bitmap2component.app/Contents/MacOS/bitmap2component - \"\" - \"${PYTHON_FRAMEWORK}\" + install( CODE " + set( KICAD_CMAKE_MODULE_PATH \"${KICAD_CMAKE_MODULE_PATH}\" ) + set( KICAD_BIN \"${KICAD_BIN}\" ) + set( OSX_BUNDLE_INSTALL_BIN_DIR \"${OSX_BUNDLE_INSTALL_BIN_DIR}\" ) + set( OSX_BUNDLE_INSTALL_LIB_DIR \"${OSX_BUNDLE_INSTALL_LIB_DIR}\" ) + " ) + + install( CODE [[ + include( ${KICAD_CMAKE_MODULE_PATH}/InstallSteps/InstallMacOS.cmake ) + + # Install any dependencies (this will generally duplicate kicad.app but we can't be sure) + install_runtime_deps( "${KICAD_BIN}/bitmap2component.app/Contents/MacOS/bitmap2component" + "" + "" ) - " COMPONENT Runtime - ) + ]] ) else() install( TARGETS bitmap2component DESTINATION ${KICAD_BIN} diff --git a/cmake/InstallSteps/InstallMacOS.cmake b/cmake/InstallSteps/InstallMacOS.cmake new file mode 100644 index 0000000000..c01942bd09 --- /dev/null +++ b/cmake/InstallSteps/InstallMacOS.cmake @@ -0,0 +1,34 @@ +# Copies the runtime dependencies for a given target into the bundle + +function( install_runtime_deps exe libs dest ) + # set(CMAKE_MESSAGE_LOG_LEVEL DEBUG) + message( DEBUG "install_runtime_deps ${exe}\n libs: ${libs}\n dest: ${dest}" ) + + file( GET_RUNTIME_DEPENDENCIES + LIBRARIES ${libs} + EXECUTABLES ${exe} + RESOLVED_DEPENDENCIES_VAR _r_deps + UNRESOLVED_DEPENDENCIES_VAR _u_deps + POST_EXCLUDE_FILES Python + ) + + if( "${dest}" STREQUAL "" ) + set( dest "${OSX_BUNDLE_INSTALL_LIB_DIR}" ) + message( DEBUG ".... Updated dest to ${dest}" ) + endif() + + foreach( _file ${_r_deps} ) + message( DEBUG ".... install dep ${_file}" ) + file(INSTALL + DESTINATION "${dest}" + TYPE SHARED_LIBRARY + FOLLOW_SYMLINK_CHAIN + FILES "${_file}" + ) + endforeach() + +# list(LENGTH _u_deps _u_length) +# if("${_u_length}" GREATER 0) +# message(WARNING "Unresolved dependencies detected! ${_u_deps}") +# endif() +endfunction() \ No newline at end of file diff --git a/cmake/RefixupMacOS.cmake b/cmake/InstallSteps/RefixupMacOS.cmake similarity index 66% rename from cmake/RefixupMacOS.cmake rename to cmake/InstallSteps/RefixupMacOS.cmake index cad23c90c4..09e92ab164 100644 --- a/cmake/RefixupMacOS.cmake +++ b/cmake/InstallSteps/RefixupMacOS.cmake @@ -1,12 +1,14 @@ # RefixupMacOS.cmake -# Adjust rpaths and dependency information on macOS -# after fixup_bundle. +# Now that we don't use BundleUtilities and instead use GET_RUNTIME_DEPENDENCIES, +# the binaries that are built all have absolute path library load commands. +# What we need to do here is update all the paths for _the runtime dependencies +# that we installed into the bundle_ to live in @rpath, with Python getting +# special treatment in that it lives in @rpath/Frameworks. -# Some of this comes from GetPrerequisites.cmake. - -# This is not intended to make an install completely -# redistributable and relocatable. +# Make sure GLOB_RECURSE doesn't follow symlinks +cmake_policy( PUSH ) +cmake_policy( SET CMP0009 NEW ) function( refix_kicad_bundle target ) # target should be the path to the kicad.app directory @@ -18,7 +20,7 @@ function( refix_kicad_bundle target ) file( GLOB_RECURSE items ${target}/*.dylib ${target}/*.so ${target}/*.kiface ) foreach( item ${items} ) - message( "Refixing '${item}'" ) + message( "Refixing prereqs for '${item}'" ) refix_prereqs( ${item} ) endforeach( ) @@ -27,30 +29,29 @@ function( refix_kicad_bundle target ) foreach( subdir ${subdirs} ) file( GLOB binaries ${subdir}/Contents/MacOS/* ) foreach( binary ${binaries} ) - message( "Refixing '${binary}'" ) - refix_rpaths( ${binary} ) + message( "Refixing rpaths and prereqs for '${binary}'" ) + #refix_rpaths( ${binary} ) refix_prereqs( ${binary} ) endforeach( ) endforeach( ) file( GLOB pythonbinbinaries ${target}/Contents/Frameworks/Python.framework/Versions/3.*/bin/python3 ) foreach( pythonbinbinary ${pythonbinbinaries} ) - message( "Refixing '${pythonbinbinary}'" ) + message( "Refixing rpaths and prereqs for '${pythonbinbinary}'" ) refix_rpaths( ${pythonbinbinary} ) refix_prereqs( ${pythonbinbinary} ) endforeach() file( GLOB pythonresbinaries ${target}/Contents/Frameworks/Python.framework/Versions/3.*/Resources/Python.app/Contents/MacOS/Python ) foreach( pythonresbinary ${pythonresbinaries} ) - message( "Refixing '${pythonresbinary}'" ) + message( "Refixing rpaths and prereqs for '${pythonresbinary}'" ) refix_rpaths( ${pythonresbinary} ) refix_prereqs( ${pythonresbinary} ) endforeach() file( GLOB binaries ${target}/Contents/MacOS/* ) foreach( binary ${binaries} ) - message( "Refixing '${binary}'" ) - refix_rpaths( ${binary} ) + message( "Refixing prereqs for '${binary}'" ) refix_prereqs( ${binary} ) endforeach( ) @@ -66,8 +67,11 @@ function( cleanup_python bundle) # Remove extra 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} ) + + if( NOT "${extra_pythons}" STREQUAL "" ) + message( "Removing extra Pythons copied into Contents/MacOS: ${extra_pythons}" ) + file( REMOVE_RECURSE ${extra_pythons} ) + endif() # Make sure Python's Current is a symlink to 3.x file( REMOVE_RECURSE ${bundle}/Contents/Frameworks/Python.framework/Versions/Current ) @@ -85,7 +89,6 @@ function( refix_rpaths binary ) string( REGEX REPLACE "/+$" "" relative_python_framework_path "${relative_python_framework_path}" ) # remove trailing slash list( APPEND desired_rpaths "@executable_path/${relative_kicad_framework_path}" "@executable_path/${relative_python_framework_path}" ) - get_item_rpaths( ${binary} old_rpaths ) foreach( desired_rpath ${desired_rpaths} ) execute_process( COMMAND install_name_tool -add_rpath ${desired_rpath} ${binary} @@ -100,7 +103,12 @@ function( refix_rpaths binary ) endfunction( ) function( refix_prereqs target ) - # Replace '@executable_path/../Frameworks/' in dependencies with '@rpath/' + # file(GET_RUNTIME_DEPENDENCIES) does not seem to work properly on libraries, it returns empty + # results. So, to figure out which ones we can remap to rpath, we make use of ${items}, which + # happens to contain all the shared libs we found in the bundle. This is a big hack, because + # we're not actually checking that these shared libs live *in* the rpath, but in practice it + # should work. If this stops being the case, we can always add more logic... + execute_process( COMMAND otool -L ${target} RESULT_VARIABLE gp_rv @@ -110,6 +118,8 @@ function( refix_prereqs target ) if( NOT gp_rv STREQUAL "0" ) message( FATAL_ERROR "otool failed: ${gp_rv}\n${gp_ev}" ) + else() + message( DEBUG "otool -L ${target} returned: ${gp_cmd_ov}" ) endif( ) string( REPLACE ";" "\\;" candidates "${gp_cmd_ov}" ) @@ -141,24 +151,42 @@ function( refix_prereqs target ) if( "${candidate}" MATCHES "${gp_regex}" ) string( REGEX REPLACE "${otool_regex}" "\\1" raw_prereq "${candidate}" ) - if ( raw_prereq MATCHES "^@executable_path/\\.\\./\\.\\./Contents/MacOS/Python$" ) - set( changed_prereq "@rpath/Versions/Current/Python" ) - elseif ( raw_prereq MATCHES "^@executable_path/\\.\\./Frameworks/" ) - string( REPLACE "@executable_path/../Frameworks/" - "@rpath/" changed_prereq - "${raw_prereq}" ) - elseif ( raw_prereq MATCHES "^@executable_path/\\.\\./PlugIns/" ) - string( REPLACE "@executable_path/../PlugIns/" - "@rpath/../PlugIns/" changed_prereq - "${raw_prereq}" ) - else( ) - continue( ) - endif( ) + message( DEBUG "processing ${raw_prereq}") + if( raw_prereq MATCHES "^@rpath.*" ) + message( DEBUG " already an rpath; skipping" ) + continue() + endif() - # Because of the above continue( ) in the else, we know we changed the prereq if we're here + get_filename_component( prereq_name ${raw_prereq} NAME ) + message( DEBUG " prereq name: ${prereq_name}" ) + set( changed_prereq "" ) + + foreach( item ${items} ) + get_filename_component( item_name ${item} NAME ) + if( "${item_name}" STREQUAL "${prereq_name}" ) + message( DEBUG " found match at ${item}" ) + + if( item MATCHES "^.*/Contents/PlugIns/.*" ) + string( REGEX REPLACE "^.*/Contents/PlugIns/(.*)$" + "@rpath/../PlugIns/\\1" + changed_prereq + "${item}" ) + else() + set( changed_prereq "@rpath/${item_name}" ) + endif() + endif() + endforeach() + + if( "${changed_prereq}" STREQUAL "" ) + message( DEBUG " not found in items; assumed to be system lib" ) + continue() + endif() + + # Because of the above continue()s, we know we changed the prereq if we're here if( raw_prereq STREQUAL gp_install_id ) set( cmd install_name_tool -id ${changed_prereq} "${target}" ) + message( DEBUG " updating install id: ${cmd}" ) execute_process( COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result ) if( NOT install_name_tool_result EQUAL 0 ) string( REPLACE ";" "' '" msg "'${cmd}'" ) @@ -167,7 +195,6 @@ function( refix_prereqs target ) continue( ) endif( ) - if ( NOT raw_prereq STREQUAL changed_prereq ) # we know we need to change this prereq set( changes ${changes} "-change" "${raw_prereq}" "${changed_prereq}" ) @@ -177,6 +204,7 @@ function( refix_prereqs target ) if( changes ) set( cmd install_name_tool ${changes} "${target}" ) + message( DEBUG "changing prereqs: ${changes}" ) execute_process( COMMAND ${cmd} RESULT_VARIABLE install_name_tool_result ) if( NOT install_name_tool_result EQUAL 0 ) string( REPLACE ";" "' '" msg "'${cmd}'" ) @@ -184,3 +212,5 @@ function( refix_prereqs target ) endif( ) endif( ) endfunction( ) + +cmake_policy( POP ) \ No newline at end of file diff --git a/cmake/SignMacOS.cmake b/cmake/InstallSteps/SignMacOS.cmake similarity index 97% rename from cmake/SignMacOS.cmake rename to cmake/InstallSteps/SignMacOS.cmake index 147262dc66..600dc008e2 100644 --- a/cmake/SignMacOS.cmake +++ b/cmake/InstallSteps/SignMacOS.cmake @@ -84,7 +84,7 @@ function( sign_kicad_bundle target signing_id use_secure_timestamp use_hardened_ RESULT_VARIABLE codesign_result) if( NOT codesign_result EQUAL 0 ) - message( FATAL_ERROR "macOS signing failed; ran ${cmd}" ) + message( WARNING "macOS signing failed; ${cmd} returned ${codesign_result}" ) endif( ) endforeach( ) endfunction() diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index 965694f5ef..46d71a4f91 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -96,6 +96,9 @@ if( APPLE ) set_target_properties( cvpcb_kiface PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR} ) + set_target_properties( cvpcb_kiface PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + set_target_properties( cvpcb_kiface PROPERTIES BUILD_WITH_INSTALL_RPATH 1 ) else() install( TARGETS cvpcb_kiface DESTINATION ${KICAD_KIFACE} diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 3b1badf301..693d080635 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -606,6 +606,14 @@ if( APPLE ) set_target_properties( eeschema_kiface PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR} ) + + set_target_properties( eeschema PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + + set_target_properties( eeschema_kiface PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + set_target_properties( eeschema_kiface PROPERTIES BUILD_WITH_INSTALL_RPATH 1 ) + # put individual bundle outside of main bundle as a first step # will be pulled into the main bundle when creating main bundle install( TARGETS eeschema @@ -614,17 +622,12 @@ if( APPLE ) ) install( CODE " - # override default embedded path settings - ${OSX_BUNDLE_OVERRIDE_PATHS} - - # do all the work - include( BundleUtilities ) - fixup_bundle( ${KICAD_BIN}/eeschema.app/Contents/MacOS/eeschema - \"\" - \"${PYTHON_FRAMEWORK}\" - ) - " COMPONENT Runtime - ) + set( KICAD_CMAKE_MODULE_PATH \"${KICAD_CMAKE_MODULE_PATH}\" ) + set( KICAD_BIN \"${KICAD_BIN}\" ) + set( OSX_BUNDLE_INSTALL_BIN_DIR \"${OSX_BUNDLE_INSTALL_BIN_DIR}\" ) + set( OSX_BUNDLE_INSTALL_LIB_DIR \"${OSX_BUNDLE_INSTALL_LIB_DIR}\" ) + set( OSX_BUNDLE_BUILD_KIFACE_DIR \"${OSX_BUNDLE_BUILD_KIFACE_DIR}\" ) + " ) # bundle libngspice and codemodels get_filename_component( ABS_LIBNGSPICE ${NGSPICE_LIBRARY} ABSOLUTE ) @@ -635,6 +638,16 @@ if( APPLE ) FILES_MATCHING PATTERN "*.dylib") install( DIRECTORY "${LIBNGSPICE_PATH}/ngspice" DESTINATION "${OSX_BUNDLE_INSTALL_PLUGIN_DIR}/sim" ) + + install( CODE [[ + include( ${KICAD_CMAKE_MODULE_PATH}/InstallSteps/InstallMacOS.cmake ) + + # Install any dependencies (this will generally duplicate kicad.app but we can't be sure) + install_runtime_deps( "${KICAD_BIN}/eeschema.app/Contents/MacOS/eeschema" + "${OSX_BUNDLE_BUILD_KIFACE_DIR}/_eeschema.kiface" + "" + ) + ]] ) else() if( MSVC ) target_sources( eeschema_kiface PRIVATE ${CMAKE_SOURCE_DIR}/resources/msw/eeschema-dll.rc ) diff --git a/gerbview/CMakeLists.txt b/gerbview/CMakeLists.txt index ee61a05616..669a26d366 100644 --- a/gerbview/CMakeLists.txt +++ b/gerbview/CMakeLists.txt @@ -185,24 +185,38 @@ if( APPLE ) set_target_properties( gerbview_kiface PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR} ) + + set_target_properties( gerbview PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + + set_target_properties( gerbview_kiface PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + set_target_properties( gerbview_kiface PROPERTIES BUILD_WITH_INSTALL_RPATH 1 ) + # put individual bundle outside of main bundle as a first step # will be pulled into the main bundle when creating main bundle install( TARGETS gerbview DESTINATION ${KICAD_BIN} COMPONENT binary ) - install( CODE " - # override default embedded path settings - ${OSX_BUNDLE_OVERRIDE_PATHS} - # do all the work - include( BundleUtilities ) - fixup_bundle( ${KICAD_BIN}/gerbview.app/Contents/MacOS/gerbview - \"\" - \"${PYTHON_FRAMEWORK}\" - ) - " COMPONENT Runtime - ) + install( CODE " + set( KICAD_CMAKE_MODULE_PATH \"${KICAD_CMAKE_MODULE_PATH}\" ) + set( KICAD_BIN \"${KICAD_BIN}\" ) + set( OSX_BUNDLE_INSTALL_BIN_DIR \"${OSX_BUNDLE_INSTALL_BIN_DIR}\" ) + set( OSX_BUNDLE_INSTALL_LIB_DIR \"${OSX_BUNDLE_INSTALL_LIB_DIR}\" ) + set( OSX_BUNDLE_BUILD_KIFACE_DIR \"${OSX_BUNDLE_BUILD_KIFACE_DIR}\" ) + " ) + + install( CODE [[ + include( ${KICAD_CMAKE_MODULE_PATH}/InstallSteps/InstallMacOS.cmake ) + + # Install any dependencies (this will generally duplicate kicad.app but we can't be sure) + install_runtime_deps( "${KICAD_BIN}/gerbview.app/Contents/MacOS/gerbview" + "${OSX_BUNDLE_BUILD_KIFACE_DIR}/_gerbview.kiface" + "" + ) + ]] ) else() if( MSVC ) target_sources( gerbview_kiface PRIVATE ${CMAKE_SOURCE_DIR}/resources/msw/gerbview-dll.rc ) diff --git a/kicad/CMakeLists.txt b/kicad/CMakeLists.txt index ff8cef8382..e61ba75bcd 100644 --- a/kicad/CMakeLists.txt +++ b/kicad/CMakeLists.txt @@ -188,84 +188,33 @@ if( APPLE ) set( PYTHON_FRAMEWORK_HELPER "0" ) endif() - if( MACOS_EXTRA_BUNDLE_FIX_DIRS ) - set( BUNDLE_FIX_DIRS ${BUNDLE_FIX_DIRS} ${MACOS_EXTRA_BUNDLE_FIX_DIRS} ) # TODO: where should we document MACOS_EXTRA_BUNDLE_FIX_DIRS? - endif() + set_target_properties( kicad PROPERTIES BUILD_RPATH ${PYTHON_FRAMEWORK} ) + set_target_properties( kicad PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + set_target_properties( kicad-cli PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + set_target_properties( kicad-cli PROPERTIES BUILD_WITH_INSTALL_RPATH 1 ) - set( BUNDLE_FIX_DIRS ${BUNDLE_FIX_DIRS} ${OCC_LIBRARY_DIR} ) - - # make main bundle relocatable install( CODE " - set( BUNDLE_FIX_DIRS ${BUNDLE_FIX_DIRS} ) # pull in the variable from above, so we can append if needed + set( KICAD_CMAKE_MODULE_PATH \"${KICAD_CMAKE_MODULE_PATH}\" ) + set( OSX_BUNDLE_INSTALL_BIN_DIR \"${OSX_BUNDLE_INSTALL_BIN_DIR}\" ) + set( OSX_BUNDLE_INSTALL_LIB_DIR \"${OSX_BUNDLE_INSTALL_LIB_DIR}\" ) + set( PYTHON_FRAMEWORK \"${PYTHON_FRAMEWORK}\" ) + " ) - # find all kicad libs and modules - file( GLOB PLUGINS_KIFACE ${OSX_BUNDLE_INSTALL_KIFACE_DIR}/*.kiface ) - file( GLOB_RECURSE PLUGINS_SO ${OSX_BUNDLE_INSTALL_PLUGIN_DIR}/*.so ) - file( GLOB_RECURSE PLUGINS_3D ${OSX_BUNDLE_INSTALL_PLUGIN_DIR}/3d/*.dylib ) - set( BUNDLE_FIX_LIBS \${PLUGINS_KIFACE} \${PLUGINS_SO} \${PLUGINS_3D} ) + install( CODE [[ + include( ${KICAD_CMAKE_MODULE_PATH}/InstallSteps/InstallMacOS.cmake ) - # Find ngspice if it is being packaged - if( ${SPICE_HELPER} ) - file( GLOB_RECURSE PLUGINS_NGSPICE ${OSX_BUNDLE_INSTALL_PLUGIN_DIR}/sim/*.dylib ) - set( BUNDLE_FIX_LIBS \${BUNDLE_FIX_LIBS} \${PLUGINS_NGSPICE} ) - endif() - - # Find python if it is requested - if( ${SCRIPTING_HELPER} ) - # file( GLOB WXPYTHON_DIR RELATIVE ${OSX_BUNDLE_BUILD_DIR}/${OSX_BUNDLE_PYTHON_SITE_PACKAGES_DIR} ${OSX_BUNDLE_INSTALL_PYTHON_SITE_PACKAGES_DIR}/wx-?.?-osx_cocoa ) - # file( GLOB PYTHON_SCRIPTING_SO ${OSX_BUNDLE_INSTALL_PYTHON_SITE_PACKAGES_DIR}/*.so ) - # set( BUNDLE_FIX_LIBS \${BUNDLE_FIX_LIBS} \${PYTHON_SCRIPTING_SO} ) - # file( GLOB PYTHON_SCRIPTING_SO ${OSX_BUNDLE_INSTALL_PYTHON_SITE_PACKAGES_DIR}/\${WXPYTHON_DIR}/wx/*.so ) - # set( BUNDLE_FIX_LIBS \${BUNDLE_FIX_LIBS} \${PYTHON_SCRIPTING_SO} ) - endif() - - # override default embedded path settings - ${OSX_BUNDLE_OVERRIDE_PATHS} - - # do all the work - - if ( ${PYTHON_FRAMEWORK_HELPER} ) - # This idea here is to repair anything that fixup_bundle doesn't handle - # properly for our setup with both Python.framework *and* symlinked subapps - # that's needed for *running* here - - # Anything that's needed strictly for packaging and making redistributable - # macOS builds can be defined in kicad-mac-builder - - # Of course, making it all work right here would be even slicker, - # but if wishes were horses... - - # It would be awesome if we find a better solution (or BundleUtilities works for our corner case better) - - execute_process( COMMAND cp -RP ${PYTHON_FRAMEWORK} ${OSX_BUNDLE_INSTALL_LIB_DIR}/) - # We're using cp -RP because CMake's COPY_RESOLVED_BUNDLE... and COPY_DIRECTORY don't handle symlinks correctly - - # Add any .so files in the site-packages directory to the list of things to fixup during fixup_bundle - file( GLOB_RECURSE PYTHON_SITE_PACKAGES_LIBS ${OSX_BUNDLE_INSTALL_PYTHON_SITE_PACKAGES_DIR}/*.so ) - set( BUNDLE_FIX_LIBS \${BUNDLE_FIX_LIBS} \${PYTHON_SITE_PACKAGES_LIBS} ) - - fixup_bundle( ${OSX_BUNDLE_INSTALL_BIN_DIR}/kicad - \"\${BUNDLE_FIX_LIBS}\" - \"\${BUNDLE_FIX_DIRS};${PYTHON_FRAMEWORK}\" - 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 - # we mark Python things as IGNORE_ITEMs. We'll refix them later. - else() - fixup_bundle( ${OSX_BUNDLE_INSTALL_BIN_DIR}/kicad - \"\${BUNDLE_FIX_LIBS}\" - \"\${BUNDLE_FIX_DIRS}\" + # Install the main bundle + install_runtime_deps( "${OSX_BUNDLE_INSTALL_BIN_DIR}/kicad" + "" + "" ) - endif() - if( ${SPICE_HELPER} ) - execute_process( COMMAND install_name_tool -id @executable_path/../PlugIns/sim/libngspice.0.dylib libngspice.0.dylib - WORKING_DIRECTORY ${OSX_BUNDLE_INSTALL_PLUGIN_DIR}/sim ) - endif() - - " COMPONENT Runtime - ) + # Now install Python framework properly (GET_RUNTIME_DEPENDENCIES can't do this) + execute_process( COMMAND rm ${OSX_BUNDLE_INSTALL_LIB_DIR}/Python ) + execute_process( COMMAND cp -RP ${PYTHON_FRAMEWORK} ${OSX_BUNDLE_INSTALL_LIB_DIR}/ ) + ]] ) # move all individual app bundles into main bundle install( CODE " @@ -285,15 +234,17 @@ if( APPLE ) endfunction( move_to_main_bundle ) # move all app bundles - move_to_main_bundle( \"bitmap2component.app\" \"Bitmap2Component.app\" ) - move_to_main_bundle( \"eeschema.app\" \"Eeschema.app\" ) + move_to_main_bundle( \"bitmap2component.app\" \"Image Converter.app\" ) + move_to_main_bundle( \"eeschema.app\" \"Schematic Editor.app\" ) move_to_main_bundle( \"gerbview.app\" \"GerbView.app\" ) move_to_main_bundle( \"pcb_calculator.app\" \"PCB Calculator.app\" ) - move_to_main_bundle( \"pcbnew.app\" \"Pcbnew.app\" ) + move_to_main_bundle( \"pcbnew.app\" \"PCB Editor.app\" ) move_to_main_bundle( \"pl_editor.app\" \"Page Layout Editor.app\" ) - if ( ${PYTHON_FRAMEWORK_HELPER} ) - include( ${KICAD_CMAKE_MODULE_PATH}/RefixupMacOS.cmake ) + cmake_policy( SET CMP0012 NEW ) + if ( ${PYTHON_FRAMEWORK_HELPER} AND ${KICAD_APPLE_MAKE_RELOCATEABLE_BUNDLE} ) + message( STATUS \"Making the finished bundle relocateable...\" ) + include( ${KICAD_CMAKE_MODULE_PATH}/InstallSteps/RefixupMacOS.cmake ) refix_kicad_bundle( ${OSX_BUNDLE_INSTALL_DIR} ) endif( ) diff --git a/pagelayout_editor/CMakeLists.txt b/pagelayout_editor/CMakeLists.txt index 8920cc70a7..731b7e712f 100644 --- a/pagelayout_editor/CMakeLists.txt +++ b/pagelayout_editor/CMakeLists.txt @@ -140,24 +140,36 @@ if( APPLE ) LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR} ) + set_target_properties( pl_editor PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + + set_target_properties( pl_editor_kiface PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + set_target_properties( pl_editor_kiface PROPERTIES BUILD_WITH_INSTALL_RPATH 1 ) + # put individual bundle outside of main bundle as a first step # will be pulled into the main bundle when creating main bundle install( TARGETS pl_editor DESTINATION ${KICAD_BIN} COMPONENT binary ) - install( CODE " - # override default embedded path settings - ${OSX_BUNDLE_OVERRIDE_PATHS} - # do all the work - include( BundleUtilities ) - fixup_bundle( ${KICAD_BIN}/pl_editor.app/Contents/MacOS/pl_editor - \"\" - \"${PYTHON_FRAMEWORK}\" + install( CODE " + set( KICAD_CMAKE_MODULE_PATH \"${KICAD_CMAKE_MODULE_PATH}\" ) + set( KICAD_BIN \"${KICAD_BIN}\" ) + set( OSX_BUNDLE_INSTALL_BIN_DIR \"${OSX_BUNDLE_INSTALL_BIN_DIR}\" ) + set( OSX_BUNDLE_INSTALL_LIB_DIR \"${OSX_BUNDLE_INSTALL_LIB_DIR}\" ) + " ) + + install( CODE [[ + include( ${KICAD_CMAKE_MODULE_PATH}/InstallSteps/InstallMacOS.cmake ) + + # Install any dependencies (this will generally duplicate kicad.app but we can't be sure) + install_runtime_deps( "${KICAD_BIN}/pl_editor.app/Contents/MacOS/pl_editor" + "" + "" ) - " COMPONENT Runtime - ) + ]] ) else() if( MSVC ) target_sources( pl_editor_kiface PRIVATE ${CMAKE_SOURCE_DIR}/resources/msw/pl_editor-dll.rc ) diff --git a/pcb_calculator/CMakeLists.txt b/pcb_calculator/CMakeLists.txt index 62353a0159..b1e4be0f54 100644 --- a/pcb_calculator/CMakeLists.txt +++ b/pcb_calculator/CMakeLists.txt @@ -149,24 +149,35 @@ if( APPLE ) LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR} ) + set_target_properties( pcb_calculator PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + set_target_properties( pcb_calculator_kiface PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + set_target_properties( pcb_calculator_kiface PROPERTIES BUILD_WITH_INSTALL_RPATH 1 ) + # put individual bundle outside of main bundle as a first step # will be pulled into the main bundle when creating main bundle install( TARGETS pcb_calculator DESTINATION ${KICAD_BIN} COMPONENT binary ) - install( CODE " - # override default embedded path settings - ${OSX_BUNDLE_OVERRIDE_PATHS} - # do all the work - include( BundleUtilities ) - fixup_bundle( ${KICAD_BIN}/pcb_calculator.app/Contents/MacOS/pcb_calculator - \"\" - \"${PYTHON_FRAMEWORK}\" + install( CODE " + set( KICAD_CMAKE_MODULE_PATH \"${KICAD_CMAKE_MODULE_PATH}\" ) + set( KICAD_BIN \"${KICAD_BIN}\" ) + set( OSX_BUNDLE_INSTALL_BIN_DIR \"${OSX_BUNDLE_INSTALL_BIN_DIR}\" ) + set( OSX_BUNDLE_INSTALL_LIB_DIR \"${OSX_BUNDLE_INSTALL_LIB_DIR}\" ) + " ) + + install( CODE [[ + include( ${KICAD_CMAKE_MODULE_PATH}/InstallSteps/InstallMacOS.cmake ) + + # Install any dependencies (this will generally duplicate kicad.app but we can't be sure) + install_runtime_deps( "${KICAD_BIN}/pcb_calculator.app/Contents/MacOS/pcb_calculator" + "" + "" ) - " COMPONENT Runtime - ) + ]] ) else() if( MSVC ) target_sources( pcb_calculator_kiface PRIVATE ${CMAKE_SOURCE_DIR}/resources/msw/pcb_calculator-dll.rc ) diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index bd4f74b828..51ce6e928a 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -711,24 +711,38 @@ if( APPLE ) set_target_properties( pcbnew_kiface PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR} ) + + set_target_properties( pcbnew PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + + set_target_properties( pcbnew_kiface PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + set_target_properties( pcbnew_kiface PROPERTIES BUILD_WITH_INSTALL_RPATH 1 ) + # put individual bundle outside of main bundle as a first step # will be pulled into the main bundle when creating main bundle install( TARGETS pcbnew DESTINATION ${KICAD_BIN} COMPONENT binary ) - install( CODE " - # override default embedded path settings - ${OSX_BUNDLE_OVERRIDE_PATHS} - # do all the work - include( BundleUtilities ) - fixup_bundle( ${KICAD_BIN}/pcbnew.app/Contents/MacOS/pcbnew - \"\" - \"${PYTHON_FRAMEWORK}\" + install( CODE " + set( KICAD_CMAKE_MODULE_PATH \"${KICAD_CMAKE_MODULE_PATH}\" ) + set( KICAD_BIN \"${KICAD_BIN}\" ) + set( OSX_BUNDLE_INSTALL_BIN_DIR \"${OSX_BUNDLE_INSTALL_BIN_DIR}\" ) + set( OSX_BUNDLE_INSTALL_LIB_DIR \"${OSX_BUNDLE_INSTALL_LIB_DIR}\" ) + set( OSX_BUNDLE_BUILD_KIFACE_DIR \"${OSX_BUNDLE_BUILD_KIFACE_DIR}\" ) + " ) + + install( CODE [[ + include( ${KICAD_CMAKE_MODULE_PATH}/InstallSteps/InstallMacOS.cmake ) + + # Install any dependencies + install_runtime_deps( "${KICAD_BIN}/pcbnew.app/Contents/MacOS/pcbnew" + "${OSX_BUNDLE_BUILD_KIFACE_DIR}/_pcbnew.kiface" + "" ) - " COMPONENT Runtime - ) + ]] ) else() if( MSVC ) target_sources( pcbnew_kiface PRIVATE ${CMAKE_SOURCE_DIR}/resources/msw/pcbnew-dll.rc ) diff --git a/scripting/CMakeLists.txt b/scripting/CMakeLists.txt index e0744f6bf6..36ca25a882 100644 --- a/scripting/CMakeLists.txt +++ b/scripting/CMakeLists.txt @@ -67,6 +67,23 @@ if( APPLE ) set_target_properties( scripting_kiface PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${OSX_BUNDLE_BUILD_KIFACE_DIR} ) + set_target_properties( scripting_kiface PROPERTIES INSTALL_RPATH + "@executable_path/../Frameworks;@executable_path/../Frameworks/Python.framework" ) + set_target_properties( scripting_kiface PROPERTIES BUILD_WITH_INSTALL_RPATH 1 ) + + install( CODE " + set( KICAD_CMAKE_MODULE_PATH \"${KICAD_CMAKE_MODULE_PATH}\" ) + set( OSX_BUNDLE_BUILD_KIFACE_DIR \"${OSX_BUNDLE_BUILD_KIFACE_DIR}\" ) + set( OSX_BUNDLE_INSTALL_LIB_DIR \"${OSX_BUNDLE_INSTALL_LIB_DIR}\" ) + + include( ${KICAD_CMAKE_MODULE_PATH}/InstallSteps/InstallMacOS.cmake ) + + # Install any dependencies + install_runtime_deps( \"\" + \"${OSX_BUNDLE_BUILD_KIFACE_DIR}/_kipython.kiface\" + \"\" + ) + " ) else() install( TARGETS scripting_kiface DESTINATION ${KICAD_KIFACE} diff --git a/signing/CMakeLists.txt b/signing/CMakeLists.txt index 7a2bf530fd..88b06a0467 100644 --- a/signing/CMakeLists.txt +++ b/signing/CMakeLists.txt @@ -1,6 +1,13 @@ if (APPLE AND KICAD_OSX_CODESIGN ) install( CODE " - include( ${KICAD_CMAKE_MODULE_PATH}/SignMacOS.cmake ) + include( ${KICAD_CMAKE_MODULE_PATH}/InstallSteps/SignMacOS.cmake ) + + # InstallMacOS.cmake pulls in all the dynamic dependencies of Python into the Python framework dir. + # We don't want this because it makes signing fail, and they are not needed either. + # I can't figure out how to keep it from happening, so for now, just clean them up + message( STATUS \"Cleaning up Python.framework...\" ) + file( GLOB _PYTHON_TO_REMOVE ${OSX_BUNDLE_INSTALL_LIB_DIR}/Python.framework/* ) + file( REMOVE \${_PYTHON_TO_REMOVE} ) 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}\" )