Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] OSX: Add signing of directory structure when exporting for OSX #56250

Merged
merged 1 commit into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion doc/classes/EditorExportPlugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,22 @@
Adds a static lib from the given [code]path[/code] to the iOS project.
</description>
</method>
<method name="add_osx_plugin_file">
<return type="void" />
<argument index="0" name="path" type="String" />
<description>
Adds file or directory matching [code]path[/code] to [code]PlugIns[/code] directory of macOS app bundle.
[b]Note:[/b] This is useful only for macOS exports.
</description>
</method>
<method name="add_shared_object">
<return type="void" />
<argument index="0" name="path" type="String" />
<argument index="1" name="tags" type="PoolStringArray" />
<description>
Adds a shared object with the given [code]tags[/code] and destination [code]path[/code].
Adds a shared object or a directory containing only shared objects with the given [code]tags[/code] and destination [code]path[/code].
[b]Note:[/b] In case of macOS exports, those shared objects will be added to [code]Frameworks[/code] directory of app bundle.
In case of a directory code-sign will error if you place non code object in directory.
</description>
</method>
<method name="skip">
Expand Down
9 changes: 9 additions & 0 deletions editor/editor_export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,14 @@ String EditorExportPlugin::get_ios_cpp_code() const {
return ios_cpp_code;
}

void EditorExportPlugin::add_osx_plugin_file(const String &p_path) {
osx_plugin_files.push_back(p_path);
}

const Vector<String> &EditorExportPlugin::get_osx_plugin_files() const {
return osx_plugin_files;
}

void EditorExportPlugin::add_ios_project_static_lib(const String &p_path) {
ios_project_static_libs.push_back(p_path);
}
Expand Down Expand Up @@ -596,6 +604,7 @@ void EditorExportPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_ios_linker_flags", "flags"), &EditorExportPlugin::add_ios_linker_flags);
ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_ios_bundle_file);
ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code);
ClassDB::bind_method(D_METHOD("add_osx_plugin_file", "path"), &EditorExportPlugin::add_osx_plugin_file);
ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip);

BIND_VMETHOD(MethodInfo("_export_file", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "type"), PropertyInfo(Variant::POOL_STRING_ARRAY, "features")));
Expand Down
7 changes: 7 additions & 0 deletions editor/editor_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ class EditorExportPlugin : public Reference {
Vector<String> ios_bundle_files;
String ios_cpp_code;

Vector<String> osx_plugin_files;

_FORCE_INLINE_ void _clear() {
shared_objects.clear();
extra_files.clear();
Expand All @@ -303,6 +305,7 @@ class EditorExportPlugin : public Reference {
ios_plist_content = "";
ios_linker_flags = "";
ios_cpp_code = "";
osx_plugin_files.clear();
}

void _export_file_script(const String &p_path, const String &p_type, const PoolVector<String> &p_features);
Expand All @@ -324,6 +327,8 @@ class EditorExportPlugin : public Reference {
void add_ios_bundle_file(const String &p_path);
void add_ios_cpp_code(const String &p_code);

void add_osx_plugin_file(const String &p_path);

void skip();

virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features);
Expand All @@ -340,6 +345,8 @@ class EditorExportPlugin : public Reference {
Vector<String> get_ios_bundle_files() const;
String get_ios_cpp_code() const;

const Vector<String> &get_osx_plugin_files() const;

EditorExportPlugin();
};

Expand Down
131 changes: 115 additions & 16 deletions platform/osx/export/export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ class EditorExportPlatformOSX : public EditorExportPlatform {

Error _notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path);
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path);
Error _code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path,
bool p_should_error_on_non_code = true);
Error _copy_and_sign_files(DirAccessRef &dir_access, const String &p_src_path, 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);
Error _export_osx_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin, const String &p_app_path_name,
DirAccessRef &dir_access, bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset,
const String &p_ent_path);
Error _create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name);
void _zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name);

