mirror of
https://github.com/godotengine/godot.git
synced 2026-05-06 07:56:56 -04:00
[iOS] Reintegrate camera module to the main repo.
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<description>
|
||||
The [CameraServer] keeps track of different cameras accessible in Godot. These are external cameras such as webcams or the cameras on your phone.
|
||||
It is notably used to provide AR modules with a video feed from the camera.
|
||||
[b]Note:[/b] This class is currently only implemented on Linux, Android, macOS, and iOS. On other platforms no [CameraFeed]s will be available. To get a [CameraFeed] on iOS, the camera plugin from [url=https://github.com/godotengine/godot-ios-plugins]godot-ios-plugins[/url] is required.
|
||||
[b]Note:[/b] This class is currently only implemented on Linux, Android, macOS, and iOS. On other platforms no [CameraFeed]s will be available. To get a [CameraFeed] on iOS, enable [member EditorExportPlatformIOS.modules/camera].
|
||||
</description>
|
||||
<tutorials>
|
||||
</tutorials>
|
||||
|
||||
@@ -283,6 +283,8 @@ void EditorExportPlatformAppleEmbedded::get_export_options(List<ExportOption> *r
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/export_project_only"), false));
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/delete_old_export_files_unconditionally"), false));
|
||||
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "modules/camera"), false));
|
||||
|
||||
Vector<PluginConfigAppleEmbedded> found_plugins = get_plugins(get_platform_name());
|
||||
for (int i = 0; i < found_plugins.size(); i++) {
|
||||
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, vformat("%s/%s", PNAME("plugins"), found_plugins[i].name)), false));
|
||||
@@ -1422,7 +1424,7 @@ Vector<String> EditorExportPlatformAppleEmbedded::_get_preset_architectures(cons
|
||||
return enabled_archs;
|
||||
}
|
||||
|
||||
Error EditorExportPlatformAppleEmbedded::_export_apple_embedded_plugins(const Ref<EditorExportPreset> &p_preset, AppleEmbeddedConfigData &p_config_data, const String &dest_dir, Vector<AppleEmbeddedExportAsset> &r_exported_assets, bool p_debug) {
|
||||
Error EditorExportPlatformAppleEmbedded::_export_apple_embedded_plugins(const Ref<EditorExportPreset> &p_preset, AppleEmbeddedConfigData &p_config_data, const String &p_dest_dir, const Vector<String> &p_module_libs, Vector<AppleEmbeddedExportAsset> &r_exported_assets, bool p_debug) {
|
||||
String plugin_definition_cpp_code;
|
||||
String plugin_initialization_cpp_code;
|
||||
String plugin_deinitialization_cpp_code;
|
||||
@@ -1449,7 +1451,7 @@ Error EditorExportPlatformAppleEmbedded::_export_apple_embedded_plugins(const Re
|
||||
String plugin_binary_result_file = plugin.binary.get_file();
|
||||
// We shouldn't embed .xcframework that contains static libraries.
|
||||
// Static libraries are not embedded anyway.
|
||||
err = _copy_asset(p_preset, dest_dir, plugin_main_binary, &plugin_binary_result_file, true, false, r_exported_assets);
|
||||
err = _copy_asset(p_preset, p_dest_dir, plugin_main_binary, &plugin_binary_result_file, true, false, r_exported_assets);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
|
||||
// Adding dependencies.
|
||||
@@ -1553,6 +1555,23 @@ Error EditorExportPlatformAppleEmbedded::_export_apple_embedded_plugins(const Re
|
||||
plugin_deinitialization_cpp_code += "\t" + deinitialization_method;
|
||||
}
|
||||
|
||||
for (const String &lib_name : p_module_libs) {
|
||||
String definition_comment = "// Module: " + lib_name + "\n";
|
||||
String initialization_method = "register_" + lib_name + "_external_module();\n";
|
||||
String deinitialization_method = "unregister_" + lib_name + "_external_module();\n";
|
||||
|
||||
plugin_definition_cpp_code += definition_comment +
|
||||
"extern void " + initialization_method +
|
||||
"extern void " + deinitialization_method + "\n";
|
||||
|
||||
plugin_initialization_cpp_code += "\t" + initialization_method;
|
||||
plugin_deinitialization_cpp_code += "\t" + deinitialization_method;
|
||||
|
||||
String binary_name = p_dest_dir.get_file().get_basename();
|
||||
AppleEmbeddedExportAsset exported_asset = { binary_name + "_" + lib_name + ".xcframework", true, false };
|
||||
r_exported_assets.push_back(exported_asset);
|
||||
}
|
||||
|
||||
// Updating `Info.plist`
|
||||
{
|
||||
for (const KeyValue<String, String> &E : plist_values) {
|
||||
@@ -1570,15 +1589,15 @@ Error EditorExportPlatformAppleEmbedded::_export_apple_embedded_plugins(const Re
|
||||
// Export files
|
||||
{
|
||||
// Export linked plugin dependency
|
||||
err = _export_additional_assets(p_preset, dest_dir, plugin_linked_dependencies, true, false, r_exported_assets);
|
||||
err = _export_additional_assets(p_preset, p_dest_dir, plugin_linked_dependencies, true, false, r_exported_assets);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
|
||||
// Export embedded plugin dependency
|
||||
err = _export_additional_assets(p_preset, dest_dir, plugin_embedded_dependencies, true, true, r_exported_assets);
|
||||
err = _export_additional_assets(p_preset, p_dest_dir, plugin_embedded_dependencies, true, true, r_exported_assets);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
|
||||
// Export plugin files
|
||||
err = _export_additional_assets(p_preset, dest_dir, plugin_files, false, false, r_exported_assets);
|
||||
err = _export_additional_assets(p_preset, p_dest_dir, plugin_files, false, false, r_exported_assets);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
}
|
||||
|
||||
@@ -1765,6 +1784,10 @@ Error EditorExportPlatformAppleEmbedded::_export_project_helper(const Ref<Editor
|
||||
}
|
||||
|
||||
String library_to_use = "libgodot." + get_platform_name() + "." + String(p_debug ? "debug" : "release") + ".xcframework";
|
||||
Vector<String> module_libs;
|
||||
if (p_preset->get("modules/camera").operator bool()) {
|
||||
module_libs.push_back("camera");
|
||||
}
|
||||
|
||||
print_line("Static framework: " + library_to_use);
|
||||
String pkg_name;
|
||||
@@ -1774,7 +1797,7 @@ Error EditorExportPlatformAppleEmbedded::_export_project_helper(const Ref<Editor
|
||||
pkg_name = "Unnamed";
|
||||
}
|
||||
|
||||
bool found_library = false;
|
||||
int found_libraries = 0;
|
||||
|
||||
HashSet<String> files_to_parse;
|
||||
const String project_file = "godot_apple_embedded.xcodeproj/project.pbxproj";
|
||||
@@ -1821,7 +1844,7 @@ Error EditorExportPlatformAppleEmbedded::_export_project_helper(const Ref<Editor
|
||||
return ERR_CANT_OPEN;
|
||||
}
|
||||
|
||||
err = _export_apple_embedded_plugins(p_preset, config_data, binary_dir, assets, p_debug);
|
||||
err = _export_apple_embedded_plugins(p_preset, config_data, binary_dir, module_libs, assets, p_debug);
|
||||
if (err != OK) {
|
||||
// TODO: Improve error reporting by using `add_message` throughout all methods called via `_export_apple_embedded_plugins`.
|
||||
// For now a generic top level message would be fine, but we're ought to use proper reporting here instead of
|
||||
@@ -1861,16 +1884,32 @@ Error EditorExportPlatformAppleEmbedded::_export_project_helper(const Ref<Editor
|
||||
|
||||
if (files_to_parse.has(file)) {
|
||||
_fix_config_file(p_preset, data, config_data, p_debug);
|
||||
} else if (file.begins_with("libgodot." + get_platform_name())) {
|
||||
if (!file.begins_with(library_to_use) || file.ends_with(String("/empty"))) {
|
||||
} else if (file.begins_with("libgodot") && file.contains(get_platform_name())) {
|
||||
String prefix_lib = library_to_use;
|
||||
String suffix_lib = binary_name;
|
||||
bool is_lib = file.begins_with(library_to_use);
|
||||
if (!is_lib) {
|
||||
for (const String &lib_name : module_libs) {
|
||||
String prefix = "libgodot_" + lib_name + "." + get_platform_name() + "." + String(p_debug ? "debug" : "release") + ".xcframework";
|
||||
if (file.begins_with(prefix)) {
|
||||
is_lib = true;
|
||||
prefix_lib = prefix;
|
||||
suffix_lib = binary_name + "_" + lib_name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_lib || file.ends_with(String("/empty"))) {
|
||||
ret = unzGoToNextFile(src_pkg_zip);
|
||||
continue; //ignore!
|
||||
}
|
||||
found_library = true;
|
||||
if (file.ends_with("Info.plist")) {
|
||||
found_libraries++;
|
||||
}
|
||||
#if defined(MACOS_ENABLED) || defined(LINUXBSD_ENABLED)
|
||||
is_execute = true;
|
||||
#endif
|
||||
file = file.replace(library_to_use, binary_name + ".xcframework");
|
||||
file = file.replace(prefix_lib, suffix_lib + ".xcframework");
|
||||
}
|
||||
|
||||
if (file == project_file) {
|
||||
@@ -1924,7 +1963,7 @@ Error EditorExportPlatformAppleEmbedded::_export_project_helper(const Ref<Editor
|
||||
// We're done with our source zip.
|
||||
unzClose(src_pkg_zip);
|
||||
|
||||
if (!found_library) {
|
||||
if (found_libraries < module_libs.size() + 1) {
|
||||
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Requested template library '%s' not found. It might be missing from your template archive."), library_to_use));
|
||||
return ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
@@ -2194,6 +2233,14 @@ bool EditorExportPlatformAppleEmbedded::has_valid_export_configuration(const Ref
|
||||
valid = dvalid || rvalid;
|
||||
r_missing_templates = !valid;
|
||||
|
||||
if (p_preset->get("modules/camera").operator bool()) {
|
||||
String description = p_preset->get("privacy/camera_usage_description");
|
||||
if (description.is_empty()) {
|
||||
valid = false;
|
||||
err += TTR("Camera module enabled, but camera usage description is not set.") + "\n";
|
||||
}
|
||||
}
|
||||
|
||||
const String &additional_plist_content = p_preset->get("application/additional_plist_content");
|
||||
if (!additional_plist_content.is_empty()) {
|
||||
const String &plist = vformat("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
|
||||
@@ -197,7 +197,7 @@ private:
|
||||
Error _export_additional_assets(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, bool p_should_embed, Vector<AppleEmbeddedExportAsset> &r_exported_assets);
|
||||
Error _copy_asset(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const String &p_asset, const String *p_custom_file_name, bool p_is_framework, bool p_should_embed, Vector<AppleEmbeddedExportAsset> &r_exported_assets);
|
||||
Error _export_additional_assets(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<AppleEmbeddedExportAsset> &r_exported_assets);
|
||||
Error _export_apple_embedded_plugins(const Ref<EditorExportPreset> &p_preset, AppleEmbeddedConfigData &p_config_data, const String &dest_dir, Vector<AppleEmbeddedExportAsset> &r_exported_assets, bool p_debug);
|
||||
Error _export_apple_embedded_plugins(const Ref<EditorExportPreset> &p_preset, AppleEmbeddedConfigData &p_config_data, const String &p_dest_dir, const Vector<String> &p_module_libs, Vector<AppleEmbeddedExportAsset> &r_exported_assets, bool p_debug);
|
||||
|
||||
Error _export_project_helper(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags, bool p_oneclick);
|
||||
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libgodot_camera.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64_x86_64-simulator</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libgodot_camera.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
<string>x86_64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>simulator</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
<key>XCFrameworkFormatVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
+1
@@ -0,0 +1 @@
|
||||
Dummy file to make dylibs folder exported
|
||||
+1
@@ -0,0 +1 @@
|
||||
Dummy file to make dylibs folder exported
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libgodot_camera.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>ios-arm64_x86_64-simulator</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libgodot_camera.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
<string>x86_64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>ios</string>
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>simulator</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
<key>XCFrameworkFormatVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
+1
@@ -0,0 +1 @@
|
||||
Dummy file to make dylibs folder exported
|
||||
+1
@@ -0,0 +1 @@
|
||||
Dummy file to make dylibs folder exported
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>xros-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libgodot_camera.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>xros</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>xros-arm64-simulator</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libgodot_camera.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>xros</string>
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>simulator</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
<key>XCFrameworkFormatVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
misc/dist/apple_embedded_xcode/libgodot_camera.visionos.debug.xcframework/xros-arm64-simulator/empty
Vendored
+1
@@ -0,0 +1 @@
|
||||
Dummy file to make dylibs folder exported
|
||||
+1
@@ -0,0 +1 @@
|
||||
Dummy file to make dylibs folder exported
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AvailableLibraries</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>xros-arm64</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libgodot_camera.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>xros</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>LibraryIdentifier</key>
|
||||
<string>xros-arm64-simulator</string>
|
||||
<key>LibraryPath</key>
|
||||
<string>libgodot_camera.a</string>
|
||||
<key>SupportedArchitectures</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
<key>SupportedPlatform</key>
|
||||
<string>xros</string>
|
||||
<key>SupportedPlatformVariant</key>
|
||||
<string>simulator</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XFWK</string>
|
||||
<key>XCFrameworkFormatVersion</key>
|
||||
<string>1.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
+1
@@ -0,0 +1 @@
|
||||
Dummy file to make dylibs folder exported
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
Dummy file to make dylibs folder exported
|
||||
@@ -6,19 +6,25 @@ Import("env_modules")
|
||||
|
||||
env_camera = env_modules.Clone()
|
||||
|
||||
if env["platform"] in ["windows", "macos", "linuxbsd", "android"]:
|
||||
if env["platform"] in ["windows", "macos", "linuxbsd", "android", "ios", "visionos"]:
|
||||
env_camera.add_source_files(env.modules_sources, "register_types.cpp")
|
||||
|
||||
if env["platform"] == "windows":
|
||||
env_camera.add_source_files(env.modules_sources, "camera_win.cpp")
|
||||
|
||||
elif env["platform"] == "macos":
|
||||
env_camera.add_source_files(env.modules_sources, "camera_macos.mm")
|
||||
env_camera.add_source_files(env.modules_sources, "camera_apple.mm")
|
||||
|
||||
elif env["platform"] == "android":
|
||||
env_camera.add_source_files(env.modules_sources, "camera_android.cpp")
|
||||
env.Append(LIBS=["camera2ndk", "mediandk"])
|
||||
|
||||
elif env["platform"] in ["ios", "visionos"]:
|
||||
ext_module_source = ["camera_apple.mm"]
|
||||
ext_camera_lib = env_camera.add_library("#bin/libgodot_camera", ext_module_source)
|
||||
env.Append(LIBS_EXTERNAL=[ext_camera_lib])
|
||||
env.Append(MODULES_EXTERNAL=["_camera"])
|
||||
|
||||
elif env["platform"] == "linuxbsd":
|
||||
env_camera.add_source_files(env.modules_sources, "camera_linux.cpp")
|
||||
env_camera.add_source_files(env.modules_sources, "camera_feed_linux.cpp")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**************************************************************************/
|
||||
/* camera_macos.h */
|
||||
/* camera_apple.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
@@ -35,11 +35,11 @@
|
||||
|
||||
#include "servers/camera/camera_server.h"
|
||||
|
||||
class CameraMacOS : public CameraServer {
|
||||
GDSOFTCLASS(CameraMacOS, CameraServer);
|
||||
class CameraApple : public CameraServer {
|
||||
GDSOFTCLASS(CameraApple, CameraServer);
|
||||
|
||||
public:
|
||||
CameraMacOS() = default;
|
||||
CameraApple() = default;
|
||||
|
||||
void update_feeds();
|
||||
void set_monitoring_feeds(bool p_monitoring_feeds) override;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**************************************************************************/
|
||||
/* camera_macos.mm */
|
||||
/* camera_apple.mm */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
@@ -31,11 +31,14 @@
|
||||
///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimize code duplication!!!!
|
||||
// If you fix something here, make sure you fix it there as well!
|
||||
|
||||
#import "camera_macos.h"
|
||||
#import "camera_apple.h"
|
||||
|
||||
#include "servers/camera/camera_feed.h"
|
||||
|
||||
#import <AVFoundation/AVFoundation.h>
|
||||
#ifdef IOS_ENABLED
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MyCaptureSession - This is a little helper class so we can capture our frames
|
||||
@@ -63,23 +66,30 @@
|
||||
width[1] = 0;
|
||||
height[1] = 0;
|
||||
|
||||
#ifdef APPLE_EMBEDDED_ENABLED
|
||||
[p_device lockForConfiguration:&error];
|
||||
#ifdef IOS_ENABLED
|
||||
if ([p_device lockForConfiguration:&error]) {
|
||||
if ([p_device isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
|
||||
[p_device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
|
||||
}
|
||||
if ([p_device isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
|
||||
[p_device setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
|
||||
}
|
||||
if ([p_device isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) {
|
||||
[p_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance];
|
||||
}
|
||||
|
||||
[p_device setFocusMode:AVCaptureFocusModeLocked];
|
||||
[p_device setExposureMode:AVCaptureExposureModeLocked];
|
||||
[p_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeLocked];
|
||||
|
||||
[p_device unlockForConfiguration];
|
||||
#endif // APPLE_EMBEDDED_ENABLED
|
||||
[p_device unlockForConfiguration];
|
||||
}
|
||||
#endif // IOS_ENABLED
|
||||
|
||||
[self beginConfiguration];
|
||||
|
||||
#ifdef APPLE_EMBEDDED_ENABLED
|
||||
#ifdef IOS_ENABLED
|
||||
self.sessionPreset = AVCaptureSessionPreset1280x720;
|
||||
#endif // APPLE_EMBEDDED_ENABLED
|
||||
#endif // IOS_ENABLED
|
||||
|
||||
input = [[AVCaptureDeviceInput alloc] initWithDevice:p_device error:&error];
|
||||
|
||||
input = [AVCaptureDeviceInput deviceInputWithDevice:p_device error:&error];
|
||||
if (!input) {
|
||||
print_line("Couldn't get input device for camera");
|
||||
[self commitConfiguration];
|
||||
@@ -219,6 +229,28 @@
|
||||
// set our texture...
|
||||
feed->set_ycbcr_images(img[0], img[1]);
|
||||
|
||||
#ifdef IOS_ENABLED
|
||||
UIInterfaceOrientation orientation = [UIApplication sharedApplication].delegate.window.windowScene.interfaceOrientation;
|
||||
|
||||
Transform2D display_transform;
|
||||
switch (orientation) {
|
||||
case UIInterfaceOrientationPortrait: {
|
||||
display_transform = Transform2D(0.0, -1.0, -1.0, 0.0, 1.0, 1.0);
|
||||
} break;
|
||||
case UIInterfaceOrientationLandscapeRight: {
|
||||
display_transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0);
|
||||
} break;
|
||||
case UIInterfaceOrientationLandscapeLeft: {
|
||||
display_transform = Transform2D(-1.0, 0.0, 0.0, 1.0, 1.0, 0.0);
|
||||
} break;
|
||||
default: {
|
||||
display_transform = Transform2D(0.0, 1.0, 1.0, 0.0, 0.0, 0.0);
|
||||
} break;
|
||||
}
|
||||
|
||||
feed->set_transform(display_transform);
|
||||
#endif // IOS_ENABLED
|
||||
|
||||
// and unlock
|
||||
CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly);
|
||||
}
|
||||
@@ -226,10 +258,10 @@
|
||||
@end
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CameraFeedMacOS - Subclass for camera feeds in macOS
|
||||
// CameraFeedApple - Subclass for camera feeds in macOS
|
||||
|
||||
class CameraFeedMacOS : public CameraFeed {
|
||||
GDSOFTCLASS(CameraFeedMacOS, CameraFeed);
|
||||
class CameraFeedApple : public CameraFeed {
|
||||
GDSOFTCLASS(CameraFeedApple, CameraFeed);
|
||||
|
||||
private:
|
||||
AVCaptureDevice *device;
|
||||
@@ -238,8 +270,8 @@ private:
|
||||
public:
|
||||
AVCaptureDevice *get_device() const;
|
||||
|
||||
CameraFeedMacOS();
|
||||
~CameraFeedMacOS();
|
||||
CameraFeedApple();
|
||||
~CameraFeedApple();
|
||||
|
||||
void set_device(AVCaptureDevice *p_device);
|
||||
|
||||
@@ -247,22 +279,23 @@ public:
|
||||
void deactivate_feed() override;
|
||||
};
|
||||
|
||||
AVCaptureDevice *CameraFeedMacOS::get_device() const {
|
||||
AVCaptureDevice *CameraFeedApple::get_device() const {
|
||||
return device;
|
||||
}
|
||||
|
||||
CameraFeedMacOS::CameraFeedMacOS() {
|
||||
CameraFeedApple::CameraFeedApple() {
|
||||
device = nullptr;
|
||||
capture_session = nullptr;
|
||||
transform = Transform2D(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); /* should re-orientate this based on device orientation */
|
||||
}
|
||||
|
||||
CameraFeedMacOS::~CameraFeedMacOS() {
|
||||
CameraFeedApple::~CameraFeedApple() {
|
||||
if (is_active()) {
|
||||
deactivate_feed();
|
||||
}
|
||||
}
|
||||
|
||||
void CameraFeedMacOS::set_device(AVCaptureDevice *p_device) {
|
||||
void CameraFeedApple::set_device(AVCaptureDevice *p_device) {
|
||||
device = p_device;
|
||||
|
||||
// get some info
|
||||
@@ -276,14 +309,14 @@ void CameraFeedMacOS::set_device(AVCaptureDevice *p_device) {
|
||||
};
|
||||
}
|
||||
|
||||
bool CameraFeedMacOS::activate_feed() {
|
||||
bool CameraFeedApple::activate_feed() {
|
||||
if (capture_session) {
|
||||
// Already recording.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Start camera capture, check permission.
|
||||
if (@available(macOS 10.14, *)) {
|
||||
if (@available(macOS 10.14, iOS 14.0, visionOS 1.0, *)) {
|
||||
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
|
||||
if (status == AVAuthorizationStatusAuthorized) {
|
||||
capture_session = [[MyCaptureSession alloc] initForFeed:this andDevice:device];
|
||||
@@ -311,7 +344,7 @@ bool CameraFeedMacOS::activate_feed() {
|
||||
}
|
||||
}
|
||||
|
||||
void CameraFeedMacOS::deactivate_feed() {
|
||||
void CameraFeedApple::deactivate_feed() {
|
||||
// end camera capture if we have one
|
||||
if (capture_session) {
|
||||
[capture_session cleanup];
|
||||
@@ -324,7 +357,7 @@ void CameraFeedMacOS::deactivate_feed() {
|
||||
// when devices are connected/disconnected
|
||||
|
||||
@interface MyDeviceNotifications : NSObject {
|
||||
CameraMacOS *camera_server;
|
||||
CameraApple *camera_server;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -335,7 +368,7 @@ void CameraFeedMacOS::deactivate_feed() {
|
||||
camera_server->update_feeds();
|
||||
}
|
||||
|
||||
- (id)initForServer:(CameraMacOS *)p_server {
|
||||
- (id)initForServer:(CameraApple *)p_server {
|
||||
if (self = [super init]) {
|
||||
camera_server = p_server;
|
||||
|
||||
@@ -356,13 +389,31 @@ void CameraFeedMacOS::deactivate_feed() {
|
||||
MyDeviceNotifications *device_notifications = nil;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CameraMacOS - Subclass for our camera server on macOS
|
||||
// CameraApple - Subclass for our camera server on macOS
|
||||
|
||||
void CameraMacOS::update_feeds() {
|
||||
void CameraApple::update_feeds() {
|
||||
NSArray<AVCaptureDevice *> *devices = nullptr;
|
||||
#ifdef APPLE_EMBEDDED_ENABLED
|
||||
{
|
||||
NSMutableArray *deviceTypes = [NSMutableArray array];
|
||||
if (@available(iOS 14.0, visionOS 2.1, *)) {
|
||||
[deviceTypes addObject:AVCaptureDeviceTypeBuiltInWideAngleCamera];
|
||||
}
|
||||
#ifdef IOS_ENABLED
|
||||
[deviceTypes addObject:AVCaptureDeviceTypeBuiltInTelephotoCamera];
|
||||
[deviceTypes addObject:AVCaptureDeviceTypeBuiltInDualCamera];
|
||||
[deviceTypes addObject:AVCaptureDeviceTypeBuiltInTrueDepthCamera];
|
||||
[deviceTypes addObject:AVCaptureDeviceTypeBuiltInUltraWideCamera];
|
||||
[deviceTypes addObject:AVCaptureDeviceTypeBuiltInDualWideCamera];
|
||||
[deviceTypes addObject:AVCaptureDeviceTypeBuiltInTripleCamera];
|
||||
#endif // IOS_ENABLED
|
||||
AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:deviceTypes mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified];
|
||||
devices = session.devices;
|
||||
}
|
||||
#else // APPLE_EMBEDDED_ENABLED
|
||||
#if defined(__x86_64__)
|
||||
if (@available(macOS 10.15, *)) {
|
||||
#endif
|
||||
#endif // __x86_64__
|
||||
AVCaptureDeviceDiscoverySession *session;
|
||||
if (@available(macOS 14.0, *)) {
|
||||
session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:[NSArray arrayWithObjects:AVCaptureDeviceTypeExternal, AVCaptureDeviceTypeBuiltInWideAngleCamera, AVCaptureDeviceTypeContinuityCamera, nil] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified];
|
||||
@@ -374,11 +425,12 @@ void CameraMacOS::update_feeds() {
|
||||
} else {
|
||||
devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
|
||||
}
|
||||
#endif
|
||||
#endif // __x86_64__
|
||||
#endif // APPLE_EMBEDDED_ENABLED
|
||||
|
||||
// Deactivate feeds that are gone before removing them.
|
||||
for (int i = feeds.size() - 1; i >= 0; i--) {
|
||||
Ref<CameraFeedMacOS> feed = (Ref<CameraFeedMacOS>)feeds[i];
|
||||
Ref<CameraFeedApple> feed = (Ref<CameraFeedApple>)feeds[i];
|
||||
if (feed.is_null()) {
|
||||
continue;
|
||||
}
|
||||
@@ -394,7 +446,7 @@ void CameraMacOS::update_feeds() {
|
||||
for (AVCaptureDevice *device in devices) {
|
||||
bool found = false;
|
||||
for (int i = 0; i < feeds.size() && !found; i++) {
|
||||
Ref<CameraFeedMacOS> feed = (Ref<CameraFeedMacOS>)feeds[i];
|
||||
Ref<CameraFeedApple> feed = (Ref<CameraFeedApple>)feeds[i];
|
||||
if (feed.is_null()) {
|
||||
continue;
|
||||
}
|
||||
@@ -404,7 +456,7 @@ void CameraMacOS::update_feeds() {
|
||||
};
|
||||
|
||||
if (!found) {
|
||||
Ref<CameraFeedMacOS> newfeed;
|
||||
Ref<CameraFeedApple> newfeed;
|
||||
newfeed.instantiate();
|
||||
newfeed->set_device(device);
|
||||
|
||||
@@ -414,7 +466,7 @@ void CameraMacOS::update_feeds() {
|
||||
emit_signal(SNAME(CameraServer::feeds_updated_signal_name));
|
||||
}
|
||||
|
||||
void CameraMacOS::set_monitoring_feeds(bool p_monitoring_feeds) {
|
||||
void CameraApple::set_monitoring_feeds(bool p_monitoring_feeds) {
|
||||
if (p_monitoring_feeds == monitoring_feeds) {
|
||||
return;
|
||||
}
|
||||
@@ -431,3 +483,14 @@ void CameraMacOS::set_monitoring_feeds(bool p_monitoring_feeds) {
|
||||
device_notifications = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef APPLE_EMBEDDED_ENABLED
|
||||
|
||||
void register_camera_external_module() {
|
||||
CameraServer::make_default<CameraApple>();
|
||||
}
|
||||
|
||||
void unregister_camera_external_module() {
|
||||
}
|
||||
|
||||
#endif // APPLE_EMBEDDED_ENABLED
|
||||
@@ -3,7 +3,14 @@ def can_build(env, platform):
|
||||
|
||||
if sys.platform.startswith("freebsd") or sys.platform.startswith("openbsd"):
|
||||
return False
|
||||
return platform == "macos" or platform == "windows" or platform == "linuxbsd" or platform == "android"
|
||||
return (
|
||||
platform == "macos"
|
||||
or platform == "windows"
|
||||
or platform == "linuxbsd"
|
||||
or platform == "android"
|
||||
or platform == "ios"
|
||||
or platform == "visionos"
|
||||
)
|
||||
|
||||
|
||||
def configure(env):
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "camera_win.h"
|
||||
#endif
|
||||
#if defined(MACOS_ENABLED)
|
||||
#include "camera_macos.h"
|
||||
#include "camera_apple.h"
|
||||
#endif
|
||||
#if defined(ANDROID_ENABLED)
|
||||
#include "camera_android.h"
|
||||
@@ -55,7 +55,7 @@ void initialize_camera_module(ModuleInitializationLevel p_level) {
|
||||
CameraServer::make_default<CameraWindows>();
|
||||
#endif
|
||||
#if defined(MACOS_ENABLED)
|
||||
CameraServer::make_default<CameraMacOS>();
|
||||
CameraServer::make_default<CameraApple>();
|
||||
#endif
|
||||
#if defined(ANDROID_ENABLED)
|
||||
CameraServer::make_default<CameraAndroid>();
|
||||
|
||||
@@ -22,6 +22,9 @@ ios_lib = env_ios.add_library("ios", ios_lib)
|
||||
# (iOS) Enable module support
|
||||
env_ios.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
|
||||
|
||||
if "LIBS_EXTERNAL" in env_ios:
|
||||
env_ios.Depends(ios_lib, env_ios["LIBS_EXTERNAL"])
|
||||
|
||||
combine_command = env_ios.CommandNoCache(
|
||||
"#bin/libgodot" + env_ios["LIBSUFFIX"], [ios_lib] + env_ios["LIBS"], env.Run(combine_libs_apple_embedded)
|
||||
)
|
||||
|
||||
@@ -269,6 +269,9 @@
|
||||
<member name="icons/spotlight_120x120_tinted" type="String" setter="" getter="">
|
||||
Spotlight icon file on iPad and iPhone (3x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
|
||||
</member>
|
||||
<member name="modules/camera" type="bool" setter="" getter="">
|
||||
If [code]true[/code], [CameraServer] module is added to the exported project.
|
||||
</member>
|
||||
<member name="privacy/active_keyboard_access_reasons" type="int" setter="" getter="">
|
||||
The reasons your app use active keyboard API. See [url=https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api]Describing use of required reason API[/url].
|
||||
</member>
|
||||
|
||||
@@ -21,6 +21,9 @@ visionos_lib = env_visionos.add_library("visionos", visionos_lib)
|
||||
# Enable module support
|
||||
env_visionos.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
|
||||
|
||||
if "LIBS_EXTERNAL" in env_visionos:
|
||||
env_visionos.Depends(visionos_lib, env_visionos["LIBS_EXTERNAL"])
|
||||
|
||||
combine_command = env_visionos.Command(
|
||||
"#bin/libgodot" + env_visionos["LIBSUFFIX"], [visionos_lib] + env_visionos["LIBS"], combine_libs_apple_embedded
|
||||
)
|
||||
|
||||
@@ -121,6 +121,9 @@
|
||||
<member name="icons/icon_1024x1024_tinted" type="String" setter="" getter="">
|
||||
Base application icon used to generate other icons, tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
|
||||
</member>
|
||||
<member name="modules/camera" type="bool" setter="" getter="">
|
||||
If [code]true[/code], [CameraServer] module is added to the exported project.
|
||||
</member>
|
||||
<member name="privacy/active_keyboard_access_reasons" type="int" setter="" getter="">
|
||||
The reasons your app use active keyboard API. See [url=https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api]Describing use of required reason API[/url].
|
||||
</member>
|
||||
|
||||
+90
-35
@@ -172,13 +172,93 @@ def combine_libs_apple_embedded(target, source, env):
|
||||
)
|
||||
|
||||
|
||||
def generate_bundle_apple_embedded(platform, framework_dir, framework_dir_sim, use_mkv, target, source, env):
|
||||
def lipo_and_copy_apple_embedded(
|
||||
platform, framework_dir, framework_dir_sim, rel_prefix, dbg_prefix, module_prefix, app_dir, env
|
||||
):
|
||||
bin_dir = env.Dir("#bin").abspath
|
||||
|
||||
# Lipo template libraries.
|
||||
#
|
||||
# env.extra_suffix contains ".simulator" when building for simulator,
|
||||
# but it's undesired when calling lipo()
|
||||
extra_suffix = env.extra_suffix.replace(".simulator", "")
|
||||
rel_target_bin = lipo(bin_dir + "/libgodot" + module_prefix + "." + rel_prefix, extra_suffix + ".a")
|
||||
dbg_target_bin = lipo(bin_dir + "/libgodot" + module_prefix + "." + dbg_prefix, extra_suffix + ".a")
|
||||
rel_target_bin_sim = lipo(
|
||||
bin_dir + "/libgodot" + module_prefix + "." + rel_prefix, ".simulator" + extra_suffix + ".a"
|
||||
)
|
||||
dbg_target_bin_sim = lipo(
|
||||
bin_dir + "/libgodot" + module_prefix + "." + dbg_prefix, ".simulator" + extra_suffix + ".a"
|
||||
)
|
||||
# Assemble Xcode project bundle.
|
||||
if rel_target_bin != "":
|
||||
print(f' Copying "{platform}" release framework')
|
||||
shutil.copy(
|
||||
rel_target_bin,
|
||||
app_dir
|
||||
+ "/libgodot"
|
||||
+ module_prefix
|
||||
+ "."
|
||||
+ platform
|
||||
+ ".release.xcframework/"
|
||||
+ framework_dir
|
||||
+ "/libgodot"
|
||||
+ module_prefix
|
||||
+ ".a",
|
||||
)
|
||||
if dbg_target_bin != "":
|
||||
print(f' Copying "{platform}" debug framework')
|
||||
shutil.copy(
|
||||
dbg_target_bin,
|
||||
app_dir
|
||||
+ "/libgodot"
|
||||
+ module_prefix
|
||||
+ "."
|
||||
+ platform
|
||||
+ ".debug.xcframework/"
|
||||
+ framework_dir
|
||||
+ "/libgodot"
|
||||
+ module_prefix
|
||||
+ ".a",
|
||||
)
|
||||
if rel_target_bin_sim != "":
|
||||
print(f' Copying "{platform}" (simulator) release framework')
|
||||
shutil.copy(
|
||||
rel_target_bin_sim,
|
||||
app_dir
|
||||
+ "/libgodot"
|
||||
+ module_prefix
|
||||
+ "."
|
||||
+ platform
|
||||
+ ".release.xcframework/"
|
||||
+ framework_dir_sim
|
||||
+ "/libgodot"
|
||||
+ module_prefix
|
||||
+ ".a",
|
||||
)
|
||||
if dbg_target_bin_sim != "":
|
||||
print(f' Copying "{platform}" (simulator) debug framework')
|
||||
shutil.copy(
|
||||
dbg_target_bin_sim,
|
||||
app_dir
|
||||
+ "/libgodot"
|
||||
+ module_prefix
|
||||
+ "."
|
||||
+ platform
|
||||
+ ".debug.xcframework/"
|
||||
+ framework_dir_sim
|
||||
+ "/libgodot"
|
||||
+ module_prefix
|
||||
+ ".a",
|
||||
)
|
||||
|
||||
|
||||
def generate_bundle_apple_embedded(platform, framework_dir, framework_dir_sim, use_mkv, target, source, env):
|
||||
# Template bundle.
|
||||
extra_suffix = env.extra_suffix.replace(".simulator", "")
|
||||
app_prefix = "godot." + platform
|
||||
rel_prefix = "libgodot." + platform + "." + "template_release"
|
||||
dbg_prefix = "libgodot." + platform + "." + "template_debug"
|
||||
rel_prefix = platform + "." + "template_release"
|
||||
dbg_prefix = platform + "." + "template_debug"
|
||||
if env.dev_build:
|
||||
app_prefix += ".dev"
|
||||
rel_prefix += ".dev"
|
||||
@@ -188,43 +268,18 @@ def generate_bundle_apple_embedded(platform, framework_dir, framework_dir_sim, u
|
||||
rel_prefix += ".double"
|
||||
dbg_prefix += ".double"
|
||||
|
||||
# Lipo template libraries.
|
||||
#
|
||||
# env.extra_suffix contains ".simulator" when building for simulator,
|
||||
# but it's undesired when calling lipo()
|
||||
extra_suffix = env.extra_suffix.replace(".simulator", "")
|
||||
rel_target_bin = lipo(bin_dir + "/" + rel_prefix, extra_suffix + ".a")
|
||||
dbg_target_bin = lipo(bin_dir + "/" + dbg_prefix, extra_suffix + ".a")
|
||||
rel_target_bin_sim = lipo(bin_dir + "/" + rel_prefix, ".simulator" + extra_suffix + ".a")
|
||||
dbg_target_bin_sim = lipo(bin_dir + "/" + dbg_prefix, ".simulator" + extra_suffix + ".a")
|
||||
# Assemble Xcode project bundle.
|
||||
app_dir = env.Dir("#bin/" + platform + "_xcode").abspath
|
||||
templ = env.Dir("#misc/dist/apple_embedded_xcode").abspath
|
||||
if os.path.exists(app_dir):
|
||||
shutil.rmtree(app_dir)
|
||||
shutil.copytree(templ, app_dir)
|
||||
if rel_target_bin != "":
|
||||
print(f' Copying "{platform}" release framework')
|
||||
shutil.copy(
|
||||
rel_target_bin, app_dir + "/libgodot." + platform + ".release.xcframework/" + framework_dir + "/libgodot.a"
|
||||
)
|
||||
if dbg_target_bin != "":
|
||||
print(f' Copying "{platform}" debug framework')
|
||||
shutil.copy(
|
||||
dbg_target_bin, app_dir + "/libgodot." + platform + ".debug.xcframework/" + framework_dir + "/libgodot.a"
|
||||
)
|
||||
if rel_target_bin_sim != "":
|
||||
print(f' Copying "{platform}" (simulator) release framework')
|
||||
shutil.copy(
|
||||
rel_target_bin_sim,
|
||||
app_dir + "/libgodot." + platform + ".release.xcframework/" + framework_dir_sim + "/libgodot.a",
|
||||
)
|
||||
if dbg_target_bin_sim != "":
|
||||
print(f' Copying "{platform}" (simulator) debug framework')
|
||||
shutil.copy(
|
||||
dbg_target_bin_sim,
|
||||
app_dir + "/libgodot." + platform + ".debug.xcframework/" + framework_dir_sim + "/libgodot.a",
|
||||
)
|
||||
|
||||
lipo_and_copy_apple_embedded(platform, framework_dir, framework_dir_sim, rel_prefix, dbg_prefix, "", app_dir, env)
|
||||
if "MODULES_EXTERNAL" in env:
|
||||
for mod in env["MODULES_EXTERNAL"]:
|
||||
lipo_and_copy_apple_embedded(
|
||||
platform, framework_dir, framework_dir_sim, rel_prefix, dbg_prefix, mod, app_dir, env
|
||||
)
|
||||
|
||||
# Remove other platform xcframeworks
|
||||
for entry in os.listdir(app_dir):
|
||||
|
||||
Reference in New Issue
Block a user