Просмотр исходного кода

Merge pull request #58973 from bruvzg/gde_export

Rémi Verschelde 3 лет назад
Родитель
Сommit
9d732aa0cf

+ 1 - 0
doc/classes/EditorExportPlugin.xml

@@ -108,6 +108,7 @@
 			<return type="void" />
 			<argument index="0" name="path" type="String" />
 			<argument index="1" name="tags" type="PackedStringArray" />
+			<argument index="2" name="target" type="String" />
 			<description>
 				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.

+ 41 - 18
editor/editor_export.cpp

@@ -566,8 +566,8 @@ void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p
 	extra_files.push_back(ef);
 }
 
-void EditorExportPlugin::add_shared_object(const String &p_path, const Vector<String> &tags) {
-	shared_objects.push_back(SharedObject(p_path, tags));
+void EditorExportPlugin::add_shared_object(const String &p_path, const Vector<String> &p_tags, const String &p_target) {
+	shared_objects.push_back(SharedObject(p_path, p_tags, p_target));
 }
 
 void EditorExportPlugin::add_ios_framework(const String &p_path) {
@@ -660,7 +660,7 @@ void EditorExportPlugin::skip() {
 }
 
 void EditorExportPlugin::_bind_methods() {
-	ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags"), &EditorExportPlugin::add_shared_object);
+	ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags", "target"), &EditorExportPlugin::add_shared_object);
 	ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_ios_project_static_lib);
 	ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file);
 	ClassDB::bind_method(D_METHOD("add_ios_framework", "path"), &EditorExportPlugin::add_ios_framework);
@@ -680,7 +680,7 @@ void EditorExportPlugin::_bind_methods() {
 EditorExportPlugin::EditorExportPlugin() {
 }
 
-EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_containers(const Ref<EditorExportPreset> &p_preset) {
+EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug) {
 	Ref<EditorExportPlatform> platform = p_preset->get_platform();
 	List<String> feature_list;
 	platform->get_platform_features(&feature_list);
@@ -692,6 +692,14 @@ EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_contai
 		result.features_pv.push_back(E);
 	}
 
+	if (p_debug) {
+		result.features.insert("debug");
+		result.features_pv.push_back("debug");
+	} else {
+		result.features.insert("release");
+		result.features_pv.push_back("release");
+	}
+
 	if (!p_preset->get_custom_features().is_empty()) {
 		Vector<String> tmp_custom_list = p_preset->get_custom_features().split(",");
 
@@ -708,7 +716,7 @@ EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_contai
 }
 
 EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
-	FeatureContainers features = p_platform.get_feature_containers(p_preset);
+	FeatureContainers features = p_platform.get_feature_containers(p_preset, p_debug);
 	Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
 	//initial export plugin callback
 	for (int i = 0; i < export_plugins.size(); i++) {
@@ -730,7 +738,7 @@ EditorExportPlatform::ExportNotifier::~ExportNotifier() {
 	}
 }
 
-Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) {
+Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) {
 	//figure out paths of files that will be exported
 	Set<String> paths;
 	Vector<String> path_remaps;
@@ -864,7 +872,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
 		export_plugins.write[i]->_clear();
 	}
 
-	FeatureContainers feature_containers = get_feature_containers(p_preset);
+	FeatureContainers feature_containers = get_feature_containers(p_preset, p_debug);
 	Set<String> &features = feature_containers.features;
 	Vector<String> &features_pv = feature_containers.features_pv;
 
@@ -1118,7 +1126,7 @@ Error EditorExportPlatform::_add_shared_object(void *p_userdata, const SharedObj
 	return OK;
 }
 
-Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) {
+Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) {
 	EditorProgress ep("savepack", TTR("Packing"), 102, true);
 
 	// Create the temporary export directory if it doesn't exist.
@@ -1134,7 +1142,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
 	pd.f = ftmp;
 	pd.so_files = p_so_files;
 
-	Error err = export_project_files(p_preset, _save_pack_file, &pd, _add_shared_object);
+	Error err = export_project_files(p_preset, p_debug, _save_pack_file, &pd, _add_shared_object);
 
 	memdelete(ftmp); //close tmp file
 
@@ -1324,7 +1332,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
 	return OK;
 }
 
-Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
+Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) {
 	EditorProgress ep("savezip", TTR("Packing"), 102, true);
 
 	FileAccess *src_f;
@@ -1335,7 +1343,7 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co
 	zd.ep = &ep;
 	zd.zip = zip;
 
-	Error err = export_project_files(p_preset, _save_zip_file, &zd);
+	Error err = export_project_files(p_preset, p_debug, _save_zip_file, &zd);
 	if (err != OK && err != ERR_SKIP) {
 		ERR_PRINT("Failed to export project files");
 	}
@@ -1347,12 +1355,12 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co
 
 Error EditorExportPlatform::export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
 	ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
-	return save_pack(p_preset, p_path);
+	return save_pack(p_preset, p_debug, p_path);
 }
 
 Error EditorExportPlatform::export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
 	ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
