Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[4.0] [tvOS] tvOS Support #58977

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/tvos_builds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: 📺 tvOS Builds
on: [push, pull_request]

# Global Settings
env:
GODOT_BASE_BRANCH: master
SCONSFLAGS: verbose=yes warnings=extra werror=yes debug_symbols=no module_text_server_fb_enabled=yes

concurrency:
group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-tvos
cancel-in-progress: true

jobs:
tvos-template:
runs-on: "macos-latest"
name: Template (target=release, tools=no)

steps:
- uses: actions/checkout@v2

- name: Setup Godot build cache
uses: ./.github/actions/godot-cache
continue-on-error: true

- name: Setup python and scons
uses: ./.github/actions/godot-deps

- name: Compilation (armv7)
uses: ./.github/actions/godot-build
with:
sconsflags: ${{ env.SCONSFLAGS }}
platform: tvos
target: release
tools: false
tests: false

- name: Upload artifact
uses: ./.github/actions/upload-artifact
1 change: 1 addition & 0 deletions core/input/input_builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def make_default_controller_mappings(target, source, env):
"Mac OS X": "#ifdef OSX_ENABLED",
"Android": "#if defined(__ANDROID__)",
"iOS": "#ifdef IPHONE_ENABLED",
"tvOS": "#ifdef TVOS_ENABLED",
"Javascript": "#ifdef JAVASCRIPT_ENABLED",
"UWP": "#ifdef UWP_ENABLED",
}
Expand Down
51 changes: 51 additions & 0 deletions doc/classes/EditorExportPlugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,57 @@
In case of a directory code-sign will error if you place non code object in directory.
</description>
</method>
<method name="add_tvos_bundle_file">
<return type="void" />
<argument index="0" name="path" type="String" />
<description>
Adds an tvOS bundle file from the given [code]path[/code] to the exported project.
</description>
</method>
<method name="add_tvos_cpp_code">
<return type="void" />
<argument index="0" name="code" type="String" />
<description>
Adds a C++ code to the tvOS export. The final code is created from the code appended by each active export plugin.
</description>
</method>
<method name="add_tvos_embedded_framework">
<return type="void" />
<argument index="0" name="path" type="String" />
<description>
Adds a dynamic library (*.dylib, *.framework) to Linking Phase in tvOS's Xcode project and embeds it into resulting binary.
[b]Note:[/b] For static libraries (*.a) works in same way as [code]add_ios_framework[/code].
This method should not be used for System libraries as they are already present on the device.
</description>
</method>
<method name="add_tvos_framework">
<return type="void" />
<argument index="0" name="path" type="String" />
<description>
Adds a static library (*.a) or dynamic library (*.dylib, *.framework) to Linking Phase in tvOS's Xcode project.
</description>
</method>
<method name="add_tvos_linker_flags">
<return type="void" />
<argument index="0" name="flags" type="String" />
<description>
Adds linker flags for the tvOS export.
</description>
</method>
<method name="add_tvos_plist_content">
<return type="void" />
<argument index="0" name="plist_content" type="String" />
<description>
Adds content for tvOS Property List files.
</description>
</method>
<method name="add_tvos_project_static_lib">
<return type="void" />
<argument index="0" name="path" type="String" />
<description>
Adds a static lib from the given [code]path[/code] to the tvOS project.
</description>
</method>
<method name="skip">
<return type="void" />
<description>
Expand Down
3 changes: 3 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,9 @@
<member name="input_devices/pointing/ios/touch_delay" type="float" setter="" getter="" default="0.15">
Default delay for touch events. This only affects iOS devices.
</member>
<member name="input_devices/pointing/tvos/press_end_delay" type="float" setter="" getter="" default="0.15">
Default delay for end press events. This only affects tvOS devices.
</member>
<member name="internationalization/locale/fallback" type="String" setter="" getter="" default="&quot;en&quot;">
The locale to fall back to if a translation isn't available in a given language. If left empty, [code]en[/code] (English) will be used.
</member>
Expand Down
4 changes: 2 additions & 2 deletions drivers/gles3/rasterizer_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@
#endif
#endif

#if !defined(IPHONE_ENABLED) && !defined(JAVASCRIPT_ENABLED)
#if !defined(UIKIT_ENABLED) && !defined(JAVASCRIPT_ENABLED)
// We include EGL below to get debug callback on GLES2 platforms,
// but EGL is not available on iOS.
// but EGL is not available on iOS/tvOS.
#define CAN_DEBUG
#endif

