diff options
Diffstat (limited to 'platform')
34 files changed, 455 insertions, 171 deletions
diff --git a/platform/android/SCsub b/platform/android/SCsub index 1562714d76..cf6752fa54 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -23,8 +23,6 @@ android_files = [ ] env_android = env.Clone() -if env['target'] == "profile": - env_android.Append(CPPFLAGS=['-DPROFILER_ENABLED']) android_objects = [] for x in android_files: diff --git a/platform/android/detect.py b/platform/android/detect.py index eed51c4d30..3f179e3a65 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -144,20 +144,21 @@ def configure(env): if (env["optimize"] == "speed"): #optimize for speed (default) env.Append(LINKFLAGS=['-O2']) env.Append(CCFLAGS=['-O2', '-fomit-frame-pointer']) - env.Append(CPPFLAGS=['-DNDEBUG']) + env.Append(CPPDEFINES=['NDEBUG']) else: #optimize for size env.Append(CCFLAGS=['-Os']) - env.Append(CPPFLAGS=['-DNDEBUG']) + env.Append(CPPDEFINES=['NDEBUG']) env.Append(LINKFLAGS=['-Os']) if (can_vectorize): env.Append(CCFLAGS=['-ftree-vectorize']) if (env["target"] == "release_debug"): - env.Append(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED']) elif (env["target"] == "debug"): env.Append(LINKFLAGS=['-O0']) env.Append(CCFLAGS=['-O0', '-g', '-fno-limit-debug-info']) - env.Append(CPPFLAGS=['-D_DEBUG', '-UNDEBUG', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CPPDEFINES=['_DEBUG', 'DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) + env.Append(CPPFLAGS=['-UNDEBUG']) ## Compiler configuration @@ -215,7 +216,7 @@ def configure(env): else: env.Append(CXXFLAGS=['-fno-rtti', '-fno-exceptions']) # Don't use dynamic_cast, necessary with no-rtti. - env.Append(CPPFLAGS=['-DNO_SAFE_CAST']) + env.Append(CPPDEFINES=['NO_SAFE_CAST']) ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"]) if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"): @@ -225,13 +226,13 @@ def configure(env): env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath]) env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/android/support/include"]) # For unified headers this define has to be set manually - env.Append(CPPFLAGS=["-D__ANDROID_API__=" + str(get_platform(env['ndk_platform']))]) + env.Append(CPPDEFINES=[('__ANDROID_API__', str(get_platform(env['ndk_platform'])))]) else: print("Using NDK deprecated headers") env.Append(CPPFLAGS=["-isystem", lib_sysroot + "/usr/include"]) env.Append(CCFLAGS='-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing'.split()) - env.Append(CPPFLAGS='-DNO_STATVFS -DGLES_ENABLED'.split()) + env.Append(CPPDEFINES=['NO_STATVFS', 'GLES_ENABLED']) env['neon_enabled'] = False if env['android_arch'] == 'x86': @@ -245,18 +246,18 @@ def configure(env): elif env["android_arch"] == "armv7": target_opts = ['-target', 'armv7-none-linux-androideabi'] env.Append(CCFLAGS='-march=armv7-a -mfloat-abi=softfp'.split()) - env.Append(CPPFLAGS='-D__ARM_ARCH_7__ -D__ARM_ARCH_7A__'.split()) + env.Append(CPPDEFINES=['__ARM_ARCH_7__', '__ARM_ARCH_7A__']) if env['android_neon']: env['neon_enabled'] = True env.Append(CCFLAGS=['-mfpu=neon']) - env.Append(CPPFLAGS=['-D__ARM_NEON__']) + env.Append(CPPDEFINES=['__ARM_NEON__']) else: env.Append(CCFLAGS=['-mfpu=vfpv3-d16']) elif env["android_arch"] == "arm64v8": target_opts = ['-target', 'aarch64-none-linux-android'] env.Append(CCFLAGS=['-mfix-cortex-a53-835769']) - env.Append(CPPFLAGS=['-D__ARM_ARCH_8A__']) + env.Append(CPPDEFINES=['__ARM_ARCH_8A__']) env.Append(CCFLAGS=target_opts) env.Append(CCFLAGS=common_opts) @@ -289,7 +290,7 @@ def configure(env): '/toolchains/' + target_subpath + '/prebuilt/' + host_subpath + '/' + abi_subpath + '/lib']) env.Prepend(CPPPATH=['#platform/android']) - env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL']) + env.Append(CPPDEFINES=['ANDROID_ENABLED', 'UNIX_ENABLED', 'NO_FCNTL']) env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'GLESv2', 'android', 'log', 'z', 'dl']) # Return NDK version string in source.properties (adapted from the Chromium project). diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 0bd82b769f..1b9d31d752 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -594,7 +594,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { if (abi_index != -1) { exported = true; String abi = abis[abi_index]; - String dst_path = "lib/" + abi + "/" + p_so.path.get_file(); + String dst_path = String("lib").plus_file(abi).plus_file(p_so.path.get_file()); Vector<uint8_t> array = FileAccess::get_file_as_array(p_so.path); Error store_err = store_in_apk(ed, dst_path, array); ERR_FAIL_COND_V(store_err, store_err); @@ -665,6 +665,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { bool screen_support_large = p_preset->get("screen/support_large"); bool screen_support_xlarge = p_preset->get("screen/support_xlarge"); + int xr_mode_index = p_preset->get("graphics/xr_mode"); + Vector<String> perms; const char **aperms = android_perms; @@ -822,6 +824,20 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { encode_uint32(min_gles3 ? 0x00030000 : 0x00020000, &p_manifest.write[iofs + 16]); } + if (tname == "meta-data" && attrname == "name" && string_table[attr_value] == "xr_mode_metadata_name") { + // Update the meta-data 'android:name' attribute based on the selected XR mode. + if (xr_mode_index == 1 /* XRMode.OVR */) { + string_table.write[attr_value] = "com.samsung.android.vr.application.mode"; + } + } + + if (tname == "meta-data" && attrname == "value" && string_table[attr_value] == "xr_mode_metadata_value") { + // Update the meta-data 'android:value' attribute based on the selected XR mode. + if (xr_mode_index == 1 /* XRMode.OVR */) { + string_table.write[attr_value] = "vr_only"; + } + } + iofs += 20; } @@ -1139,6 +1155,7 @@ public: virtual void get_export_options(List<ExportOption> *r_options) { + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), "")); @@ -2071,6 +2088,14 @@ public: } } + int xr_mode_index = p_preset->get("graphics/xr_mode"); + if (xr_mode_index == 1 /* XRMode.OVR */) { + cl.push_back("--xr_mode_ovr"); + } else { + // XRMode.REGULAR is the default. + cl.push_back("--xr_mode_regular"); + } + if (use_32_fb) cl.push_back("--use_depth_32"); diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp index 63bc5f69d1..5b8cf01138 100644 --- a/platform/android/file_access_jandroid.cpp +++ b/platform/android/file_access_jandroid.cpp @@ -62,7 +62,7 @@ Error FileAccessJAndroid::_open(const String &p_path, int p_mode_flags) { JNIEnv *env = ThreadAndroid::get_env(); jstring js = env->NewStringUTF(path.utf8().get_data()); - int res = env->CallIntMethod(io, _file_open, js, p_mode_flags & WRITE ? true : false); + int res = env->CallIntMethod(io, _file_open, js, (p_mode_flags & WRITE) ? true : false); env->DeleteLocalRef(js); OS::get_singleton()->print("fopen: '%s' ret %i\n", path.utf8().get_data(), res); diff --git a/platform/android/java/AndroidManifest.xml b/platform/android/java/AndroidManifest.xml index 9997950137..3152ef12cd 100644 --- a/platform/android/java/AndroidManifest.xml +++ b/platform/android/java/AndroidManifest.xml @@ -13,7 +13,7 @@ <!--glEsVersion is modified by the exporter, changing this value here has no effect--> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> -<!--Adding custom text to manifest is fine, but do it outside the custom user and application BEGIN/ENDregions, as that gets rewritten--> +<!--Adding custom text to manifest is fine, but do it outside the custom user and application BEGIN/END regions, as that gets rewritten--> <!--Custom permissions XML added by add-ons. It's recommended to add them from the export preset, though--> <!--CHUNK_USER_PERMISSIONS_BEGIN--> @@ -25,12 +25,15 @@ <!--The following values are replaced when Godot exports, modifying them here has no effect. Do these changes in the--> <!--export preset. Adding new ones is fine.--> +<!-- XR mode metadata. This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. --> + <meta-data android:name="xr_mode_metadata_name" android:value="xr_mode_metadata_value"/> + <activity android:name="org.godotengine.godot.Godot" android:label="@string/godot_project_name_string" - android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" android:launchMode="singleTask" android:screenOrientation="landscape" - android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize" + android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" android:resizeableActivity="false" tools:ignore="UnusedAttribute"> diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java index 751e885118..6e1841fa8b 100644 --- a/platform/android/java/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -58,7 +58,6 @@ import android.os.Environment; import android.os.Messenger; import android.provider.Settings.Secure; import android.support.v4.content.ContextCompat; -import android.util.Log; import android.view.Display; import android.view.KeyEvent; import android.view.MotionEvent; @@ -115,6 +114,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC private Button mPauseButton; private Button mWiFiSettingsButton; + private XRMode xrMode = XRMode.REGULAR; private boolean use_32_bits = false; private boolean use_immersive = false; private boolean use_debug_opengl = false; @@ -282,7 +282,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC // ...add to FrameLayout layout.addView(edittext); - mView = new GodotView(this, XRMode.PANCAKE, use_gl3, use_32_bits, use_debug_opengl); + mView = new GodotView(this, xrMode, use_gl3, use_32_bits, use_debug_opengl); layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); edittext.setView(mView); io.setEdit(edittext); @@ -488,7 +488,11 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC for (int i = 0; i < command_line.length; i++) { boolean has_extra = i < command_line.length - 1; - if (command_line[i].equals("--use_depth_32")) { + if (command_line[i].equals(XRMode.REGULAR.cmdLineArg)) { + xrMode = XRMode.REGULAR; + } else if (command_line[i].equals(XRMode.OVR.cmdLineArg)) { + xrMode = XRMode.OVR; + } else if (command_line[i].equals("--use_depth_32")) { use_32_bits = true; } else if (command_line[i].equals("--debug_opengl")) { use_debug_opengl = true; diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java index 1c189a1579..fc3e47e69d 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/src/org/godotengine/godot/GodotView.java @@ -40,9 +40,9 @@ import org.godotengine.godot.xr.XRMode; import org.godotengine.godot.xr.ovr.OvrConfigChooser; import org.godotengine.godot.xr.ovr.OvrContextFactory; import org.godotengine.godot.xr.ovr.OvrWindowSurfaceFactory; -import org.godotengine.godot.xr.pancake.PancakeConfigChooser; -import org.godotengine.godot.xr.pancake.PancakeContextFactory; -import org.godotengine.godot.xr.pancake.PancakeFallbackConfigChooser; +import org.godotengine.godot.xr.regular.RegularConfigChooser; +import org.godotengine.godot.xr.regular.RegularContextFactory; +import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser; /** * A simple GLSurfaceView sub-class that demonstrate how to perform @@ -123,7 +123,7 @@ public class GodotView extends GLSurfaceView { setEGLWindowSurfaceFactory(new OvrWindowSurfaceFactory()); break; - case PANCAKE: + case REGULAR: default: /* By default, GLSurfaceView() creates a RGB_565 opaque surface. * If we want a translucent one, we should change the surface's @@ -137,7 +137,7 @@ public class GodotView extends GLSurfaceView { /* Setup the context factory for 2.0 rendering. * See ContextFactory class definition below */ - setEGLContextFactory(new PancakeContextFactory()); + setEGLContextFactory(new RegularContextFactory()); /* We need to choose an EGLConfig that matches the format of * our surface exactly. This is going to be done in our @@ -147,15 +147,15 @@ public class GodotView extends GLSurfaceView { if (GLUtils.use_32) { setEGLConfigChooser(translucent ? - new PancakeFallbackConfigChooser(8, 8, 8, 8, 24, stencil, - new PancakeConfigChooser(8, 8, 8, 8, 16, stencil)) : - new PancakeFallbackConfigChooser(8, 8, 8, 8, 24, stencil, - new PancakeConfigChooser(5, 6, 5, 0, 16, stencil))); + new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil, + new RegularConfigChooser(8, 8, 8, 8, 16, stencil)) : + new RegularFallbackConfigChooser(8, 8, 8, 8, 24, stencil, + new RegularConfigChooser(5, 6, 5, 0, 16, stencil))); } else { setEGLConfigChooser(translucent ? - new PancakeConfigChooser(8, 8, 8, 8, 16, stencil) : - new PancakeConfigChooser(5, 6, 5, 0, 16, stencil)); + new RegularConfigChooser(8, 8, 8, 8, 16, stencil) : + new RegularConfigChooser(5, 6, 5, 0, 16, stencil)); } break; } diff --git a/platform/android/java/src/org/godotengine/godot/xr/XRMode.java b/platform/android/java/src/org/godotengine/godot/xr/XRMode.java index cbc8a1e902..dd5701af7d 100644 --- a/platform/android/java/src/org/godotengine/godot/xr/XRMode.java +++ b/platform/android/java/src/org/godotengine/godot/xr/XRMode.java @@ -34,6 +34,16 @@ package org.godotengine.godot.xr; * Godot available XR modes. */ public enum XRMode { - PANCAKE, // Regular/flatscreen - OVR, // Oculus mobile VR SDK + REGULAR(0, "Regular", "--xr_mode_regular"), // Regular/flatscreen + OVR(1, "Oculus Mobile VR", "--xr_mode_ovr"); + + final int index; + final String label; + public final String cmdLineArg; + + XRMode(int index, String label, String cmdLineArg) { + this.index = index; + this.label = label; + this.cmdLineArg = cmdLineArg; + } } diff --git a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeConfigChooser.java b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java index ac19a09e76..3836967f86 100644 --- a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeConfigChooser.java +++ b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java @@ -1,5 +1,5 @@ /*************************************************************************/ -/* PancakeConfigChooser.java */ +/* RegularConfigChooser.java */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.xr.pancake; +package org.godotengine.godot.xr.regular; import android.opengl.GLSurfaceView; import javax.microedition.khronos.egl.EGL10; @@ -39,9 +39,9 @@ import org.godotengine.godot.utils.GLUtils; /** * Used to select the egl config for pancake games. */ -public class PancakeConfigChooser implements GLSurfaceView.EGLConfigChooser { +public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { - private static final String TAG = PancakeConfigChooser.class.getSimpleName(); + private static final String TAG = RegularConfigChooser.class.getSimpleName(); private int[] mValue = new int[1]; @@ -69,7 +69,7 @@ public class PancakeConfigChooser implements GLSurfaceView.EGLConfigChooser { EGL10.EGL_NONE }; - public PancakeConfigChooser(int r, int g, int b, int a, int depth, int stencil) { + public RegularConfigChooser(int r, int g, int b, int a, int depth, int stencil) { mRedSize = r; mGreenSize = g; mBlueSize = b; diff --git a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeContextFactory.java b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularContextFactory.java index aca6ffdba6..4f1e9a696b 100644 --- a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeContextFactory.java +++ b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularContextFactory.java @@ -1,5 +1,5 @@ /*************************************************************************/ -/* PancakeContextFactory.java */ +/* RegularContextFactory.java */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.xr.pancake; +package org.godotengine.godot.xr.regular; import android.opengl.GLSurfaceView; import android.util.Log; @@ -42,8 +42,8 @@ import org.godotengine.godot.utils.GLUtils; /** * Factory used to setup the opengl context for pancake games. */ -public class PancakeContextFactory implements GLSurfaceView.EGLContextFactory { - private static final String TAG = PancakeContextFactory.class.getSimpleName(); +public class RegularContextFactory implements GLSurfaceView.EGLContextFactory { + private static final String TAG = RegularContextFactory.class.getSimpleName(); private static final int _EGL_CONTEXT_FLAGS_KHR = 0x30FC; private static final int _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR = 0x00000001; diff --git a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeFallbackConfigChooser.java b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java index e19f218916..f5718ef2b3 100644 --- a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeFallbackConfigChooser.java +++ b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java @@ -1,5 +1,5 @@ /*************************************************************************/ -/* PancakeFallbackConfigChooser.java */ +/* RegularFallbackConfigChooser.java */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.xr.pancake; +package org.godotengine.godot.xr.regular; import android.util.Log; import javax.microedition.khronos.egl.EGL10; @@ -37,13 +37,13 @@ import javax.microedition.khronos.egl.EGLDisplay; import org.godotengine.godot.utils.GLUtils; /* Fallback if 32bit View is not supported*/ -public class PancakeFallbackConfigChooser extends PancakeConfigChooser { +public class RegularFallbackConfigChooser extends RegularConfigChooser { - private static final String TAG = PancakeFallbackConfigChooser.class.getSimpleName(); + private static final String TAG = RegularFallbackConfigChooser.class.getSimpleName(); - private PancakeConfigChooser fallback; + private RegularConfigChooser fallback; - public PancakeFallbackConfigChooser(int r, int g, int b, int a, int depth, int stencil, PancakeConfigChooser fallback) { + public RegularFallbackConfigChooser(int r, int g, int b, int a, int depth, int stencil, RegularConfigChooser fallback) { super(r, g, b, a, depth, stencil); this.fallback = fallback; } diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 466f79c215..77f077456e 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -289,7 +289,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { PoolVector<int>::Write w = sarr.write(); env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); - w = PoolVector<int>::Write(); + w.release(); return sarr; }; @@ -302,7 +302,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { PoolVector<uint8_t>::Write w = sarr.write(); env->GetByteArrayRegion(arr, 0, fCount, reinterpret_cast<signed char *>(w.ptr())); - w = PoolVector<uint8_t>::Write(); + w.release(); return sarr; }; @@ -514,7 +514,7 @@ public: PoolVector<int>::Write w = sarr.write(); env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); - w = PoolVector<int>::Write(); + w.release(); ret = sarr; env->DeleteLocalRef(arr); } break; @@ -528,7 +528,7 @@ public: PoolVector<float>::Write w = sarr.write(); env->GetFloatArrayRegion(arr, 0, fCount, w.ptr()); - w = PoolVector<float>::Write(); + w.release(); ret = sarr; env->DeleteLocalRef(arr); } break; diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 5a708cdaca..2a3e165069 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -128,8 +128,8 @@ def configure(env): if any(platform.machine() in s for s in list_of_x86): env["x86_libtheora_opt_gcc"] = True - if not env['builtin_libwebsockets']: - env.ParseConfig('pkg-config libwebsockets --cflags --libs') + if not env['builtin_wslay']: + env.ParseConfig('pkg-config libwslay --cflags --libs') if not env['builtin_mbedtls']: # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228 @@ -148,8 +148,7 @@ def configure(env): ## Flags env.Prepend(CPPPATH=['#platform/haiku']) - env.Append(CPPFLAGS=['-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED']) - env.Append(CPPFLAGS=['-DMEDIA_KIT_ENABLED']) - # env.Append(CPPFLAGS=['-DFREETYPE_ENABLED']) - env.Append(CPPFLAGS=['-DPTHREAD_NO_RENAME']) # TODO: enable when we have pthread_setname_np + env.Append(CPPDEFINES=['UNIX_ENABLED', 'OPENGL_ENABLED', 'GLES_ENABLED']) + env.Append(CPPDEFINES=['MEDIA_KIT_ENABLED']) + env.Append(CPPDEFINES=['PTHREAD_NO_RENAME']) # TODO: enable when we have pthread_setname_np env.Append(LIBS=['be', 'game', 'media', 'network', 'bnetapi', 'z', 'GL']) diff --git a/platform/iphone/camera_ios.h b/platform/iphone/camera_ios.h index cf747283e1..ceabdba6a3 100644 --- a/platform/iphone/camera_ios.h +++ b/platform/iphone/camera_ios.h @@ -31,12 +31,10 @@ #ifndef CAMERAIOS_H #define CAMERAIOS_H -///@TODO this is a near duplicate of CameraOSX, we should find a way to combine those to minimise code duplication!!!! -// If you fix something here, make sure you fix it there as wel! - #include "servers/camera_server.h" class CameraIOS : public CameraServer { +private: public: CameraIOS(); ~CameraIOS(); diff --git a/platform/iphone/camera_ios.mm b/platform/iphone/camera_ios.mm index 4c11701fdd..029ce6debf 100644 --- a/platform/iphone/camera_ios.mm +++ b/platform/iphone/camera_ios.mm @@ -241,7 +241,6 @@ class CameraFeedIOS : public CameraFeed { private: - bool is_arkit; // if true this feed is updated through ARKit (should only have one and not yet implemented) AVCaptureDevice *device; MyCaptureSession *capture_session; @@ -258,10 +257,6 @@ public: void deactivate_feed(); }; -bool CameraFeedIOS::get_is_arkit() const { - return is_arkit; -}; - AVCaptureDevice *CameraFeedIOS::get_device() const { return device; }; @@ -274,24 +269,16 @@ CameraFeedIOS::CameraFeedIOS() { void CameraFeedIOS::set_device(AVCaptureDevice *p_device) { device = p_device; - if (device == NULL) { - ///@TODO finish this! - is_arkit = true; - name = "ARKit"; + [device retain]; + + // get some info + NSString *device_name = p_device.localizedName; + name = device_name.UTF8String; + position = CameraFeed::FEED_UNSPECIFIED; + if ([p_device position] == AVCaptureDevicePositionBack) { position = CameraFeed::FEED_BACK; - } else { - is_arkit = false; - [device retain]; - - // get some info - NSString *device_name = p_device.localizedName; - name = device_name.UTF8String; - position = CameraFeed::FEED_UNSPECIFIED; - if ([p_device position] == AVCaptureDevicePositionBack) { - position = CameraFeed::FEED_BACK; - } else if ([p_device position] == AVCaptureDevicePositionFront) { - position = CameraFeed::FEED_FRONT; - }; + } else if ([p_device position] == AVCaptureDevicePositionFront) { + position = CameraFeed::FEED_FRONT; }; }; @@ -308,15 +295,11 @@ CameraFeedIOS::~CameraFeedIOS() { }; bool CameraFeedIOS::activate_feed() { - if (is_arkit) { - ///@TODO to implement; + if (capture_session) { + // already recording! } else { - if (capture_session) { - // already recording! - } else { - // start camera capture - capture_session = [[MyCaptureSession alloc] initForFeed:this andDevice:device]; - }; + // start camera capture + capture_session = [[MyCaptureSession alloc] initForFeed:this andDevice:device]; }; return true; @@ -376,14 +359,14 @@ void CameraIOS::update_feeds() { // this way of doing things is deprecated but still works, // rewrite to using AVCaptureDeviceDiscoverySession - AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:[NSArray arrayWithObjects:AVCaptureDeviceTypeBuiltInTelephotoCamera, AVCaptureDeviceTypeBuiltInDualCamera, AVCaptureDeviceTypeBuiltInTrueDepthCamera] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified]; + AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:[NSArray arrayWithObjects:AVCaptureDeviceTypeBuiltInTelephotoCamera, AVCaptureDeviceTypeBuiltInDualCamera, AVCaptureDeviceTypeBuiltInTrueDepthCamera, AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified]; // remove devices that are gone.. for (int i = feeds.size() - 1; i >= 0; i--) { - Ref<CameraFeedIOS> feed = (Ref<CameraFeedIOS>)feeds[i]; + Ref<CameraFeedIOS> feed(feeds[i]); - if (feed->get_is_arkit()) { - // ignore, this is our arkit entry + if (feed.is_null()) { + // feed not managed by us } else if (![session.devices containsObject:feed->get_device()]) { // remove it from our array, this will also destroy it ;) remove_feed(feed); @@ -393,9 +376,13 @@ void CameraIOS::update_feeds() { // add new devices.. for (AVCaptureDevice *device in session.devices) { bool found = false; + for (int i = 0; i < feeds.size() && !found; i++) { - Ref<CameraFeedIOS> feed = (Ref<CameraFeedIOS>)feeds[i]; - if (feed->get_device() == device) { + Ref<CameraFeedIOS> feed(feeds[i]); + + if (feed.is_null()) { + // feed not managed by us + } else if (feed->get_device() == device) { found = true; }; }; @@ -410,9 +397,29 @@ void CameraIOS::update_feeds() { }; CameraIOS::CameraIOS() { + // check if we have our usage description + NSString *usage_desc = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSCameraUsageDescription"]; + if (usage_desc == NULL) { + // don't initialise if we don't get anything + print_line("No NSCameraUsageDescription key in pList, no access to cameras."); + return; + } else if (usage_desc.length == 0) { + // don't initialise if we don't get anything + print_line("Empty NSCameraUsageDescription key in pList, no access to cameras."); + return; + } + + // now we'll request access. + // If this is the first time the user will be prompted with the string (iOS will read it). + // Once a decision is made it is returned. If the user wants to change it later on they + // need to go into setting. + print_line("Requesting Camera permissions"); + [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) { if (granted) { + print_line("Access to cameras granted!"); + // Find available cameras we have at this time update_feeds(); diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index daf4f405fd..f646b8b1d5 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -43,7 +43,7 @@ def configure(env): ## Build type if (env["target"].startswith("release")): - env.Append(CPPFLAGS=['-DNDEBUG', '-DNS_BLOCK_ASSERTIONS=1']) + env.Append(CPPDEFINES=['NDEBUG', ('NS_BLOCK_ASSERTIONS', 1)]) if (env["optimize"] == "speed"): #optimize for speed (default) env.Append(CCFLAGS=['-O2', '-ftree-vectorize', '-fomit-frame-pointer']) env.Append(LINKFLAGS=['-O2']) @@ -52,11 +52,11 @@ def configure(env): env.Append(LINKFLAGS=['-Os']) if env["target"] == "release_debug": - env.Append(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED']) elif (env["target"] == "debug"): env.Append(CCFLAGS=['-gdwarf-2', '-O0']) - env.Append(CPPFLAGS=['-D_DEBUG', '-DDEBUG=1', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CPPDEFINES=['_DEBUG', ('DEBUG', 1), 'DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) if (env["use_lto"]): env.Append(CCFLAGS=['-flto']) @@ -112,8 +112,8 @@ def configure(env): elif (env["arch"] == "arm64"): detect_darwin_sdk_path('iphone', env) env.Append(CCFLAGS='-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=10.0 -isysroot $IPHONESDK'.split()) - env.Append(CPPFLAGS=['-DNEED_LONG_INT']) - env.Append(CPPFLAGS=['-DLIBYUV_DISABLE_NEON']) + env.Append(CPPDEFINES=['NEED_LONG_INT']) + env.Append(CPPDEFINES=['LIBYUV_DISABLE_NEON']) # Disable exceptions on non-tools (template) builds if not env['tools']: @@ -154,19 +154,20 @@ def configure(env): '-framework', 'Security', '-framework', 'SystemConfiguration', '-framework', 'UIKit', + '-framework', 'ARKit', ]) # Feature options if env['game_center']: - env.Append(CPPFLAGS=['-DGAME_CENTER_ENABLED']) + env.Append(CPPDEFINES=['GAME_CENTER_ENABLED']) env.Append(LINKFLAGS=['-framework', 'GameKit']) if env['store_kit']: - env.Append(CPPFLAGS=['-DSTOREKIT_ENABLED']) + env.Append(CPPDEFINES=['STOREKIT_ENABLED']) env.Append(LINKFLAGS=['-framework', 'StoreKit']) if env['icloud']: - env.Append(CPPFLAGS=['-DICLOUD_ENABLED']) + env.Append(CPPDEFINES=['ICLOUD_ENABLED']) env.Prepend(CPPPATH=['$IPHONESDK/usr/include', '$IPHONESDK/System/Library/Frameworks/OpenGLES.framework/Headers', @@ -176,4 +177,4 @@ def configure(env): env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate' env.Prepend(CPPPATH=['#platform/iphone']) - env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DCOREAUDIO_ENABLED']) + env.Append(CPPDEFINES=['IPHONE_ENABLED', 'UNIX_ENABLED', 'GLES_ENABLED', 'COREAUDIO_ENABLED']) diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index b2064472e4..85a45d62f8 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -95,7 +95,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform { Vector<ExportArchitecture> _get_supported_architectures(); Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset); - void _add_assets_to_project(Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets); + void _add_assets_to_project(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets); Error _export_additional_assets(const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, Vector<IOSExportAsset> &r_exported_assets); Error _export_additional_assets(const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets); @@ -268,8 +268,9 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/in_app_purchases"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/push_notifications"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/camera_usage_description"), "Godot would like to use your camera")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photolibrary_usage_description"), "Godot would like to use your photos")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/camera_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the camera"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photolibrary_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need access to the photo library"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/landscape_left"), true)); @@ -398,6 +399,9 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ } else if (lines[i].find("$camera_usage_description") != -1) { String description = p_preset->get("privacy/camera_usage_description"); strnew += lines[i].replace("$camera_usage_description", description) + "\n"; + } else if (lines[i].find("$microphone_usage_description") != -1) { + String description = p_preset->get("privacy/microphone_usage_description"); + strnew += lines[i].replace("$microphone_usage_description", description) + "\n"; } else if (lines[i].find("$photolibrary_usage_description") != -1) { String description = p_preset->get("privacy/photolibrary_usage_description"); strnew += lines[i].replace("$photolibrary_usage_description", description) + "\n"; @@ -564,7 +568,7 @@ Error EditorExportPlatformIOS::_walk_dir_recursive(DirAccess *p_da, FileHandler dirs.push_back(path); } } else { - Error err = p_handler(current_dir + "/" + path, p_userdata); + Error err = p_handler(current_dir.plus_file(path), p_userdata); if (err) { p_da->list_dir_end(); return err; @@ -656,7 +660,7 @@ struct ExportLibsData { String dest_dir; }; -void EditorExportPlatformIOS::_add_assets_to_project(Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets) { +void EditorExportPlatformIOS::_add_assets_to_project(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets) { Vector<Ref<EditorExportPlugin> > export_plugins = EditorExport::get_singleton()->get_export_plugins(); Vector<String> frameworks; for (int i = 0; i < export_plugins.size(); ++i) { @@ -714,7 +718,28 @@ void EditorExportPlatformIOS::_add_assets_to_project(Vector<uint8_t> &p_project_ // Note, frameworks like gamekit are always included in our project.pbxprof file // even if turned off in capabilities. - // Frameworks that are used by modules (like arkit) we may need to optionally add here. + + // We do need our ARKit framework + if ((bool)p_preset->get("capabilities/arkit")) { + String build_id = (++current_id).str(); + String ref_id = (++current_id).str(); + + if (pbx_frameworks_build.length() > 0) { + pbx_frameworks_build += ",\n"; + pbx_frameworks_refs += ",\n"; + } + + pbx_frameworks_build += build_id; + pbx_frameworks_refs += ref_id; + + Dictionary format_dict; + format_dict["build_id"] = build_id; + format_dict["ref_id"] = ref_id; + format_dict["name"] = "ARKit.framework"; + format_dict["file_path"] = "System/Library/Frameworks/ARKit.framework"; + format_dict["file_type"] = "wrapper.framework"; + pbx_files += file_info_format.format(format_dict, "$_"); + } String str = String::utf8((const char *)p_project_data.ptr(), p_project_data.size()); str = str.replace("$additional_pbx_files", pbx_files); @@ -763,7 +788,7 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir } } - String destination = destination_dir + "/" + asset.get_file(); + String destination = destination_dir.plus_file(asset.get_file()); Error err = dir_exists ? da->copy_dir(asset, destination) : da->copy(asset, destination); memdelete(da); if (err) { @@ -1045,7 +1070,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p print_line("Exporting additional assets"); Vector<IOSExportAsset> assets; _export_additional_assets(dest_dir + binary_name, libraries, assets); - _add_assets_to_project(project_file_data, assets); + _add_assets_to_project(p_preset, project_file_data, assets); String project_file_name = dest_dir + binary_name + ".xcodeproj/project.pbxproj"; FileAccess *f = FileAccess::open(project_file_name, FileAccess::WRITE); if (!f) { diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index 1cb8d0e44e..4641b2c4ac 100644 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -494,7 +494,7 @@ static void clear_touches() { #ifdef DEBUG_ENABLED GLenum err = glGetError(); if (err) - NSLog(@"%x error", err); + NSLog(@"DrawView: %x error", err); #endif } diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 145ac42863..10680ad1f5 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -69,9 +69,14 @@ def configure(env): exec(f.read(), em_config) except StandardError as e: raise RuntimeError("Emscripten configuration file '%s' is invalid:\n%s" % (em_config_file, e)) - if 'EMSCRIPTEN_ROOT' not in em_config: - raise RuntimeError("'EMSCRIPTEN_ROOT' missing in Emscripten configuration file '%s'" % em_config_file) - env.PrependENVPath('PATH', em_config['EMSCRIPTEN_ROOT']) + if 'BINARYEN_ROOT' in em_config and os.path.isdir(os.path.join(em_config.get('BINARYEN_ROOT'), 'emscripten')): + # New style, emscripten path as a subfolder of BINARYEN_ROOT + env.PrependENVPath('PATH', os.path.join(em_config.get('BINARYEN_ROOT'), 'emscripten')) + elif 'EMSCRIPTEN_ROOT' in em_config: + # Old style (but can be there as a result from previous activation, so do last) + env.PrependENVPath('PATH', em_config.get('EMSCRIPTEN_ROOT')) + else: + raise RuntimeError("'BINARYEN_ROOT' or 'EMSCRIPTEN_ROOT' missing in Emscripten configuration file '%s'" % em_config_file) env['CC'] = 'emcc' env['CXX'] = 'em++' diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 2175797dec..881ed05025 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -56,7 +56,7 @@ def configure(env): env.Prepend(CCFLAGS=['-O2']) else: #optimize for size env.Prepend(CCFLAGS=['-Os']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) if (env["debug_symbols"] == "full"): @@ -64,7 +64,7 @@ def configure(env): elif (env["target"] == "debug"): env.Prepend(CCFLAGS=['-g3']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) ## Architecture @@ -90,7 +90,7 @@ def configure(env): env['AR'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ar" env['RANLIB'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib" env['AS'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-as" - env.Append(CPPFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define + env.Append(CPPDEFINES=['__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define detect_darwin_sdk_path('osx', env) env.Append(CCFLAGS=['-isysroot', '$MACOS_SDK_PATH']) @@ -112,10 +112,10 @@ def configure(env): env['AR'] = basecmd + "ar" env['RANLIB'] = basecmd + "ranlib" env['AS'] = basecmd + "as" - env.Append(CPPFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define + env.Append(CPPDEFINES=['__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define if (env["CXX"] == "clang++"): - env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) + env.Append(CPPDEFINES=['TYPED_METHOD_BIND']) env["CC"] = "clang" env["LINK"] = "clang++" @@ -127,7 +127,7 @@ def configure(env): ## Flags env.Prepend(CPPPATH=['#platform/osx']) - env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED', '-DCOREMIDI_ENABLED']) + env.Append(CPPDEFINES=['OSX_ENABLED', 'UNIX_ENABLED', 'GLES_ENABLED', 'APPLE_STYLE_KEYS', 'COREAUDIO_ENABLED', 'COREMIDI_ENABLED']) env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'AVFoundation', '-framework', 'CoreMedia', '-framework', 'CoreVideo']) env.Append(LIBS=['pthread']) diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index 9dabbb12fc..8cabc45250 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -570,7 +570,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p if (export_format == "dmg") { // write it into our application bundle - file = tmp_app_path_name + "/" + file; + file = tmp_app_path_name.plus_file(file); // write the file, need to add chmod FileAccess *f = FileAccess::open(file, FileAccess::WRITE); diff --git a/platform/server/detect.py b/platform/server/detect.py index a325395d6d..185dce8128 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -66,7 +66,7 @@ def configure(env): env.Prepend(CCFLAGS=['-O2']) else: #optimize for size env.Prepend(CCFLAGS=['-Os']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) @@ -75,7 +75,7 @@ def configure(env): elif (env["target"] == "debug"): env.Prepend(CCFLAGS=['-g3']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) env.Append(LINKFLAGS=['-rdynamic']) ## Architecture @@ -95,7 +95,7 @@ def configure(env): env["CC"] = "clang" env["CXX"] = "clang++" env["LINK"] = "clang++" - env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) + env.Append(CPPDEFINES=['TYPED_METHOD_BIND']) env.extra_suffix = ".llvm" + env.extra_suffix @@ -196,8 +196,8 @@ def configure(env): # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228 env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509']) - if not env['builtin_libwebsockets']: - env.ParseConfig('pkg-config libwebsockets --cflags --libs') + if not env['builtin_wslay']: + env.ParseConfig('pkg-config libwslay --cflags --libs') if not env['builtin_miniupnpc']: # No pkgconfig file so far, hardcode default paths. @@ -216,7 +216,7 @@ def configure(env): env.ParseConfig('pkg-config zlib --cflags --libs') env.Prepend(CPPPATH=['#platform/server']) - env.Append(CPPFLAGS=['-DSERVER_ENABLED', '-DUNIX_ENABLED']) + env.Append(CPPDEFINES=['SERVER_ENABLED', 'UNIX_ENABLED']) if (platform.system() == "Darwin"): env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-lz', '-framework', 'IOKit']) diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py index 00f419f4f0..7da93eafae 100644 --- a/platform/uwp/detect.py +++ b/platform/uwp/detect.py @@ -60,13 +60,13 @@ def configure(env): elif (env["target"] == "release_debug"): env.Append(CCFLAGS=['/O2', '/Zi']) env.Append(CCFLAGS=['/MD']) - env.Append(CPPFLAGS=['/DDEBUG_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED']) env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) elif (env["target"] == "debug"): env.Append(CCFLAGS=['/Zi']) env.Append(CCFLAGS=['/MDd']) - env.Append(CPPFLAGS=['/DDEBUG_ENABLED', '/DDEBUG_MEMORY_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) env.Append(LINKFLAGS=['/DEBUG']) @@ -138,18 +138,18 @@ def configure(env): ## Compile flags env.Prepend(CPPPATH=['#platform/uwp', '#drivers/windows']) - env.Append(CPPFLAGS=['/DUWP_ENABLED', '/DWINDOWS_ENABLED', '/DTYPED_METHOD_BIND']) - env.Append(CPPFLAGS=['/DGLES_ENABLED', '/DGL_GLEXT_PROTOTYPES', '/DEGL_EGLEXT_PROTOTYPES', '/DANGLE_ENABLED']) + env.Append(CPPDEFINES=['UWP_ENABLED', 'WINDOWS_ENABLED', 'TYPED_METHOD_BIND']) + env.Append(CPPDEFINES=['GLES_ENABLED', 'GL_GLEXT_PROTOTYPES', 'EGL_EGLEXT_PROTOTYPES', 'ANGLE_ENABLED']) winver = "0x0602" # Windows 8 is the minimum target for UWP build - env.Append(CPPFLAGS=['/DWINVER=%s' % winver, '/D_WIN32_WINNT=%s' % winver]) + env.Append(CPPDEFINES=[('WINVER', winver), ('_WIN32_WINNT', winver), 'WIN32']) - env.Append(CPPFLAGS=['/D__WRL_NO_DEFAULT_LIB__', '/DWIN32', '/DPNG_ABORT=abort']) + env.Append(CPPDEFINES=['__WRL_NO_DEFAULT_LIB__', ('PNG_ABORT', 'abort')]) env.Append(CPPFLAGS=['/AI', vc_base_path + 'lib/store/references']) env.Append(CPPFLAGS=['/AI', vc_base_path + 'lib/x86/store/references']) env.Append(CCFLAGS='/FS /MP /GS /wd"4453" /wd"28204" /wd"4291" /Zc:wchar_t /Gm- /fp:precise /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo'.split()) - env.Append(CPPFLAGS=['/D_UNICODE', '/DUNICODE', '/D "WINAPI_FAMILY=WINAPI_FAMILY_APP"']) + env.Append(CPPDEFINES=['_UNICODE', 'UNICODE', ('WINAPI_FAMILY', 'WINAPI_FAMILY_APP')]) env.Append(CXXFLAGS=['/ZW']) env.Append(CCFLAGS=['/AI', vc_base_path + '\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR'] + '\\References\\CommonConfiguration\\Neutral']) diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index ec43a4c26f..abb7b391d3 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -32,6 +32,7 @@ #include "core/bind/core_bind.h" #include "core/io/marshalls.h" #include "core/io/zip_io.h" +#include "core/math/crypto_core.h" #include "core/object.h" #include "core/os/file_access.h" #include "core/project_settings.h" @@ -42,8 +43,6 @@ #include "thirdparty/minizip/unzip.h" #include "thirdparty/minizip/zip.h" -#include "thirdparty/misc/base64.h" -#include "thirdparty/misc/sha256.h" #include <zlib.h> @@ -198,15 +197,12 @@ public: String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len) { - char hash[32]; + unsigned char hash[32]; char base64[45]; - sha256_context ctx; - sha256_init(&ctx); - sha256_hash(&ctx, (uint8_t *)p_block_data, p_block_len); - sha256_done(&ctx, (uint8_t *)hash); - - base64_encode(base64, hash, 32); + CryptoCore::sha256(p_block_data, p_block_len, hash); + size_t len = 0; + CryptoCore::b64_encode((unsigned char *)base64, 45, &len, (unsigned char *)hash, 32); base64[44] = '\0'; return String(base64); diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 4b4b507499..cc9ba720a8 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -274,7 +274,7 @@ def configure_mingw(env): elif (env["target"] == "release_debug"): env.Append(CCFLAGS=['-O2']) - env.Append(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) if (env["debug_symbols"] == "full"): @@ -286,7 +286,7 @@ def configure_mingw(env): elif (env["target"] == "debug"): env.Append(CCFLAGS=['-g3']) - env.Append(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) ## Compiler configuration @@ -328,14 +328,11 @@ def configure_mingw(env): ## Compile flags env.Append(CCFLAGS=['-mwindows']) - env.Append(CPPFLAGS=['-DWINDOWS_ENABLED']) - env.Append(CPPFLAGS=['-DOPENGL_ENABLED']) - env.Append(CPPFLAGS=['-DWASAPI_ENABLED']) - env.Append(CPPFLAGS=['-DWINMIDI_ENABLED']) - env.Append(CPPFLAGS=['-DWINVER=%s' % env['target_win_version'], '-D_WIN32_WINNT=%s' % env['target_win_version']]) + env.Append(CPPDEFINES=['WINDOWS_ENABLED', 'OPENGL_ENABLED', 'WASAPI_ENABLED', 'WINMIDI_ENABLED']) + env.Append(CPPDEFINES=[('WINVER', env['target_win_version']), ('_WIN32_WINNT', env['target_win_version'])]) env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid']) - env.Append(CPPFLAGS=['-DMINGW_ENABLED']) + env.Append(CPPDEFINES=['MINGW_ENABLED']) # resrc env.Append(BUILDERS={'RES': env.Builder(action=build_res_file, suffix='.o', src_suffix='.rc')}) diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 4a72d07adc..827daa2d58 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -34,6 +34,8 @@ #include "editor/editor_settings.h" #include "platform/windows/logo.gen.h" +static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size); + class EditorExportPlatformWindows : public EditorExportPlatformPC { public: @@ -172,6 +174,80 @@ void register_windows_exporter() { platform->set_release_64("windows_64_release.exe"); platform->set_debug_64("windows_64_debug.exe"); platform->set_os_name("Windows"); + platform->set_fixup_embedded_pck_func(&fixup_embedded_pck); EditorExport::get_singleton()->add_export_platform(platform); } + +static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { + + // Patch the header of the "pck" section in the PE file so that it corresponds to the embedded data + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE); + if (!f) { + return ERR_CANT_OPEN; + } + + // Jump to the PE header and check the magic number + { + f->seek(0x3c); + uint32_t pe_pos = f->get_32(); + + f->seek(pe_pos); + uint32_t magic = f->get_32(); + if (magic != 0x00004550) { + f->close(); + return ERR_FILE_CORRUPT; + } + } + + // Process header + + int num_sections; + { + int64_t header_pos = f->get_position(); + + f->seek(header_pos + 2); + num_sections = f->get_16(); + f->seek(header_pos + 16); + uint16_t opt_header_size = f->get_16(); + + // Skip rest of header + optional header to go to the section headers + f->seek(f->get_position() + 2 + opt_header_size); + } + + // Search for the "pck" section + + int64_t section_table_pos = f->get_position(); + + bool found = false; + for (int i = 0; i < num_sections; ++i) { + + int64_t section_header_pos = section_table_pos + i * 40; + f->seek(section_header_pos); + + uint8_t section_name[9]; + f->get_buffer(section_name, 8); + section_name[8] = '\0'; + + if (strcmp((char *)section_name, "pck") == 0) { + // "pck" section found, let's patch! + + // Set virtual size to a little to avoid it taking memory (zero would give issues) + f->seek(section_header_pos + 8); + f->store_32(8); + + f->seek(section_header_pos + 16); + f->store_32(p_embedded_size); + f->seek(section_header_pos + 20); + f->store_32(p_embedded_start); + + found = true; + break; + } + } + + f->close(); + + return found ? OK : ERR_FILE_CORRUPT; +} diff --git a/platform/windows/godot_windows.cpp b/platform/windows/godot_windows.cpp index 0b52682c7c..11bfea6922 100644 --- a/platform/windows/godot_windows.cpp +++ b/platform/windows/godot_windows.cpp @@ -34,6 +34,17 @@ #include <locale.h> #include <stdio.h> +// For export templates, add a section; the exporter will patch it to enclose +// the data appended to the executable (bundled PCK) +#ifndef TOOLS_ENABLED +#if defined _MSC_VER +#pragma section("pck", read) +__declspec(allocate("pck")) static char dummy[8] = { 0 }; +#elif defined __GNUC__ +static const char dummy[8] __attribute__((section("pck"), used)) = { 0 }; +#endif +#endif + PCHAR * CommandLineToArgvA( PCHAR CmdLine, diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 5876a385c6..0a9cfc0214 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -843,8 +843,8 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (wParam==VK_WIN) TODO wtf is this? meta_mem=uMsg==WM_KEYDOWN; */ - - } //fallthrough + FALLTHROUGH; + } case WM_CHAR: { ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE); @@ -2586,7 +2586,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, modstr.resize(cmdline.size()); for (int i = 0; i < cmdline.size(); i++) modstr.write[i] = cmdline[i]; - int ret = CreateProcessW(NULL, modstr.ptrw(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS, NULL, NULL, si_w, &pi.pi); + int ret = CreateProcessW(NULL, modstr.ptrw(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, NULL, NULL, si_w, &pi.pi); ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK); if (p_blocking) { diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index 9718b03164..d70b947fcc 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -145,6 +145,7 @@ Error ContextGL_X11::initialize() { break; } } + XFree(fbc); ERR_FAIL_COND_V(!fbconfig, ERR_UNCONFIGURED); swa.background_pixmap = None; @@ -159,6 +160,7 @@ Error ContextGL_X11::initialize() { vi = glXGetVisualFromFBConfig(x11_display, fbc[0]); fbconfig = fbc[0]; + XFree(fbc); } int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler); diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 9614104750..f3a486df02 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -98,7 +98,7 @@ def configure(env): env.Prepend(CCFLAGS=['-O2']) else: #optimize for size env.Prepend(CCFLAGS=['-Os']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) @@ -107,7 +107,7 @@ def configure(env): elif (env["target"] == "debug"): env.Prepend(CCFLAGS=['-g3']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) env.Append(LINKFLAGS=['-rdynamic']) ## Architecture @@ -127,7 +127,7 @@ def configure(env): env["CC"] = "clang" env["CXX"] = "clang++" env["LINK"] = "clang++" - env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) + env.Append(CPPDEFINES=['TYPED_METHOD_BIND']) env.extra_suffix = ".llvm" + env.extra_suffix if env['use_lld']: @@ -197,7 +197,7 @@ def configure(env): env.ParseConfig('pkg-config xi --cflags --libs') if (env['touch']): - env.Append(CPPFLAGS=['-DTOUCH_ENABLED']) + env.Append(CPPDEFINES=['TOUCH_ENABLED']) # FIXME: Check for existence of the libs before parsing their flags with pkg-config @@ -266,8 +266,8 @@ def configure(env): # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228 env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509']) - if not env['builtin_libwebsockets']: - env.ParseConfig('pkg-config libwebsockets --cflags --libs') + if not env['builtin_wslay']: + env.ParseConfig('pkg-config libwslay --cflags --libs') if not env['builtin_miniupnpc']: # No pkgconfig file so far, hardcode default paths. @@ -283,7 +283,7 @@ def configure(env): if (os.system("pkg-config --exists alsa") == 0): # 0 means found print("Enabling ALSA") - env.Append(CPPFLAGS=["-DALSA_ENABLED", "-DALSAMIDI_ENABLED"]) + env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) # Don't parse --cflags, we don't need to add /usr/include/alsa to include path env.ParseConfig('pkg-config alsa --libs') else: @@ -292,18 +292,18 @@ def configure(env): if env['pulseaudio']: if (os.system("pkg-config --exists libpulse") == 0): # 0 means found print("Enabling PulseAudio") - env.Append(CPPFLAGS=["-DPULSEAUDIO_ENABLED"]) + env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED"]) env.ParseConfig('pkg-config --cflags --libs libpulse') else: print("PulseAudio development libraries not found, disabling driver") if (platform.system() == "Linux"): - env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"]) + env.Append(CPPDEFINES=["JOYDEV_ENABLED"]) if env['udev']: if (os.system("pkg-config --exists libudev") == 0): # 0 means found print("Enabling udev support") - env.Append(CPPFLAGS=["-DUDEV_ENABLED"]) + env.Append(CPPDEFINES=["UDEV_ENABLED"]) env.ParseConfig('pkg-config libudev --cflags --libs') else: print("libudev development libraries not found, disabling udev support") @@ -313,7 +313,7 @@ def configure(env): env.ParseConfig('pkg-config zlib --cflags --libs') env.Prepend(CPPPATH=['#platform/x11']) - env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED']) + env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED', 'OPENGL_ENABLED', 'GLES_ENABLED']) env.Append(LIBS=['GL', 'pthread']) if (platform.system() == "Linux"): @@ -324,6 +324,9 @@ def configure(env): if env["execinfo"]: env.Append(LIBS=['execinfo']) + + if not env['tools']: + env.Append(LINKFLAGS=['-T', 'platform/x11/pck_embed.ld']) ## Cross-compilation diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp index f7d98c1d68..8767aac517 100644 --- a/platform/x11/export/export.cpp +++ b/platform/x11/export/export.cpp @@ -30,10 +30,13 @@ #include "export.h" +#include "core/os/file_access.h" #include "editor/editor_export.h" #include "platform/x11/logo.gen.h" #include "scene/resources/texture.h" +static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size); + void register_x11_exporter() { Ref<EditorExportPlatformPC> platform; @@ -53,6 +56,115 @@ void register_x11_exporter() { platform->set_debug_64("linux_x11_64_debug"); platform->set_os_name("X11"); platform->set_chmod_flags(0755); + platform->set_fixup_embedded_pck_func(&fixup_embedded_pck); EditorExport::get_singleton()->add_export_platform(platform); } + +static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { + + // Patch the header of the "pck" section in the ELF file so that it corresponds to the embedded data + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE); + if (!f) { + return ERR_CANT_OPEN; + } + + // Read and check ELF magic number + { + uint32_t magic = f->get_32(); + if (magic != 0x464c457f) { // 0x7F + "ELF" + f->close(); + return ERR_FILE_CORRUPT; + } + } + + // Read program architecture bits from class field + + int bits = f->get_8() * 32; + + if (bits == 32 && p_embedded_size >= 0x100000000) { + f->close(); + ERR_EXPLAIN("32-bit executables cannot have embedded data >= 4 GiB"); + ERR_FAIL_V(ERR_INVALID_DATA); + } + + // Get info about the section header table + + int64_t section_table_pos; + int64_t section_header_size; + if (bits == 32) { + section_header_size = 40; + f->seek(0x20); + section_table_pos = f->get_32(); + f->seek(0x30); + } else { // 64 + section_header_size = 64; + f->seek(0x28); + section_table_pos = f->get_64(); + f->seek(0x3c); + } + int num_sections = f->get_16(); + int string_section_idx = f->get_16(); + + // Load the strings table + uint8_t *strings; + { + // Jump to the strings section header + f->seek(section_table_pos + string_section_idx * section_header_size); + + // Read strings data size and offset + int64_t string_data_pos; + int64_t string_data_size; + if (bits == 32) { + f->seek(f->get_position() + 0x10); + string_data_pos = f->get_32(); + string_data_size = f->get_32(); + } else { // 64 + f->seek(f->get_position() + 0x18); + string_data_pos = f->get_64(); + string_data_size = f->get_64(); + } + + // Read strings data + f->seek(string_data_pos); + strings = (uint8_t *)memalloc(string_data_size); + if (!strings) { + f->close(); + return ERR_OUT_OF_MEMORY; + } + f->get_buffer(strings, string_data_size); + } + + // Search for the "pck" section + + bool found = false; + for (int i = 0; i < num_sections; ++i) { + + int64_t section_header_pos = section_table_pos + i * section_header_size; + f->seek(section_header_pos); + + uint32_t name_offset = f->get_32(); + if (strcmp((char *)strings + name_offset, "pck") == 0) { + // "pck" section found, let's patch! + + if (bits == 32) { + f->seek(section_header_pos + 0x10); + f->store_32(p_embedded_start); + f->store_32(p_embedded_size); + } else { // 64 + f->seek(section_header_pos + 0x18); + f->store_64(p_embedded_start); + f->store_64(p_embedded_size); + } + + found = true; + break; + } + } + + memfree(strings); + f->close(); + + return found ? OK : ERR_FILE_CORRUPT; +} diff --git a/platform/x11/godot_x11.cpp b/platform/x11/godot_x11.cpp index 9baa4d6dca..755ef7a84f 100644 --- a/platform/x11/godot_x11.cpp +++ b/platform/x11/godot_x11.cpp @@ -43,6 +43,7 @@ int main(int argc, char *argv[]) { setlocale(LC_CTYPE, ""); char *cwd = (char *)malloc(PATH_MAX); + ERR_FAIL_COND_V(!cwd, ERR_OUT_OF_MEMORY); char *ret = getcwd(cwd, PATH_MAX); Error err = Main::setup(argv[0], argc - 1, &argv[1]); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index bf6bc0b464..624efe8815 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -2997,7 +2997,7 @@ void OS_X11::alert(const String &p_alert, const String &p_title) { for (int i = 0; i < path_elems.size(); i++) { for (unsigned int k = 0; k < sizeof(message_programs) / sizeof(char *); k++) { - String tested_path = path_elems[i] + "/" + message_programs[k]; + String tested_path = path_elems[i].plus_file(message_programs[k]); if (FileAccess::exists(tested_path)) { program = tested_path; diff --git a/platform/x11/pck_embed.ld b/platform/x11/pck_embed.ld new file mode 100644 index 0000000000..fe09144d88 --- /dev/null +++ b/platform/x11/pck_embed.ld @@ -0,0 +1,10 @@ +SECTIONS +{ + /* Add a zero-sized section; the exporter will patch it to enclose the data appended to the executable (embedded PCK) */ + pck 0 (NOLOAD) : + { + /* Just some content to avoid the linker discarding the section */ + . = ALIGN(8); + } +} +INSERT AFTER .rodata; |