diff options
Diffstat (limited to 'platform/macos/export')
-rw-r--r-- | platform/macos/export/export_plugin.cpp | 153 | ||||
-rw-r--r-- | platform/macos/export/export_plugin.h | 2 | ||||
-rw-r--r-- | platform/macos/export/lipo.cpp | 6 | ||||
-rw-r--r-- | platform/macos/export/lipo.h | 5 | ||||
-rw-r--r-- | platform/macos/export/macho.cpp | 16 | ||||
-rw-r--r-- | platform/macos/export/macho.h | 5 | ||||
-rw-r--r-- | platform/macos/export/plist.cpp | 6 | ||||
-rw-r--r-- | platform/macos/export/plist.h | 5 |
8 files changed, 82 insertions, 116 deletions
diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp index 070830c486..de6016cb9b 100644 --- a/platform/macos/export/export_plugin.cpp +++ b/platform/macos/export/export_plugin.cpp @@ -31,6 +31,8 @@ #include "export_plugin.h" #include "codesign.h" +#include "lipo.h" +#include "macho.h" #include "core/string/translation.h" #include "editor/editor_node.h" @@ -381,7 +383,7 @@ void EditorExportPlatformMacOS::_fix_plist(const Ref<EditorExportPreset> &p_pres if (lines[i].find("$binary") != -1) { strnew += lines[i].replace("$binary", p_binary) + "\n"; } else if (lines[i].find("$name") != -1) { - strnew += lines[i].replace("$name", ProjectSettings::get_singleton()->get("application/config/name")) + "\n"; + strnew += lines[i].replace("$name", GLOBAL_GET("application/config/name")) + "\n"; } else if (lines[i].find("$bundle_identifier") != -1) { strnew += lines[i].replace("$bundle_identifier", p_preset->get("application/bundle_identifier")) + "\n"; } else if (lines[i].find("$short_version") != -1) { @@ -471,7 +473,7 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres case 1: { // "rcodesign" print_verbose("using rcodesign notarization..."); - String rcodesign = EditorSettings::get_singleton()->get("export/macos/rcodesign").operator String(); + String rcodesign = EDITOR_GET("export/macos/rcodesign").operator String(); if (rcodesign.is_empty()) { add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("rcodesign path is not set. Configure rcodesign path in the Editor Settings (Export > macOS > rcodesign).")); return Error::FAILED; @@ -634,7 +636,7 @@ Error EditorExportPlatformMacOS::_code_sign(const Ref<EditorExportPreset> &p_pre case 2: { // "rcodesign" print_verbose("using rcodesign codesign..."); - String rcodesign = EditorSettings::get_singleton()->get("export/macos/rcodesign").operator String(); + String rcodesign = EDITOR_GET("export/macos/rcodesign").operator String(); if (rcodesign.is_empty()) { add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("Xrcodesign path is not set. Configure rcodesign path in the Editor Settings (Export > macOS > rcodesign).")); return Error::FAILED; @@ -754,6 +756,7 @@ Error EditorExportPlatformMacOS::_code_sign_directory(const Ref<EditorExportPres if (extensions_to_sign.is_empty()) { extensions_to_sign.push_back("dylib"); extensions_to_sign.push_back("framework"); + extensions_to_sign.push_back(""); } Error dir_access_error; @@ -778,6 +781,10 @@ Error EditorExportPlatformMacOS::_code_sign_directory(const Ref<EditorExportPres if (code_sign_error != OK) { return code_sign_error; } + if (is_executable(current_file_path)) { + // chmod with 0755 if the file is executable. + FileAccess::set_unix_permissions(current_file_path, 0755); + } } else if (dir_access->current_is_dir()) { Error code_sign_error{ _code_sign_directory(p_preset, current_file_path, p_ent_path, p_should_error_on_non_code) }; if (code_sign_error != OK) { @@ -799,6 +806,14 @@ Error EditorExportPlatformMacOS::_copy_and_sign_files(Ref<DirAccess> &dir_access const String &p_in_app_path, bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset, const String &p_ent_path, bool p_should_error_on_non_code_sign) { + static Vector<String> extensions_to_sign; + + if (extensions_to_sign.is_empty()) { + extensions_to_sign.push_back("dylib"); + extensions_to_sign.push_back("framework"); + extensions_to_sign.push_back(""); + } + Error err{ OK }; if (dir_access->dir_exists(p_src_path)) { #ifndef UNIX_ENABLED @@ -818,7 +833,13 @@ Error EditorExportPlatformMacOS::_copy_and_sign_files(Ref<DirAccess> &dir_access // If it is a directory, find and sign all dynamic libraries. err = _code_sign_directory(p_preset, p_in_app_path, p_ent_path, p_should_error_on_non_code_sign); } else { - err = _code_sign(p_preset, p_in_app_path, p_ent_path, false); + if (extensions_to_sign.find(p_in_app_path.get_extension()) > -1) { + err = _code_sign(p_preset, p_in_app_path, p_ent_path, false); + } + if (is_executable(p_in_app_path)) { + // chmod with 0755 if the file is executable. + FileAccess::set_unix_permissions(p_in_app_path, 0755); + } } } return err; @@ -877,6 +898,17 @@ Error EditorExportPlatformMacOS::_create_dmg(const String &p_dmg_path, const Str return OK; } +bool EditorExportPlatformMacOS::is_shbang(const String &p_path) const { + Ref<FileAccess> fb = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_V_MSG(fb.is_null(), false, vformat("Can't open file: \"%s\".", p_path)); + uint16_t magic = fb->get_16(); + return (magic == 0x2123); +} + +bool EditorExportPlatformMacOS::is_executable(const String &p_path) const { + return MachO::is_macho(p_path) || LipO::is_lipo(p_path) || is_shbang(p_path); +} + Error EditorExportPlatformMacOS::_export_debug_script(const Ref<EditorExportPreset> &p_preset, const String &p_app_name, const String &p_pkg_name, const String &p_path) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE); if (f.is_null()) { @@ -950,8 +982,8 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p String binary_to_use = "godot_macos_" + String(p_debug ? "debug" : "release") + "." + architecture; String pkg_name; - if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") { - pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name")); + if (String(GLOBAL_GET("application/config/name")) != "") { + pkg_name = String(GLOBAL_GET("application/config/name")); } else { pkg_name = "Unnamed"; } @@ -1041,7 +1073,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p } } - Dictionary appnames = ProjectSettings::get_singleton()->get("application/config/name_localized"); + Dictionary appnames = GLOBAL_GET("application/config/name_localized"); Dictionary microphone_usage_descriptions = p_preset->get("privacy/microphone_usage_description_localized"); Dictionary camera_usage_descriptions = p_preset->get("privacy/camera_usage_description_localized"); Dictionary location_usage_descriptions = p_preset->get("privacy/location_usage_description_localized"); @@ -1055,7 +1087,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p Dictionary removable_volumes_usage_descriptions = p_preset->get("privacy/removable_volumes_usage_description_localized"); Dictionary copyrights = p_preset->get("application/copyright_localized"); - Vector<String> translations = ProjectSettings::get_singleton()->get("internationalization/locale/translations"); + Vector<String> translations = GLOBAL_GET("internationalization/locale/translations"); if (translations.size() > 0) { { String fname = tmp_app_path_name + "/Contents/Resources/en.lproj"; @@ -1063,7 +1095,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p Ref<FileAccess> f = FileAccess::open(fname + "/InfoPlist.strings", FileAccess::WRITE); f->store_line("/* Localized versions of Info.plist keys */"); f->store_line(""); - f->store_line("CFBundleDisplayName = \"" + ProjectSettings::get_singleton()->get("application/config/name").operator String() + "\";"); + f->store_line("CFBundleDisplayName = \"" + GLOBAL_GET("application/config/name").operator String() + "\";"); if (!((String)p_preset->get("privacy/microphone_usage_description")).is_empty()) { f->store_line("NSMicrophoneUsageDescription = \"" + p_preset->get("privacy/microphone_usage_description").operator String() + "\";"); } @@ -1158,11 +1190,8 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p // Now process our template. bool found_binary = false; - Vector<String> dylibs_found; while (ret == UNZ_OK && err == OK) { - bool is_execute = false; - // Get filename. unz_file_info info; char fname[16384]; @@ -1219,7 +1248,6 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p continue; // skip } found_binary = true; - is_execute = true; file = "Contents/MacOS/" + pkg_name; } @@ -1229,7 +1257,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p if (p_preset->get("application/icon") != "") { iconpath = p_preset->get("application/icon"); } else { - iconpath = ProjectSettings::get_singleton()->get("application/config/icon"); + iconpath = GLOBAL_GET("application/config/icon"); } if (!iconpath.is_empty()) { @@ -1251,25 +1279,6 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p } if (data.size() > 0) { - if (file.find("/data.mono.macos.release_debug." + architecture + "/") != -1) { - if (!p_debug) { - ret = unzGoToNextFile(src_pkg_zip); - continue; // skip - } - file = file.replace("/data.mono.macos.release_debug." + architecture + "/", "/GodotSharp/"); - } - if (file.find("/data.mono.macos.release." + architecture + "/") != -1) { - if (p_debug) { - ret = unzGoToNextFile(src_pkg_zip); - continue; // skip - } - file = file.replace("/data.mono.macos.release." + architecture + "/", "/GodotSharp/"); - } - - if (file.ends_with(".dylib")) { - dylibs_found.push_back(file); - } - print_verbose("ADDING: " + file + " size: " + itos(data.size())); // Write it into our application bundle. @@ -1285,7 +1294,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p if (f.is_valid()) { f->store_buffer(data.ptr(), data.size()); f.unref(); - if (is_execute) { + if (is_executable(file)) { // chmod with 0755 if the file is executable. FileAccess::set_unix_permissions(file, 0755); } @@ -1324,12 +1333,35 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p return ERR_SKIP; } + // See if we can code sign our new package. + bool sign_enabled = (p_preset->get("codesign/codesign").operator int() > 0); + bool ad_hoc = false; + int codesign_tool = p_preset->get("codesign/codesign"); + switch (codesign_tool) { + case 1: { // built-in ad-hoc + ad_hoc = true; + } break; + case 2: { // "rcodesign" + ad_hoc = p_preset->get("codesign/certificate_file").operator String().is_empty() || p_preset->get("codesign/certificate_password").operator String().is_empty(); + } break; +#ifdef MACOS_ENABLED + case 3: { // "codesign" + ad_hoc = (p_preset->get("codesign/identity") == "" || p_preset->get("codesign/identity") == "-"); + } break; +#endif + default: { + }; + } + String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck"; Vector<SharedObject> shared_objects; err = save_pack(p_preset, p_debug, pack_path, &shared_objects); - // See if we can code sign our new package. - bool sign_enabled = (p_preset->get("codesign/codesign").operator int() > 0); + bool lib_validation = p_preset->get("codesign/entitlements/disable_library_validation"); + if (!shared_objects.is_empty() && sign_enabled && ad_hoc && !lib_validation) { + add_message(EXPORT_MESSAGE_INFO, TTR("Entitlements Modified"), TTR("Ad-hoc signed applications require the 'Disable Library Validation' entitlement to load dynamic libraries.")); + lib_validation = true; + } String ent_path = p_preset->get("codesign/entitlements/custom_file"); String hlp_ent_path = EditorPaths::get_singleton()->get_cache_dir().path_join(pkg_name + "_helper.entitlements"); @@ -1365,7 +1397,7 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p } } - if ((bool)p_preset->get("codesign/entitlements/disable_library_validation")) { + if (lib_validation) { ent_f->store_line("<key>com.apple.security.cs.disable-library-validation</key>"); ent_f->store_line("<true/>"); } @@ -1495,32 +1527,6 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p } } - bool ad_hoc = false; - int codesign_tool = p_preset->get("codesign/codesign"); - switch (codesign_tool) { - case 1: { // built-in ad-hoc - ad_hoc = true; - } break; - case 2: { // "rcodesign" - ad_hoc = p_preset->get("codesign/certificate_file").operator String().is_empty() || p_preset->get("codesign/certificate_password").operator String().is_empty(); - } break; -#ifdef MACOS_ENABLED - case 3: { // "codesign" - ad_hoc = (p_preset->get("codesign/identity") == "" || p_preset->get("codesign/identity") == "-"); - } break; -#endif - default: { - }; - } - - if (err == OK) { - bool lib_validation = p_preset->get("codesign/entitlements/disable_library_validation"); - if ((!dylibs_found.is_empty() || !shared_objects.is_empty()) && sign_enabled && ad_hoc && !lib_validation) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("Ad-hoc signed applications require the 'Disable Library Validation' entitlement to load dynamic libraries.")); - err = ERR_CANT_CREATE; - } - } - if (err == OK) { Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); for (int i = 0; i < shared_objects.size(); i++) { @@ -1529,8 +1535,9 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p String path_in_app = tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file(); err = _copy_and_sign_files(da, src_path, path_in_app, sign_enabled, p_preset, ent_path, true); } else { - String path_in_app = tmp_app_path_name.path_join(shared_objects[i].target).path_join(src_path.get_file()); - err = _copy_and_sign_files(da, src_path, path_in_app, sign_enabled, p_preset, ent_path, false); + String path_in_app = tmp_app_path_name.path_join(shared_objects[i].target); + tmp_app_dir->make_dir_recursive(path_in_app); + err = _copy_and_sign_files(da, src_path, path_in_app.path_join(src_path.get_file()), sign_enabled, p_preset, ent_path, false); } if (err != OK) { break; @@ -1546,14 +1553,6 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p } } - if (sign_enabled) { - for (int i = 0; i < dylibs_found.size(); i++) { - if (err == OK) { - err = _code_sign(p_preset, tmp_app_path_name + "/" + dylibs_found[i], ent_path, false); - } - } - } - if (err == OK && sign_enabled) { if (ep.step(TTR("Code signing bundle"), 2)) { return ERR_SKIP; @@ -1683,8 +1682,6 @@ void EditorExportPlatformMacOS::_zip_folder_recursive(zipFile &p_zip, const Stri } else if (da->current_is_dir()) { _zip_folder_recursive(p_zip, p_root_path, p_folder.path_join(f), p_pkg_name); } else { - bool is_executable = (p_folder.ends_with("MacOS") && (f == p_pkg_name)) || p_folder.ends_with("Helpers") || f.ends_with(".command"); - OS::DateTime dt = OS::get_singleton()->get_datetime(); zip_fileinfo zipfi; @@ -1698,7 +1695,7 @@ void EditorExportPlatformMacOS::_zip_folder_recursive(zipFile &p_zip, const Stri // 0100000: regular file type // 0000755: permissions rwxr-xr-x // 0000644: permissions rw-r--r-- - uint32_t _mode = (is_executable ? 0100755 : 0100644); + uint32_t _mode = (is_executable(dir.path_join(f)) ? 0100755 : 0100644); zipfi.external_fa = (_mode << 16L) | !(_mode & 0200); zipfi.internal_fa = 0; @@ -1855,7 +1852,7 @@ bool EditorExportPlatformMacOS::has_valid_project_configuration(const Ref<Editor valid = false; } - String rcodesign = EditorSettings::get_singleton()->get("export/macos/rcodesign").operator String(); + String rcodesign = EDITOR_GET("export/macos/rcodesign").operator String(); if (rcodesign.is_empty()) { err += TTR("Notarization: rcodesign path is not set. Configure rcodesign path in the Editor Settings (Export > macOS > rcodesign).") + "\n"; valid = false; @@ -1878,7 +1875,7 @@ bool EditorExportPlatformMacOS::has_valid_project_configuration(const Ref<Editor valid = false; } } else if (codesign_tool == 2) { - String rcodesign = EditorSettings::get_singleton()->get("export/macos/rcodesign").operator String(); + String rcodesign = EDITOR_GET("export/macos/rcodesign").operator String(); if (rcodesign.is_empty()) { err += TTR("Code signing: rcodesign path is not set. Configure rcodesign path in the Editor Settings (Export > macOS > rcodesign).") + "\n"; valid = false; diff --git a/platform/macos/export/export_plugin.h b/platform/macos/export/export_plugin.h index 87790129d3..b6ad587caa 100644 --- a/platform/macos/export/export_plugin.h +++ b/platform/macos/export/export_plugin.h @@ -97,6 +97,7 @@ class EditorExportPlatformMacOS : public EditorExportPlatform { return true; } + bool is_shbang(const String &p_path) const; protected: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override; @@ -108,6 +109,7 @@ public: virtual String get_os_name() const override { return "macOS"; } virtual Ref<Texture2D> get_logo() const override { return logo; } + virtual bool is_executable(const String &p_path) const override; virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override { List<String> list; if (use_dmg()) { diff --git a/platform/macos/export/lipo.cpp b/platform/macos/export/lipo.cpp index 82baf18c52..76d4eee418 100644 --- a/platform/macos/export/lipo.cpp +++ b/platform/macos/export/lipo.cpp @@ -28,12 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "modules/modules_enabled.gen.h" // For regex. - #include "lipo.h" -#ifdef MODULE_REGEX_ENABLED - bool LipO::is_lipo(const String &p_path) { Ref<FileAccess> fb = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V_MSG(fb.is_null(), false, vformat("LipO: Can't open file: \"%s\".", p_path)); @@ -232,5 +228,3 @@ void LipO::close() { LipO::~LipO() { close(); } - -#endif // MODULE_REGEX_ENABLED diff --git a/platform/macos/export/lipo.h b/platform/macos/export/lipo.h index 6378f9899c..bd8b7f6f2c 100644 --- a/platform/macos/export/lipo.h +++ b/platform/macos/export/lipo.h @@ -35,12 +35,9 @@ #include "core/io/file_access.h" #include "core/object/ref_counted.h" -#include "modules/modules_enabled.gen.h" // For regex. #include "macho.h" -#ifdef MODULE_REGEX_ENABLED - class LipO : public RefCounted { struct FatArch { uint32_t cputype; @@ -71,6 +68,4 @@ public: ~LipO(); }; -#endif // MODULE_REGEX_ENABLED - #endif // MACOS_LIPO_H diff --git a/platform/macos/export/macho.cpp b/platform/macos/export/macho.cpp index e6e67eff06..642d99e098 100644 --- a/platform/macos/export/macho.cpp +++ b/platform/macos/export/macho.cpp @@ -28,24 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "modules/modules_enabled.gen.h" // For regex. - #include "macho.h" -#ifdef MODULE_REGEX_ENABLED - uint32_t MachO::seg_align(uint64_t p_vmaddr, uint32_t p_min, uint32_t p_max) { - uint32_t align = p_max; + uint32_t salign = p_max; if (p_vmaddr != 0) { uint64_t seg_align = 1; - align = 0; + salign = 0; while ((seg_align & p_vmaddr) == 0) { seg_align = seg_align << 1; - align++; + salign++; } - align = CLAMP(align, p_min, p_max); + salign = CLAMP(salign, p_min, p_max); } - return align; + return salign; } bool MachO::alloc_signature(uint64_t p_size) { @@ -544,5 +540,3 @@ bool MachO::set_signature_size(uint64_t p_size) { } return true; } - -#endif // MODULE_REGEX_ENABLED diff --git a/platform/macos/export/macho.h b/platform/macos/export/macho.h index 0d42a7013f..0c954e66b1 100644 --- a/platform/macos/export/macho.h +++ b/platform/macos/export/macho.h @@ -37,9 +37,6 @@ #include "core/crypto/crypto_core.h" #include "core/io/file_access.h" #include "core/object/ref_counted.h" -#include "modules/modules_enabled.gen.h" // For regex. - -#ifdef MODULE_REGEX_ENABLED class MachO : public RefCounted { struct MachHeader { @@ -210,6 +207,4 @@ public: bool set_signature_size(uint64_t p_size); }; -#endif // MODULE_REGEX_ENABLED - #endif // MACOS_MACHO_H diff --git a/platform/macos/export/plist.cpp b/platform/macos/export/plist.cpp index 36de9dd34b..cad014e65b 100644 --- a/platform/macos/export/plist.cpp +++ b/platform/macos/export/plist.cpp @@ -28,12 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "modules/modules_enabled.gen.h" // For regex. - #include "plist.h" -#ifdef MODULE_REGEX_ENABLED - Ref<PListNode> PListNode::new_array() { Ref<PListNode> node = memnew(PListNode()); ERR_FAIL_COND_V(node.is_null(), Ref<PListNode>()); @@ -566,5 +562,3 @@ String PList::save_text() const { Ref<PListNode> PList::get_root() { return root; } - -#endif // MODULE_REGEX_ENABLED diff --git a/platform/macos/export/plist.h b/platform/macos/export/plist.h index b3c51a9635..97331a3629 100644 --- a/platform/macos/export/plist.h +++ b/platform/macos/export/plist.h @@ -35,9 +35,6 @@ #include "core/crypto/crypto_core.h" #include "core/io/file_access.h" -#include "modules/modules_enabled.gen.h" // For regex. - -#ifdef MODULE_REGEX_ENABLED class PListNode; @@ -111,6 +108,4 @@ public: ~PListNode() {} }; -#endif // MODULE_REGEX_ENABLED - #endif // MACOS_PLIST_H |