Expand Down
4 changes: 4 additions & 0 deletions drivers/unix/os_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, St
// Don't compile this code at all to avoid undefined references.
// Actual virtual call goes to OS_JavaScript.
ERR_FAIL_V(ERR_BUG);
#elif defined(TVOS_ENABLED)
ERR_FAIL_V(ERR_CANT_FORK);
#else
if (r_pipe) {
String command = "\"" + p_path + "\"";
Expand Down Expand Up @@ -363,6 +365,8 @@ Error OS_Unix::create_process(const String &p_path, const List<String> &p_argume
// Don't compile this code at all to avoid undefined references.
// Actual virtual call goes to OS_JavaScript.
ERR_FAIL_V(ERR_BUG);
#elif defined(TVOS_ENABLED)
ERR_FAIL_V(ERR_CANT_FORK);
#else
pid_t pid = fork();
ERR_FAIL_COND_V(pid < 0, ERR_CANT_FORK);
Expand Down
2 changes: 1 addition & 1 deletion drivers/vulkan/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if env["use_volk"]:

if env["platform"] == "android":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_ANDROID_KHR"])
elif env["platform"] == "iphone":
elif env["platform"] == "iphone" or env["platform"] == "tvos":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_IOS_MVK"])
elif env["platform"] == "linuxbsd":
env.AppendUnique(CPPDEFINES=["VK_USE_PLATFORM_XLIB_KHR"])
Expand Down
66 changes: 66 additions & 0 deletions editor/editor_export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,65 @@ Vector<String> EditorExportPlugin::get_ios_project_static_libs() const {
return ios_project_static_libs;
}

void EditorExportPlugin::add_tvos_framework(const String &p_path) {
tvos_frameworks.push_back(p_path);
}

void EditorExportPlugin::add_tvos_embedded_framework(const String &p_path) {
tvos_embedded_frameworks.push_back(p_path);
}

Vector<String> EditorExportPlugin::get_tvos_frameworks() const {
return tvos_frameworks;
}

Vector<String> EditorExportPlugin::get_tvos_embedded_frameworks() const {
return tvos_embedded_frameworks;
}

void EditorExportPlugin::add_tvos_plist_content(const String &p_plist_content) {
tvos_plist_content += p_plist_content + "\n";
}

String EditorExportPlugin::get_tvos_plist_content() const {
return tvos_plist_content;
}

void EditorExportPlugin::add_tvos_linker_flags(const String &p_flags) {
if (tvos_linker_flags.length() > 0) {
tvos_linker_flags += ' ';
}
tvos_linker_flags += p_flags;
}

String EditorExportPlugin::get_tvos_linker_flags() const {
return tvos_linker_flags;
}

void EditorExportPlugin::add_tvos_bundle_file(const String &p_path) {
tvos_bundle_files.push_back(p_path);
}

Vector<String> EditorExportPlugin::get_tvos_bundle_files() const {
return tvos_bundle_files;
}

void EditorExportPlugin::add_tvos_cpp_code(const String &p_code) {
tvos_cpp_code += p_code;
}

String EditorExportPlugin::get_tvos_cpp_code() const {
return tvos_cpp_code;
}

void EditorExportPlugin::add_tvos_project_static_lib(const String &p_path) {
tvos_project_static_libs.push_back(p_path);
}

Vector<String> EditorExportPlugin::get_tvos_project_static_libs() const {
return tvos_project_static_libs;
}

void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features) {
GDVIRTUAL_CALL(_export_file, p_path, p_type, p_features);
}
Expand Down Expand Up @@ -670,6 +729,13 @@ void EditorExportPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_ios_bundle_file);
ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code);
ClassDB::bind_method(D_METHOD("add_osx_plugin_file", "path"), &EditorExportPlugin::add_osx_plugin_file);
ClassDB::bind_method(D_METHOD("add_tvos_project_static_lib", "path"), &EditorExportPlugin::add_tvos_project_static_lib);
ClassDB::bind_method(D_METHOD("add_tvos_framework", "path"), &EditorExportPlugin::add_tvos_framework);
ClassDB::bind_method(D_METHOD("add_tvos_embedded_framework", "path"), &EditorExportPlugin::add_tvos_embedded_framework);
ClassDB::bind_method(D_METHOD("add_tvos_plist_content", "plist_content"), &EditorExportPlugin::add_tvos_plist_content);
ClassDB::bind_method(D_METHOD("add_tvos_linker_flags", "flags"), &EditorExportPlugin::add_tvos_linker_flags);
ClassDB::bind_method(D_METHOD("add_tvos_bundle_file", "path"), &EditorExportPlugin::add_tvos_bundle_file);
ClassDB::bind_method(D_METHOD("add_tvos_cpp_code", "code"), &EditorExportPlugin::add_tvos_cpp_code);
ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip);

