diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 893042afa00..8c9cf1fb878 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -63,6 +63,8 @@ endfunction() # Ideally this would be done as part of the Blender build since it makes assumptions # about where the files will be installed. However it would add patchelf as a new # dependency for building. +# +# Also removes versioned symlinks, which give errors with macOS notarization. if(APPLE) set(set_rpath_cmd python3 ${CMAKE_CURRENT_SOURCE_DIR}/darwin/set_rpath.py @loader_path) else() @@ -76,7 +78,11 @@ function(harvest_rpath_lib from to pattern) cmake_policy(SET CMP0009 NEW)\n file(GLOB_RECURSE shared_libs ${HARVEST_TARGET}/${to}/${pattern}) \n foreach(f \${shared_libs}) \n - if(NOT IS_SYMLINK \${f})\n + if(IS_SYMLINK \${f})\n + if(APPLE)\n + file(REMOVE_RECURSE \${f}) + endif()\n + else()\n execute_process(COMMAND ${set_rpath_cmd} \${f}) \n endif()\n endforeach()") @@ -101,15 +107,21 @@ function(harvest_rpath_python from to pattern) install(CODE "\ file(GLOB_RECURSE shared_libs ${HARVEST_TARGET}/${to}/${pattern}\.so*) \n foreach(f \${shared_libs}) \n - get_filename_component(f_dir \${f} DIRECTORY) \n - file(RELATIVE_PATH relative_dir \${f_dir} ${HARVEST_TARGET}) \n - execute_process(COMMAND ${set_rpath_cmd}/\${relative_dir}../lib \${f}) \n + if(IS_SYMLINK \${f})\n + if(APPLE)\n + file(REMOVE_RECURSE \${f}) + endif()\n + else()\n + get_filename_component(f_dir \${f} DIRECTORY) \n + file(RELATIVE_PATH relative_dir \${f_dir} ${HARVEST_TARGET}) \n + execute_process(COMMAND ${set_rpath_cmd}/\${relative_dir}../lib \${f}) \n + endif()\n endforeach()") endfunction() harvest(alembic/include alembic/include "*.h") harvest(alembic/lib/libAlembic.a alembic/lib/libAlembic.a) -harvest(alembic/bin alembic/bin "*") +harvest_rpath_bin(alembic/bin alembic/bin "*") harvest(brotli/include brotli/include "*.h") harvest(brotli/lib brotli/lib "*.a") harvest(boost/include boost/include "*") @@ -151,7 +163,7 @@ harvest(llvm/lib llvm/lib "libLLVM*.a") harvest(llvm/lib llvm/lib "libclang*.a") harvest(llvm/lib/clang llvm/lib/clang "*.h") if(APPLE) - harvest(openmp/lib openmp/lib "*") + harvest(openmp/lib openmp/lib "libomp.dylib") harvest(openmp/include openmp/include "*.h") endif() if(BLENDER_PLATFORM_ARM) @@ -242,9 +254,8 @@ harvest(usd/lib/usd usd/lib/usd "*") harvest_rpath_python(usd/lib/python/pxr python/lib/python${PYTHON_SHORT_VERSION}/site-packages/pxr "*") harvest(usd/plugin usd/plugin "*") harvest(materialx/include materialx/include "*.h") -harvest(materialx/lib materialx/lib "*") +harvest_rpath_lib(materialx/lib materialx/lib "*${SHAREDLIBEXT}*") harvest(materialx/libraries materialx/libraries "*") -harvest(materialx/python materialx/python "*") harvest(materialx/lib/cmake/MaterialX materialx/lib/cmake/MaterialX "*.cmake") harvest_rpath_python(materialx/python/MaterialX python/lib/python${PYTHON_SHORT_VERSION}/site-packages/MaterialX "*") # We do not need anything from the resources folder, but the MaterialX config diff --git a/build_files/build_environment/darwin/set_rpath.py b/build_files/build_environment/darwin/set_rpath.py index 190e619a5ba..6ca58875ac1 100644 --- a/build_files/build_environment/darwin/set_rpath.py +++ b/build_files/build_environment/darwin/set_rpath.py @@ -1,9 +1,19 @@ #!/usr/bin/env python3 # macOS utility to remove all rpaths and add a new one. +import os +import re import subprocess import sys +# Strip version numbers from dependenciesm macOS notarizatiom fails +# with version symlinks. +def strip_lib_version(name): + name = re.sub(r'(\.[0-9]+)+.dylib', '.dylib', name) + name = re.sub(r'(\.[0-9]+)+.so', '.so', name) + name = re.sub(r'(\.[0-9]+)+.cpython', '.cpython', name) + return name + rpath = sys.argv[1] file = sys.argv[2] @@ -17,3 +27,18 @@ for i, token in enumerate(tokens): subprocess.run(['install_name_tool', '-delete_rpath', old_rpath, file]) subprocess.run(['install_name_tool', '-add_rpath', rpath, file]) + +# Strip version from dependencies. +p = subprocess.run(['otool', '-L', file], capture_output=True) +tokens = p.stdout.split() +for i, token in enumerate(tokens): + token = token.decode("utf-8") + if token.startswith("@rpath"): + new_token = strip_lib_version(token) + subprocess.run(['install_name_tool', '-change', token, new_token, file]) + +# Strip version from library itself. +new_file = strip_lib_version(file) +new_id = '@rpath/' + os.path.basename(new_file) +os.rename(file, new_file) +subprocess.run(['install_name_tool', '-id', new_id, new_file])