-	return save_zip(p_preset, p_path);
+	return save_zip(p_preset, p_debug, p_path);
 }
 
 void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags) {
@@ -1873,7 +1881,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
 
 		int64_t embedded_pos;
 		int64_t embedded_size;
-		err = save_pack(p_preset, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size);
+		err = save_pack(p_preset, p_debug, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size);
 		if (err == OK && p_preset->get("binary_format/embed_pck")) {
 			if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) {
 				EditorNode::get_singleton()->show_warning(TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."));
@@ -1887,12 +1895,27 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
 		}
 
 		if (err == OK && !so_files.is_empty()) {
-			//if shared object files, copy them
+			// If shared object files, copy them.
 			da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
 			for (int i = 0; i < so_files.size() && err == OK; i++) {
-				err = da->copy(so_files[i].path, p_path.get_base_dir().plus_file(so_files[i].path.get_file()));
-				if (err == OK) {
-					err = sign_shared_object(p_preset, p_debug, p_path.get_base_dir().plus_file(so_files[i].path.get_file()));
+				String src_path = ProjectSettings::get_singleton()->globalize_path(so_files[i].path);
+				String target_path;
+				if (so_files[i].target.is_empty()) {
+					target_path = p_path.get_base_dir().plus_file(src_path.get_file());
+				} else {
+					target_path = p_path.get_base_dir().plus_file(so_files[i].target).plus_file(src_path.get_file());
+				}
+
+				if (da->dir_exists(src_path)) {
+					err = da->make_dir_recursive(target_path);
+					if (err == OK) {
+						err = da->copy_dir(src_path, target_path, -1, true);
+					}
+				} else {
+					err = da->copy(src_path, target_path);
+					if (err == OK) {
+						err = sign_shared_object(p_preset, p_debug, target_path);
+					}
 				}
 			}
 		}

+ 9 - 7
editor/editor_export.h

@@ -152,10 +152,12 @@ public:
 struct SharedObject {
 	String path;
 	Vector<String> tags;
+	String target;
 
-	SharedObject(const String &p_path, const Vector<String> &p_tags) :
+	SharedObject(const String &p_path, const Vector<String> &p_tags, const String &p_target) :
 			path(p_path),
-			tags(p_tags) {
+			tags(p_tags),
+			target(p_target) {
 	}
 
 	SharedObject() {}
@@ -216,7 +218,7 @@ protected:
 		~ExportNotifier();
 	};
 
-	FeatureContainers get_feature_containers(const Ref<EditorExportPreset> &p_preset);
+	FeatureContainers get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug);
 
 	bool exists_export_template(String template_file_name, String *err) const;
 	String find_export_template(String template_file_name, String *err = nullptr) const;
@@ -246,10 +248,10 @@ public:
 	virtual String get_name() const = 0;
 	virtual Ref<Texture2D> get_logo() const = 0;
 
-	Error export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr);
+	Error export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr);
 
-	Error save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr);
-	Error save_zip(const Ref<EditorExportPreset> &p_preset, const String &p_path);
+	Error save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr);
+	Error save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path);
 
 	virtual bool poll_export() { return false; }
 	virtual int get_options_count() const { return 0; }
@@ -334,7 +336,7 @@ protected:
 	Ref<EditorExportPreset> get_export_preset() const;
 
 	void add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap);
-	void add_shared_object(const String &p_path, const Vector<String> &tags);
+	void add_shared_object(const String &p_path, const Vector<String> &tags, const String &p_target = String());
 
 	void add_ios_framework(const String &p_path);
 	void add_ios_embedded_framework(const String &p_path);

+ 6 - 0
editor/editor_node.cpp

@@ -146,6 +146,7 @@
 #include "editor/plugins/editor_debugger_plugin.h"
 #include "editor/plugins/editor_preview_plugins.h"
 #include "editor/plugins/font_editor_plugin.h"
+#include "editor/plugins/gdextension_export_plugin.h"
 #include "editor/plugins/gpu_particles_2d_editor_plugin.h"
 #include "editor/plugins/gpu_particles_3d_editor_plugin.h"
 #include "editor/plugins/gpu_particles_collision_sdf_editor_plugin.h"
