Browse Source

Add GDNative Framework loading and export support.

bruvzg 4 years ago
parent
commit
53f05c9167

+ 0 - 1
drivers/windows/dir_access_windows.h

@@ -83,7 +83,6 @@ public:
 	virtual String read_link(String p_file) { return p_file; };
 	virtual Error create_link(String p_source, String p_target) { return FAILED; };
 
-	//virtual FileType get_file_type() const;
 	uint64_t get_space_left();
 
 	virtual String get_filesystem_type() const;

+ 11 - 1
modules/gdnative/gdnative.cpp

@@ -32,6 +32,7 @@
 
 #include "core/global_constants.h"
 #include "core/io/file_access_encrypted.h"
+#include "core/os/dir_access.h"
 #include "core/os/file_access.h"
 #include "core/os/os.h"
 #include "core/project_settings.h"
@@ -325,9 +326,18 @@ bool GDNative::initialize() {
 	// On OSX the exported libraries are located under the Frameworks directory.
 	// So we need to replace the library path.
 	String path = ProjectSettings::get_singleton()->globalize_path(lib_path);
-	if (!FileAccess::exists(path)) {
+	DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+
+	if (!da->file_exists(path) && !da->dir_exists(path)) {
 		path = OS::get_singleton()->get_executable_path().get_base_dir().plus_file("../Frameworks").plus_file(lib_path.get_file());
 	}
+
+	if (da->dir_exists(path)) { // Target library is a ".framework", add library base name to the path.
+		path = path.plus_file(path.get_file().get_basename());
+	}
+
+	memdelete(da);
+
 #else
 	String path = ProjectSettings::get_singleton()->globalize_path(lib_path);
 #endif

+ 3 - 4
modules/gdnative/gdnative_library_editor_plugin.cpp

@@ -139,7 +139,7 @@ void GDNativeLibraryEditor::_on_item_button(Object *item, int column, int id) {
 
 		if (id == BUTTON_SELECT_DEPENDENCES) {
 			mode = EditorFileDialog::MODE_OPEN_FILES;
-		} else if (treeItem->get_text(0) == "iOS") {
+		} else if (treeItem->get_text(0) == "iOS" || treeItem->get_text(0) == "macOS") {
 			mode = EditorFileDialog::MODE_OPEN_ANY;
 		}
 
@@ -286,10 +286,9 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
 		platforms["X11"] = platform_linux;
 
 		NativePlatformConfig platform_osx;
-		platform_osx.name = "Mac OSX";
+		platform_osx.name = "macOS";
 		platform_osx.entries.push_back("64");
-		platform_osx.entries.push_back("32");
-		platform_osx.library_extension = "*.dylib";
+		platform_osx.library_extension = "*.framework; Framework, *.dylib; Dynamic Library";
 		platforms["OSX"] = platform_osx;
 
 		NativePlatformConfig platform_haiku;

+ 57 - 3
platform/osx/export/export.cpp

@@ -820,9 +820,22 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
 		if (err == OK) {
 			DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
 			for (int i = 0; i < shared_objects.size(); i++) {
-				err = da->copy(shared_objects[i].path, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file());
+				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());
+				}
 				if (err == OK && sign_enabled) {
-					err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file(), ent_path);
+					err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file(), ent_path);
 				}
 			}
 			memdelete(da);
@@ -898,7 +911,48 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
 		if (f == "." || f == "..") {
 			continue;
 		}
-		if (da->current_is_dir()) {
+		if (da->is_link(f)) {
+			OS::Time time = OS::get_singleton()->get_time();
+			OS::Date date = OS::get_singleton()->get_date();
+
+			zip_fileinfo zipfi;
+			zipfi.tmz_date.tm_hour = time.hour;
+			zipfi.tmz_date.tm_mday = date.day;
+			zipfi.tmz_date.tm_min = time.min;
+			zipfi.tmz_date.tm_mon = date.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, http://www.cplusplus.com/reference/ctime/tm/
+			zipfi.tmz_date.tm_sec = time.sec;
+			zipfi.tmz_date.tm_year = date.year;
+			zipfi.dosDate = 0;
+			// 0120000: symbolic link type
+			// 0000755: permissions rwxr-xr-x
+			// 0000644: permissions rw-r--r--
+			uint32_t _mode = 0120644;
+			zipfi.external_fa = (_mode << 16L) | !(_mode & 0200);
+			zipfi.internal_fa = 0;
+
+			zipOpenNewFileInZip4(p_zip,
+					p_folder.plus_file(f).utf8().get_data(),
+					&zipfi,
+					nullptr,
+					0,
+					nullptr,
+					0,
+					nullptr,
+					Z_DEFLATED,
+					Z_DEFAULT_COMPRESSION,
+					0,
+					-MAX_WBITS,
+					DEF_MEM_LEVEL,
+					Z_DEFAULT_STRATEGY,
+					nullptr,
+					0,
+					0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions
+					0);
+
+			String target = da->read_link(f);
+			zipWriteInFileInZip(p_zip, target.utf8().get_data(), target.utf8().size());
+			zipCloseFileInZip(p_zip);
+		} else if (da->current_is_dir()) {
 			_zip_folder_recursive(p_zip, p_root_path, p_folder.plus_file(f), p_pkg_name);
 		} else {
 			bool is_executable = (p_folder.ends_with("MacOS") && (f == p_pkg_name));