diff options
author | Kreeblah <kreeblah@gmail.com> | 2021-11-10 09:50:03 +0300 |
---|---|---|
committer | SCG82 <scg082+github@gmail.com> | 2021-11-13 21:39:22 +0300 |
commit | 217436755e18d8d91b96ef113b766ca60ef75b43 (patch) | |
tree | eef948776bd6cc1cdae848f32017087f580debd2 | |
parent | cff64d3bd6514a027a10322fb8b2cac3c3a26b4e (diff) |
Fix signatures, as valid signatures are required on ARM Macs
-rw-r--r-- | .gitignore | 7 | ||||
-rw-r--r-- | CMakeLists.txt | 26 | ||||
-rw-r--r-- | src/DylibBundler.cpp | 12 | ||||
-rw-r--r-- | src/Utils.cpp | 47 | ||||
-rw-r--r-- | src/Utils.h | 3 | ||||
-rw-r--r-- | src/main.cpp | 2 |
6 files changed, 93 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..94ed808 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +*.o +dylibbundler +.idea/ +.vscode/ +build/ +cmake-build-*/ +.DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d3c7fa0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.15) +project(dylibbundler) + +set(CMAKE_CXX_STANDARD 11) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +string(REPLACE "-O3" "-O2" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE}) + +add_compile_options(-pipe -Wall -Wextra -Wpedantic) + +include_directories(src) + +add_executable(dylibbundler + src/Dependency.cpp + src/Dependency.h + src/DylibBundler.cpp + src/DylibBundler.h + src/main.cpp + src/Settings.cpp + src/Settings.h + src/Utils.cpp + src/Utils.h +) diff --git a/src/DylibBundler.cpp b/src/DylibBundler.cpp index 8933fd4..78f5189 100644 --- a/src/DylibBundler.cpp +++ b/src/DylibBundler.cpp @@ -48,9 +48,11 @@ void changeLibPathsOnFile(std::string file_to_fix) { if (deps_collected.find(file_to_fix) == deps_collected.end()) { + std::cout << " "; collectDependencies(file_to_fix); + std::cout << "\n"; } - std::cout << "\n* Fixing dependencies on " << file_to_fix.c_str() << std::endl; + std::cout << " * Fixing dependencies on " << file_to_fix.c_str() << std::endl; std::vector<Dependency> deps_in_file = deps_per_file[file_to_fix]; const int dep_amount = deps_in_file.size(); @@ -388,19 +390,23 @@ void doneWithDeps_go() { createDestDir(); - for(int n=0; n<dep_amount; n++) + for(int n=dep_amount-1; n>=0; n--) { + std::cout << "\n* Processing dependency " << deps[n].getInstallPath() << std::endl; deps[n].copyYourself(); changeLibPathsOnFile(deps[n].getInstallPath()); fixRpathsOnFile(deps[n].getOriginalPath(), deps[n].getInstallPath()); + adhocCodeSign(deps[n].getInstallPath()); } } const int fileToFixAmount = Settings::fileToFixAmount(); - for(int n=0; n<fileToFixAmount; n++) + for(int n=fileToFixAmount-1; n>=0; n--) { + std::cout << "\n* Processing " << Settings::fileToFix(n) << std::endl; copyFile(Settings::fileToFix(n), Settings::fileToFix(n)); // to set write permission changeLibPathsOnFile(Settings::fileToFix(n)); fixRpathsOnFile(Settings::fileToFix(n), Settings::fileToFix(n)); + adhocCodeSign(Settings::fileToFix(n)); } } diff --git a/src/Utils.cpp b/src/Utils.cpp index 9903f20..fc2b990 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -217,3 +217,50 @@ std::string getUserInputDirForFile(const std::string& filename) } } } + +void adhocCodeSign(const std::string& file) +{ + // Add ad-hoc signature for ARM (Apple Silicon) binaries + std::string signCommand = std::string("codesign --force --deep --preserve-metadata=entitlements,requirements,flags,runtime --sign - \"") + file + "\""; + if( systemp( signCommand ) != 0 ) + { + // If the codesigning fails, it may be a bug in Apple's codesign utility. + // A known workaround is to copy the file to another inode, then move it back + // erasing the previous file. Then sign again. + std::cerr << " * Error : An error occurred while applying ad-hoc signature to " << file << ". Attempting workaround" << std::endl; + + std::string machine = system_get_output("machine"); + bool isArm = machine.find("arm") != std::string::npos; + std::string tempDirTemplate = std::string(std::getenv("TMPDIR") + std::string("dylibbundler.XXXXXXXX")); + std::string filename = file.substr(file.rfind("/")+1); + char* tmpDirCstr = mkdtemp((char *)(tempDirTemplate.c_str())); + if( tmpDirCstr == NULL ) + { + std::cerr << " * Error : Unable to create temp directory for signing workaround" << std::endl; + if( isArm ) + { + exit(1); + } + } + std::string tmpDir = std::string(tmpDirCstr); + std::string tmpFile = tmpDir+"/"+filename; + const auto runCommand = [isArm](const std::string& command, const std::string& errMsg) + { + if( systemp( command ) != 0 ) + { + std::cerr << errMsg << std::endl; + if( isArm ) + { + exit(1); + } + } + }; + std::string command = std::string("cp -p \"") + file + "\" \"" + tmpFile + "\""; + runCommand(command, " * Error : An error occurred copying " + file + " to " + tmpDir); + command = std::string("mv -f \"") + tmpFile + "\" \"" + file + "\""; + runCommand(command, " * Error : An error occurred moving " + tmpFile + " to " + file); + command = std::string("rm -rf \"") + tmpDir + "\""; + systemp( command ); + runCommand(signCommand, " * Error : An error occurred while applying ad-hoc signature to " + file); + } +} diff --git a/src/Utils.h b/src/Utils.h index fa1016f..9026ae8 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -44,4 +44,7 @@ int systemp(const std::string& cmd); void changeInstallName(const std::string& binary_file, const std::string& old_name, const std::string& new_name); std::string getUserInputDirForFile(const std::string& filename); +// sign `file` with an ad-hoc code signature: required for ARM (Apple Silicon) binaries +void adhocCodeSign(const std::string& file); + #endif diff --git a/src/main.cpp b/src/main.cpp index 13ec125..4296a70 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,7 +41,7 @@ THE SOFTWARE. */ -const std::string VERSION = "1.0.1"; +const std::string VERSION = "1.0.2"; // FIXME - no memory management is done at all (anyway the program closes immediately so who cares?) |