@@ -7094,6 +7095,11 @@ EditorNode::EditorNode() {
 
 	EditorExport::get_singleton()->add_export_plugin(export_text_to_binary_plugin);
 
+	Ref<GDExtensionExportPlugin> gdextension_export_plugin;
+	gdextension_export_plugin.instantiate();
+
+	EditorExport::get_singleton()->add_export_plugin(gdextension_export_plugin);
+
 	Ref<PackedSceneEditorTranslationParserPlugin> packed_scene_translation_parser_plugin;
 	packed_scene_translation_parser_plugin.instantiate();
 	EditorTranslationParser::get_singleton()->add_parser(packed_scene_translation_parser_plugin, EditorTranslationParser::STANDARD);

+ 138 - 0
editor/plugins/gdextension_export_plugin.h

@@ -0,0 +1,138 @@
+/*************************************************************************/
+/*  gdextension_export_plugin.h                                          */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef GDEXTENSION_EXPORT_PLUGIN_H
+#define GDEXTENSION_EXPORT_PLUGIN_H
+
+#include "editor/editor_export.h"
+
+class GDExtensionExportPlugin : public EditorExportPlugin {
+protected:
+	virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features);
+};
+
+void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p_type, const Set<String> &p_features) {
+	if (p_type != "NativeExtension") {
+		return;
+	}
+
+	Ref<ConfigFile> config;
+	config.instantiate();
+
+	Error err = config->load(p_path);
+
+	if (err != OK) {
+		return;
+	}
+
+	if (!config->has_section_key("configuration", "entry_symbol")) {
+		return;
+	}
+
+	String entry_symbol = config->get_value("configuration", "entry_symbol");
+
+	List<String> libraries;
+
+	config->get_section_keys("libraries", &libraries);
+
+	for (const String &E : libraries) {
+		Vector<String> tags = E.split(".");
+		bool all_tags_met = true;
+		for (int i = 0; i < tags.size(); i++) {
+			String tag = tags[i].strip_edges();
+			if (!p_features.has(tag)) {
+				all_tags_met = false;
+				break;
+			}
+		}
+
+		if (all_tags_met) {
+			String library_path = config->get_value("libraries", E);
+			if (!library_path.begins_with("res://")) {
+				print_line("Skipping export of out-of-project library " + library_path);
+				continue;
+			}
+			add_shared_object(library_path, tags);
+
+			if (p_features.has("iOS") && (library_path.ends_with(".a") || library_path.ends_with(".xcframework"))) {
+				String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n"
+										 "extern void add_ios_init_callback(void (*cb)());\n"
+										 "\n"
+										 "extern \"C\" void $ENTRY();\n"
+										 "void $ENTRY_init() {\n"
+										 "  if (&$ENTRY) register_dynamic_symbol((char *)\"$ENTRY\", (void *)$ENTRY);\n"
+										 "}\n"
+										 "struct $ENTRY_struct {\n"
+										 "  $ENTRY_struct() {\n"
+										 "    add_ios_init_callback($ENTRY_init);\n"
+										 "  }\n"
+										 "};\n"
+										 "$ENTRY_struct $ENTRY_struct_instance;\n\n";
+				additional_code = additional_code.replace("$ENTRY", entry_symbol);
+				add_ios_cpp_code(additional_code);
+
+				String linker_flags = "-Wl,-U,_" + entry_symbol;
+				add_ios_linker_flags(linker_flags);
+			}
+			break;
+		}
+	}
+
+	List<String> dependencies;
+
+	config->get_section_keys("dependencies", &dependencies);
+	for (const String &E : libraries) {
+		Vector<String> tags = E.split(".");
+		bool all_tags_met = true;
+		for (int i = 0; i < tags.size(); i++) {
+			String tag = tags[i].strip_edges();
+			if (!p_features.has(tag)) {
+				all_tags_met = false;
+				break;
+			}
+		}
+
+		if (all_tags_met) {
+			Dictionary dependency = config->get_value("dependencies", E);
+			for (const Variant *key = dependency.next(nullptr); key; key = dependency.next(key)) {
+				String library_path = *key;
+				String target_path = dependency[*key];
+				if (!library_path.begins_with("res://")) {
+					print_line("Skipping export of out-of-project library " + library_path);
+					continue;
+				}
+				add_shared_object(library_path, tags, target_path);
+			}
+			break;
+		}
+	}
+}
+
+#endif // GDEXTENSION_EXPORT_PLUGIN_H

+ 2 - 2
modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs

@@ -107,7 +107,7 @@ namespace GodotTools.Export
                     ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir);
 
                     // The Godot exporter expects us to pass the abi in the tags parameter