GDVIRTUAL_BIND(_export_file, "path", "type", "features");
Expand Down
31 changes: 31 additions & 0 deletions editor/editor_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,14 @@ class EditorExportPlugin : public RefCounted {

Vector<String> osx_plugin_files;

Vector<String> tvos_frameworks;
Vector<String> tvos_embedded_frameworks;
Vector<String> tvos_project_static_libs;
String tvos_plist_content;
String tvos_linker_flags;
Vector<String> tvos_bundle_files;
String tvos_cpp_code;

_FORCE_INLINE_ void _clear() {
shared_objects.clear();
extra_files.clear();
Expand All @@ -325,6 +333,13 @@ class EditorExportPlugin : public RefCounted {
ios_linker_flags = "";
ios_cpp_code = "";
osx_plugin_files.clear();

tvos_frameworks.clear();
tvos_embedded_frameworks.clear();
tvos_bundle_files.clear();
tvos_plist_content = "";
tvos_linker_flags = "";
tvos_cpp_code = "";
}

void _export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features);
Expand All @@ -347,6 +362,14 @@ class EditorExportPlugin : public RefCounted {
void add_ios_cpp_code(const String &p_code);
void add_osx_plugin_file(const String &p_path);

void add_tvos_framework(const String &p_path);
void add_tvos_embedded_framework(const String &p_path);
void add_tvos_project_static_lib(const String &p_path);
void add_tvos_plist_content(const String &p_plist_content);
void add_tvos_linker_flags(const String &p_flags);
void add_tvos_bundle_file(const String &p_path);
void add_tvos_cpp_code(const String &p_code);

void skip();

virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features);
Expand All @@ -368,6 +391,14 @@ class EditorExportPlugin : public RefCounted {
String get_ios_cpp_code() const;
const Vector<String> &get_osx_plugin_files() const;

Vector<String> get_tvos_frameworks() const;
Vector<String> get_tvos_embedded_frameworks() const;
Vector<String> get_tvos_project_static_libs() const;
String get_tvos_plist_content() const;
String get_tvos_linker_flags() const;
Vector<String> get_tvos_bundle_files() const;
String get_tvos_cpp_code() const;

EditorExportPlugin();
};

Expand Down
19 changes: 13 additions & 6 deletions editor/plugins/gdextension_export_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,25 +81,32 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p
}
add_shared_object(library_path, tags);

if (p_features.has("iOS") && (library_path.ends_with(".a") || library_path.ends_with(".xcframework"))) {
if ((p_features.has("iOS") || p_features.has("tvOS")) && (library_path.ends_with(".a") || library_path.ends_with(".xcframework"))) {
String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n"
"extern void add_ios_init_callback(void (*cb)());\n"
"extern void add_$PLATFORM_init_callback(void (*cb)());\n"
"\n"
"extern \"C\" void $ENTRY();\n"
"void $ENTRY_init() {\n"
" if (&$ENTRY) register_dynamic_symbol((char *)\"$ENTRY\", (void *)$ENTRY);\n"
"}\n"
"struct $ENTRY_struct {\n"
" $ENTRY_struct() {\n"
" add_ios_init_callback($ENTRY_init);\n"
" add_$PLATFORM_init_callback($ENTRY_init);\n"
" }\n"
"};\n"
"$ENTRY_struct $ENTRY_struct_instance;\n\n";
additional_code = additional_code.replace("$ENTRY", entry_symbol);
add_ios_cpp_code(additional_code);

String linker_flags = "-Wl,-U,_" + entry_symbol;
add_ios_linker_flags(linker_flags);

if (p_features.has("iOS")) {
additional_code = additional_code.replace("$PLATFORM", "ios");
add_ios_cpp_code(additional_code);
add_ios_linker_flags(linker_flags);
} else if (p_features.has("tvOS")) {
additional_code = additional_code.replace("$PLATFORM", "tvos");
add_tvos_cpp_code(additional_code);
add_tvos_linker_flags(linker_flags);
}
}
break;
}
Expand Down
1 change: 1 addition & 0 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph

GLOBAL_DEF("display/window/ios/hide_home_indicator", true);
GLOBAL_DEF("input_devices/pointing/ios/touch_delay", 0.150);
GLOBAL_DEF("input_devices/pointing/tvos/press_end_delay", 0.150);

Engine::get_singleton()->set_frame_delay(frame_delay);

Expand Down
6 changes: 6 additions & 0 deletions methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,12 @@ def detect_darwin_sdk_path(platform, env):
elif platform == "iphonesimulator":
sdk_name = "iphonesimulator"
var_name = "IPHONESDK"
elif platform == "tvos":
sdk_name = "appletvos"
var_name = "TVOSSDK"
elif platform == "tvossimulator":
sdk_name = "appletvsimulator"
var_name = "TVOSSDK"
else:
raise Exception("Invalid platform argument passed to detect_darwin_sdk_path")

Expand Down
Empty file added misc/dist/tvos_xcode/data.pck
Empty file.
Loading