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

[macOS/iOS export] Add option to set custom Info.plist data. #87029

Merged
merged 1 commit into from
Jan 11, 2024
Merged
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
54 changes: 37 additions & 17 deletions platform/macos/export/plist.cpp → core/io/plist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,9 @@ PList::PList() {
}

PList::PList(const String &p_string) {
load_string(p_string);
String err_str;
bool ok = load_string(p_string, err_str);
ERR_FAIL_COND_MSG(!ok, "PList: " + err_str);
}

uint64_t PList::read_bplist_var_size_int(Ref<FileAccess> p_file, uint8_t p_size) {
Expand Down Expand Up @@ -642,11 +644,15 @@ bool PList::load_file(const String &p_filename) {

String ret;
ret.parse_utf8((const char *)array.ptr(), array.size());
return load_string(ret);
String err_str;
bool ok = load_string(ret, err_str);
ERR_FAIL_COND_V_MSG(!ok, false, "PList: " + err_str);

return true;
}
}

bool PList::load_string(const String &p_string) {
bool PList::load_string(const String &p_string, String &r_err_out) {
root = Ref<PListNode>();

int pos = 0;
Expand All @@ -657,14 +663,16 @@ bool PList::load_string(const String &p_string) {
while (pos >= 0) {
int open_token_s = p_string.find("<", pos);
if (open_token_s == -1) {
ERR_FAIL_V_MSG(false, "PList: Unexpected end of data. No tags found.");
r_err_out = "Unexpected end of data. No tags found.";
return false;
}
int open_token_e = p_string.find(">", open_token_s);
pos = open_token_e;

String token = p_string.substr(open_token_s + 1, open_token_e - open_token_s - 1);
if (token.is_empty()) {
ERR_FAIL_V_MSG(false, "PList: Invalid token name.");
r_err_out = "Invalid token name.";
return false;
}
String value;
if (token[0] == '?' || token[0] == '!') { // Skip <?xml ... ?> and <!DOCTYPE ... >
Expand All @@ -684,7 +692,8 @@ bool PList::load_string(const String &p_string) {
}

if (!in_plist) {
ERR_FAIL_V_MSG(false, "PList: Node outside of <plist> tag.");
r_err_out = "Node outside of <plist> tag.";
return false;
}

if (token == "dict") {
Expand All @@ -693,13 +702,15 @@ bool PList::load_string(const String &p_string) {
Ref<PListNode> dict = PListNode::new_dict();
dict->data_type = PList::PLNodeType::PL_NODE_TYPE_DICT;
if (!stack.back()->get()->push_subnode(dict, key)) {
ERR_FAIL_V_MSG(false, "PList: Can't push subnode, invalid parent type.");
r_err_out = "Can't push subnode, invalid parent type.";
return false;
}
stack.push_back(dict);
} else {
// Add root node.
if (!root.is_null()) {
ERR_FAIL_V_MSG(false, "PList: Root node already set.");
r_err_out = "Root node already set.";
return false;
}
Ref<PListNode> dict = PListNode::new_dict();
stack.push_back(dict);
Expand All @@ -711,7 +722,8 @@ bool PList::load_string(const String &p_string) {
if (token == "/dict") {
// Exit current dict.
if (stack.is_empty() || stack.back()->get()->data_type != PList::PLNodeType::PL_NODE_TYPE_DICT) {
ERR_FAIL_V_MSG(false, "PList: Mismatched </dict> tag.");
r_err_out = "Mismatched </dict> tag.";
return false;
}
stack.pop_back();
continue;
Expand All @@ -722,13 +734,15 @@ bool PList::load_string(const String &p_string) {
// Add subnode end enter it.
Ref<PListNode> arr = PListNode::new_array();
if (!stack.back()->get()->push_subnode(arr, key)) {
ERR_FAIL_V_MSG(false, "PList: Can't push subnode, invalid parent type.");
r_err_out = "Can't push subnode, invalid parent type.";
return false;
}
stack.push_back(arr);
} else {
// Add root node.
if (!root.is_null()) {
ERR_FAIL_V_MSG(false, "PList: Root node already set.");
r_err_out = "Root node already set.";
return false;
}
Ref<PListNode> arr = PListNode::new_array();
stack.push_back(arr);
Expand All @@ -740,7 +754,8 @@ bool PList::load_string(const String &p_string) {
if (token == "/array") {
// Exit current array.
if (stack.is_empty() || stack.back()->get()->data_type != PList::PLNodeType::PL_NODE_TYPE_ARRAY) {
ERR_FAIL_V_MSG(false, "PList: Mismatched </array> tag.");
r_err_out = "Mismatched </array> tag.";
return false;
}
stack.pop_back();
continue;
Expand All @@ -751,13 +766,15 @@ bool PList::load_string(const String &p_string) {
} else {
int end_token_s = p_string.find("</", pos);
if (end_token_s == -1) {
ERR_FAIL_V_MSG(false, vformat("PList: Mismatched <%s> tag.", token));
r_err_out = vformat("Mismatched <%s> tag.", token);
return false;
}
int end_token_e = p_string.find(">", end_token_s);
pos = end_token_e;
String end_token = p_string.substr(end_token_s + 2, end_token_e - end_token_s - 2);
if (end_token != token) {
ERR_FAIL_V_MSG(false, vformat("PList: Mismatched <%s> and <%s> token pair.", token, end_token));
r_err_out = vformat("Mismatched <%s> and <%s> token pair.", token, end_token);
return false;
}
value = p_string.substr(open_token_e + 1, end_token_s - open_token_e - 1);
}
Expand All @@ -780,15 +797,18 @@ bool PList::load_string(const String &p_string) {
} else if (token == "date") {
var = PListNode::new_date(value);
} else {
ERR_FAIL_V_MSG(false, "PList: Invalid value type.");
r_err_out = vformat("Invalid value type: %s.", token);
return false;
}
if (stack.is_empty() || !stack.back()->get()->push_subnode(var, key)) {
ERR_FAIL_V_MSG(false, "PList: Can't push subnode, invalid parent type.");
r_err_out = "Can't push subnode, invalid parent type.";
return false;
}
}
}
if (!stack.is_empty() || !done_plist) {
ERR_FAIL_V_MSG(false, "PList: Unexpected end of data. Root node is not closed.");
r_err_out = "Unexpected end of data. Root node is not closed.";
return false;
}
return true;
}
Expand Down
8 changes: 4 additions & 4 deletions platform/macos/export/plist.h → core/io/plist.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef MACOS_PLIST_H
#define MACOS_PLIST_H
#ifndef PLIST_H
#define PLIST_H

// Property list file format (application/x-plist) parser, property list ASN-1 serialization.

Expand Down Expand Up @@ -75,7 +75,7 @@ class PList : public RefCounted {
PList(const String &p_string);

bool load_file(const String &p_filename);
bool load_string(const String &p_string);
bool load_string(const String &p_string, String &r_err_out);

PackedByteArray save_asn1() const;
String save_text() const;
Expand Down Expand Up @@ -125,4 +125,4 @@ class PListNode : public RefCounted {
~PListNode() {}
};

#endif // MACOS_PLIST_H
#endif // PLIST_H
1 change: 1 addition & 0 deletions misc/dist/macos_template.app/Contents/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ $usage_descriptions
</dict>
<key>NSHighResolutionCapable</key>
$highres
$additional_plist_content
</dict>
</plist>
7 changes: 7 additions & 0 deletions platform/ios/doc_classes/EditorExportPlatformIOS.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
<link title="iOS plugins documentation index">$DOCS_URL/tutorials/platform/ios/index.html</link>
</tutorials>
<members>
<member name="application/additional_plist_content" type="String" setter="" getter="">
Additional data added to the root [code]&lt;dict&gt;[/code] section of the [url=https://developer.apple.com/documentation/bundleresources/information_property_list]Info.plist[/url] file. The value should be an XML section with pairs of key-value elements, e.g.:
[codeblock]
&lt;key&gt;key_name&lt;/key&gt;
&lt;string&gt;value&lt;/string&gt;
[/codeblock]
</member>
<member name="application/app_store_team_id" type="String" setter="" getter="">
Apple Team ID, unique 10-character string. To locate your Team ID check "Membership details" section in your Apple developer account dashboard, or "Organizational Unit" of your code signing certificate. See [url=https://developer.apple.com/help/account/manage-your-team/locate-your-team-id]Locate your Team ID[/url].
</member>
Expand Down
25 changes: 25 additions & 0 deletions platform/ios/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "run_icon_svg.gen.h"

#include "core/io/json.h"
#include "core/io/plist.h"
#include "core/string/translation.h"
#include "editor/editor_node.h"
#include "editor/editor_paths.h"
Expand Down Expand Up @@ -154,6 +155,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options)

r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/min_ios_version"), "12.0"));

r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/additional_plist_content", PROPERTY_HINT_MULTILINE_TEXT), ""));

r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/icon_interpolation", PROPERTY_HINT_ENUM, "Nearest neighbor,Bilinear,Cubic,Trilinear,Lanczos"), 4));

r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "application/export_project_only"), false));
Expand Down Expand Up @@ -1498,6 +1501,8 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
false
};

config_data.plist_content += p_preset->get("application/additional_plist_content").operator String() + "\n";

Vector<IOSExportAsset> assets;

Ref<DirAccess> tmp_app_path = DirAccess::create_for_path(dest_dir);
Expand Down Expand Up @@ -1867,6 +1872,26 @@ bool EditorExportPlatformIOS::has_valid_export_configuration(const Ref<EditorExp
valid = dvalid || rvalid;
r_missing_templates = !valid;

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"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
"<plist version=\"1.0\">"
"<dict>\n"
"%s\n"
"</dict>\n"
"</plist>\n",
additional_plist_content);

String plist_err;
Ref<PList> plist_parser;
plist_parser.instantiate();
if (!plist_parser->load_string(plist, plist_err)) {
err += TTR("Invalid additional PList content: ") + plist_err + "\n";
valid = false;
}
}

if (!err.is_empty()) {
r_error = err;
}
Expand Down
7 changes: 7 additions & 0 deletions platform/macos/doc_classes/EditorExportPlatformMacOS.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@
<link title="Running Godot apps on macOS">$DOCS_URL/tutorials//export/running_on_macos.html</link>
</tutorials>
<members>
<member name="application/additional_plist_content" type="String" setter="" getter="">
Additional data added to the root [code]&lt;dict&gt;[/code] section of the [url=https://developer.apple.com/documentation/bundleresources/information_property_list]Info.plist[/url] file. The value should be an XML section with pairs of key-value elements, e.g.:
[codeblock]
&lt;key&gt;key_name&lt;/key&gt;
&lt;string&gt;value&lt;/string&gt;
[/codeblock]
</member>
<member name="application/app_category" type="String" setter="" getter="">
Application category for the App Store.
</member>
Expand Down
2 changes: 1 addition & 1 deletion platform/macos/export/codesign.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@

#include "lipo.h"
#include "macho.h"
#include "plist.h"

#include "core/io/plist.h"
#include "core/os/os.h"
#include "editor/editor_paths.h"
#include "editor/editor_settings.h"
Expand Down
3 changes: 1 addition & 2 deletions platform/macos/export/codesign.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,10 @@
// - Requirements code generator is not implemented (only hard-coded requirements for the ad-hoc signing is supported).
// - RFC5652/CMS blob generation is not implemented, supports ad-hoc signing only.

#include "plist.h"

#include "core/crypto/crypto_core.h"
#include "core/io/dir_access.h"
#include "core/io/file_access.h"
#include "core/io/plist.h"
#include "core/object/ref_counted.h"

#include "modules/modules_enabled.gen.h" // For regex.
Expand Down
25 changes: 25 additions & 0 deletions platform/macos/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "run_icon_svg.gen.h"

#include "core/io/image_loader.h"
#include "core/io/plist.h"
#include "core/string/translation.h"
#include "drivers/png/png_driver_common.h"
#include "editor/editor_node.h"
Expand Down Expand Up @@ -388,6 +389,8 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/export_angle", PROPERTY_HINT_ENUM, "Auto,Yes,No"), 0, true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "display/high_res"), true));

r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/additional_plist_content", PROPERTY_HINT_MULTILINE_TEXT), ""));

r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/platform_build"), "14C18"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/sdk_version"), "13.1"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "xcode/sdk_build"), "22C55"));
Expand Down Expand Up @@ -672,6 +675,8 @@ void EditorExportPlatformMacOS::_fix_plist(const Ref<EditorExportPreset> &p_pres
strnew += lines[i].replace("$min_version", p_preset->get("application/min_macos_version")) + "\n";
} else if (lines[i].find("$highres") != -1) {
strnew += lines[i].replace("$highres", p_preset->get("display/high_res") ? "\t<true/>" : "\t<false/>") + "\n";
} else if (lines[i].find("$additional_plist_content") != -1) {
strnew += lines[i].replace("$additional_plist_content", p_preset->get("application/additional_plist_content")) + "\n";
} else if (lines[i].find("$platfbuild") != -1) {
strnew += lines[i].replace("$platfbuild", p_preset->get("xcode/platform_build")) + "\n";
} else if (lines[i].find("$sdkver") != -1) {
Expand Down Expand Up @@ -2095,6 +2100,26 @@ bool EditorExportPlatformMacOS::has_valid_project_configuration(const Ref<Editor
};
}

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"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
"<plist version=\"1.0\">"
"<dict>\n"
"%s\n"
"</dict>\n"
"</plist>\n",
additional_plist_content);

String plist_err;
Ref<PList> plist_parser;
plist_parser.instantiate();
if (!plist_parser->load_string(plist, plist_err)) {
err += TTR("Invalid additional PList content: ") + plist_err + "\n";
valid = false;
}
}

List<ExportOption> options;
get_export_options(&options);
for (const EditorExportPlatform::ExportOption &E : options) {
Expand Down
Loading