Expand Down Expand Up @@ -528,6 +536,101 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
return OK;
}

Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path,
const String &p_ent_path, bool p_should_error_on_non_code) {
#ifdef OSX_ENABLED
static Vector<String> extensions_to_sign;

if (extensions_to_sign.empty()) {
extensions_to_sign.push_back("dylib");
extensions_to_sign.push_back("framework");
}

Error dir_access_error;
DirAccessRef dir_access{ DirAccess::open(p_path, &dir_access_error) };

if (dir_access_error != OK) {
return dir_access_error;
}

dir_access->list_dir_begin();
String current_file{ dir_access->get_next() };
while (!current_file.empty()) {
String current_file_path{ p_path.plus_file(current_file) };

if (current_file == ".." || current_file == ".") {
current_file = dir_access->get_next();
continue;
}

if (extensions_to_sign.find(current_file.get_extension()) > -1) {
Error code_sign_error{ _code_sign(p_preset, current_file_path, p_ent_path) };
if (code_sign_error != OK) {
return code_sign_error;
}
} 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) {
return code_sign_error;
}
} else if (p_should_error_on_non_code) {
ERR_PRINT(vformat("Cannot sign file %s.", current_file));
return Error::FAILED;
}

current_file = dir_access->get_next();
}
#endif

return OK;
}

Error EditorExportPlatformOSX::_copy_and_sign_files(DirAccessRef &dir_access, const String &p_src_path,
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) {
Error err{ OK };
if (dir_access->dir_exists(p_src_path)) {
#ifndef UNIX_ENABLED
WARN_PRINT("Relative symlinks are not supported, exported " + p_src_path.get_file() + " might be broken!");
#endif
print_verbose("export framework: " + p_src_path + " -> " + p_in_app_path);
err = dir_access->make_dir_recursive(p_in_app_path);
if (err == OK) {
err = dir_access->copy_dir(p_src_path, p_in_app_path, -1, true);
}
} else {
print_verbose("export dylib: " + p_src_path + " -> " + p_in_app_path);
err = dir_access->copy(p_src_path, p_in_app_path);
}
if (err == OK && p_sign_enabled) {
if (dir_access->dir_exists(p_src_path) && p_src_path.get_extension().empty()) {
// 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);
}
}
return err;
}

Error EditorExportPlatformOSX::_export_osx_plugins_for(Ref<EditorExportPlugin> p_editor_export_plugin,
const String &p_app_path_name, DirAccessRef &dir_access,
bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset,
const String &p_ent_path) {
Error error{ OK };
const Vector<String> &osx_plugins{ p_editor_export_plugin->get_osx_plugin_files() };
for (int i = 0; i < osx_plugins.size(); ++i) {
String src_path{ ProjectSettings::get_singleton()->globalize_path(osx_plugins[i]) };
String path_in_app{ p_app_path_name + "/Contents/PlugIns/" + src_path.get_file() };
error = _copy_and_sign_files(dir_access, src_path, path_in_app, p_sign_enabled, p_preset, p_ent_path, false);
if (error != OK) {
break;
}
}
return error;
}

Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name) {
List<String> args;

Expand Down Expand Up @@ -914,27 +1017,23 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}

if (err == OK) {
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
for (int i = 0; i < shared_objects.size(); i++) {
String src_path = ProjectSettings::get_singleton()->globalize_path(shared_objects[i].path);
if (da->dir_exists(src_path)) {
#ifndef UNIX_ENABLED
WARN_PRINT("Relative symlinks are not supported, exported " + src_path.get_file() + " might be broken!");
#endif
print_verbose("export framework: " + src_path + " -> " + tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file());
err = da->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file());
if (err == OK) {
err = da->copy_dir(src_path, tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file(), -1, true);
}
} else {
print_verbose("export dylib: " + src_path + " -> " + tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file());
err = da->copy(src_path, tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file());
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);
if (err != OK) {
break;
}
if (err == OK && sign_enabled) {
err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file(), ent_path);
}

Vector<Ref<EditorExportPlugin>> export_plugins{ EditorExport::get_singleton()->get_export_plugins() };
for (int i = 0; i < export_plugins.size(); ++i) {
err = _export_osx_plugins_for(export_plugins[i], tmp_app_path_name, da, sign_enabled, p_preset, ent_path);
if (err != OK) {
break;
}
}
memdelete(da);
}

if (sign_enabled) {
Expand Down