-                    exporter.AddSharedObject(soFilePath, tags: new[] { abi });
+                    exporter.AddSharedObject(soFilePath, tags: new[] { abi }, "");
                 }
             }
         }
@@ -134,7 +134,7 @@ namespace GodotTools.Export
 
                 if (platform == OS.Platforms.MacOS)
                 {
-                    exporter.AddSharedObject(tempOutputFilePath, tags: null);
+                    exporter.AddSharedObject(tempOutputFilePath, tags: null, "");
                 }
                 else
                 {

+ 7 - 7
platform/android/export/export_plugin.cpp

@@ -2256,9 +2256,9 @@ String EditorExportPlatformAndroid::get_apk_expansion_fullpath(const Ref<EditorE
 	return fullpath;
 }
 
-Error EditorExportPlatformAndroid::save_apk_expansion_file(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
+Error EditorExportPlatformAndroid::save_apk_expansion_file(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) {
 	String fullpath = get_apk_expansion_fullpath(p_preset, p_path);
-	Error err = save_pack(p_preset, fullpath);
+	Error err = save_pack(p_preset, p_debug, fullpath);
 	return err;
 }
 
@@ -2576,7 +2576,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 			CustomExportData user_data;
 			user_data.assets_directory = assets_directory;
 			user_data.debug = p_debug;
-			err = export_project_files(p_preset, rename_and_store_file_in_gradle_project, &user_data, copy_gradle_so);
+			err = export_project_files(p_preset, p_debug, rename_and_store_file_in_gradle_project, &user_data, copy_gradle_so);
 			if (err != OK) {
 				EditorNode::add_io_error(TTR("Could not export project files to gradle project\n"));
 				return err;
@@ -2589,7 +2589,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 			}
 		} else {
 			print_verbose("Saving apk expansion file..");
-			err = save_apk_expansion_file(p_preset, p_path);
+			err = save_apk_expansion_file(p_preset, p_debug, p_path);
 			if (err != OK) {
 				EditorNode::add_io_error(TTR("Could not write expansion package file!"));
 				return err;
@@ -2915,10 +2915,10 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 		APKExportData ed;
 		ed.ep = &ep;
 		ed.apk = unaligned_apk;
-		err = export_project_files(p_preset, ignore_apk_file, &ed, save_apk_so);
+		err = export_project_files(p_preset, p_debug, ignore_apk_file, &ed, save_apk_so);
 	} else {
 		if (apk_expansion) {
-			err = save_apk_expansion_file(p_preset, p_path);
+			err = save_apk_expansion_file(p_preset, p_debug, p_path);
 			if (err != OK) {
 				EditorNode::add_io_error(TTR("Could not write expansion package file!"));
 				return err;
@@ -2927,7 +2927,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
 			APKExportData ed;
 			ed.ep = &ep;
 			ed.apk = unaligned_apk;
-			err = export_project_files(p_preset, save_apk_file, &ed, save_apk_so);
+			err = export_project_files(p_preset, p_debug, save_apk_file, &ed, save_apk_so);
 		}
 	}
 

+ 1 - 1
platform/android/export/export_plugin.h

@@ -210,7 +210,7 @@ public:
 
 	String get_apk_expansion_fullpath(const Ref<EditorExportPreset> &p_preset, const String &p_path);
 
-	Error save_apk_expansion_file(const Ref<EditorExportPreset> &p_preset, const String &p_path);
+	Error save_apk_expansion_file(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path);
 
 	void get_command_line_flags(const Ref<EditorExportPreset> &p_preset, const String &p_path, int p_flags, Vector<uint8_t> &r_command_line_flags);
 

+ 1 - 1
platform/iphone/export/export_plugin.cpp

@@ -1440,7 +1440,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
 	}
 	String pack_path = dest_dir + binary_name + ".pck";
 	Vector<SharedObject> libraries;
-	Error err = save_pack(p_preset, pack_path, &libraries);
+	Error err = save_pack(p_preset, p_debug, pack_path, &libraries);
 	if (err) {
 		return err;
 	}

+ 1 - 1
platform/javascript/export/export_plugin.cpp

@@ -440,7 +440,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
 	// Export pck and shared objects
 	Vector<SharedObject> shared_objects;
 	String pck_path = base_path + ".pck";
-	Error error = save_pack(p_preset, pck_path, &shared_objects);
+	Error error = save_pack(p_preset, p_debug, pck_path, &shared_objects);
 	if (error != OK) {
 		EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + pck_path);
 		return error;

+ 22 - 13
platform/osx/export/export_plugin.cpp

@@ -458,7 +458,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset
 	return OK;
 }
 
-Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path) {
+Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn) {
 	bool force_builtin_codesign = EditorSettings::get_singleton()->get("export/macos/force_builtin_codesign");
 	bool ad_hoc = (p_preset->get("codesign/identity") == "" || p_preset->get("codesign/identity") == "-");
 
@@ -467,10 +467,10 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
 #ifdef MODULE_REGEX_ENABLED
 
 #ifdef OSX_ENABLED
-		if (p_preset->get("codesign/timestamp")) {
+		if (p_preset->get("codesign/timestamp") && p_warn) {
 			WARN_PRINT("Timestamping is not compatible with ad-hoc signature, and was disabled!");
 		}
-		if (p_preset->get("codesign/hardened_runtime")) {
+		if (p_preset->get("codesign/hardened_runtime") && p_warn) {
 			WARN_PRINT("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!");
 		}
 #endif
@@ -490,14 +490,18 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
 		List<String> args;
 		if (p_preset->get("codesign/timestamp")) {
 			if (ad_hoc) {
-				WARN_PRINT("Timestamping is not compatible with ad-hoc signature, and was disabled!");
+				if (p_warn) {
+					WARN_PRINT("Timestamping is not compatible with ad-hoc signature, and was disabled!");
+				}
 			} else {
 				args.push_back("--timestamp");
 			}
 		}
 		if (p_preset->get("codesign/hardened_runtime")) {
 			if (ad_hoc) {
-				WARN_PRINT("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!");
+				if (p_warn) {
+					WARN_PRINT("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!");
+				}
 			} else {
 				args.push_back("--options");
 				args.push_back("runtime");
@@ -577,7 +581,7 @@ Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset
 		}
 
 		if (extensions_to_sign.find(current_file.get_extension()) > -1) {
-			Error code_sign_error{ _code_sign(p_preset, current_file_path, p_ent_path) };
+			Error code_sign_error{ _code_sign(p_preset, current_file_path, p_ent_path, false) };
 			if (code_sign_error != OK) {
 				return code_sign_error;
 			}
@@ -621,7 +625,7 @@ Error EditorExportPlatformOSX::_copy_and_sign_files(DirAccessRef &dir_access, co
 			// 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);
+			err = _code_sign(p_preset, p_in_app_path, p_ent_path, false);
 		}
 	}
 	return err;
@@ -1046,7 +1050,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
 
 		String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck";
 		Vector<SharedObject> shared_objects;
-		err = save_pack(p_preset, pack_path, &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/enable");
@@ -1213,7 +1217,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
 				String hlp_path = helpers[i];
 				err = da->copy(hlp_path, tmp_app_path_name + "/Contents/Helpers/" + hlp_path.get_file());
 				if (err == OK && sign_enabled) {
-					err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Helpers/" + hlp_path.get_file(), hlp_ent_path);
+					err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Helpers/" + hlp_path.get_file(), hlp_ent_path, false);
 				}
 				FileAccess::set_unix_permissions(tmp_app_path_name + "/Contents/Helpers/" + hlp_path.get_file(), 0755);
 			}
@@ -1238,8 +1242,13 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
 			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);
-				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 (shared_objects[i].target.is_empty()) {
+					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.plus_file(shared_objects[i].target).plus_file(src_path.get_file());
+					err = _copy_and_sign_files(da, src_path, path_in_app, sign_enabled, p_preset, ent_path, false);
+				}
 				if (err != OK) {
 					break;
 				}
@@ -1257,7 +1266,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_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);
+					err = _code_sign(p_preset, tmp_app_path_name + "/" + dylibs_found[i], ent_path, false);
 				}
 			}
 		}
@@ -1282,7 +1291,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
 				if (ep.step(TTR("Code signing DMG"), 3)) {
 					return ERR_SKIP;
 				}
-				err = _code_sign(p_preset, p_path, ent_path);
+				err = _code_sign(p_preset, p_path, ent_path, false);
 			}
 		} else if (export_format == "zip") {
 			// Create ZIP.

+ 1 - 1
platform/osx/export/export_plugin.h

@@ -56,7 +56,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
 	void _make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data);
 
 	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(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn = true);
 	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,

+ 1 - 1
platform/uwp/export/export_plugin.cpp

@@ -416,7 +416,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p
 	EditorNode::progress_add_task("project_files", "Project Files", 100);
 	packager.set_progress_task("project_files");
 
-	err = export_project_files(p_preset, save_appx_file, &packager);
+	err = export_project_files(p_preset, p_debug, save_appx_file, &packager);
 
 	EditorNode::progress_end_task("project_files");