Skip to content

Commit 06acfcc

Browse files
committed
Merge pull request godotengine#102506 from akien-mga/mingw-gcc-lto-one-the-rocks
Workaround mingw-gcc LTO ICE by re-adding some dead code...
2 parents d497631 + e12a424 commit 06acfcc

File tree

2 files changed

+239
-0
lines changed

2 files changed

+239
-0
lines changed

platform/ios/export/export_plugin.cpp

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,167 @@ struct ExportLibsData {
12561256
String dest_dir;
12571257
};
12581258

1259+
bool EditorExportPlatformIOS::_archive_has_arm64(const String &p_path, uint32_t *r_cputype, uint32_t *r_cpusubtype) const {
1260+
bool has_arm64_image = false;
1261+
if (FileAccess::exists(p_path)) {
1262+
if (LipO::is_lipo(p_path)) {
1263+
// LipO.
1264+
Ref<LipO> lipo;
1265+
lipo.instantiate();
1266+
if (lipo->open_file(p_path)) {
1267+
for (int i = 0; i < lipo->get_arch_count(); i++) {
1268+
if (lipo->get_arch_cputype(i) == 0x100000c && lipo->get_arch_cpusubtype(i) == 0) {
1269+
has_arm64_image = true;
1270+
break;
1271+
}
1272+
}
1273+
}
1274+
lipo->close();
1275+
} else {
1276+
// Single architecture archive.
1277+
Ref<FileAccess> sim_f = FileAccess::open(p_path, FileAccess::READ);
1278+
if (sim_f.is_valid()) {
1279+
char magic[9] = {};
1280+
sim_f->get_buffer((uint8_t *)&magic[0], 8);
1281+
if (String(magic) == String("!<arch>\n")) {
1282+
while (!sim_f->eof_reached()) {
1283+
// Read file metadata.
1284+
char name_short[17] = {};
1285+
char size_short[11] = {};
1286+
sim_f->get_buffer((uint8_t *)&name_short[0], 16);
1287+
sim_f->seek(sim_f->get_position() + 12 + 6 + 6 + 8); // Skip modification time, owner ID, group ID, file mode.
1288+
sim_f->get_buffer((uint8_t *)&size_short[0], 10);
1289+
sim_f->seek(sim_f->get_position() + 2); // Skip end marker.
1290+
1291+
int64_t file_size = String(size_short).to_int();
1292+
int64_t next_off = sim_f->get_position() + file_size;
1293+
1294+
String name = String(name_short); // Skip extended name.
1295+
if (name.is_empty() || file_size == 0) {
1296+
break;
1297+
}
1298+
if (name.begins_with("#1/")) {
1299+
int64_t name_len = String(name_short).replace("#1/", "").to_int();
1300+
sim_f->seek(sim_f->get_position() + name_len);
1301+
}
1302+
1303+
// Read file content.
1304+
uint32_t obj_magic = sim_f->get_32();
1305+
1306+
bool swap = (obj_magic == 0xcffaedfe || obj_magic == 0xcefaedfe);
1307+
if (obj_magic == 0xcefaedfe || obj_magic == 0xfeedface || obj_magic == 0xcffaedfe || obj_magic == 0xfeedfacf) {
1308+
uint32_t cputype = sim_f->get_32();
1309+
uint32_t cpusubtype = sim_f->get_32();
1310+
if (swap) {
1311+
cputype = BSWAP32(cputype);
1312+
cpusubtype = BSWAP32(cpusubtype);
1313+
}
1314+
if (r_cputype) {
1315+
*r_cputype = cputype;
1316+
}
1317+
if (r_cpusubtype) {
1318+
*r_cpusubtype = cpusubtype;
1319+
}
1320+
if (cputype == 0x100000c && cpusubtype == 0) {
1321+
has_arm64_image = true;
1322+
}
1323+
break;
1324+
}
1325+
sim_f->seek(next_off);
1326+
}
1327+
}
1328+
sim_f->close();
1329+
}
1330+
}
1331+
}
1332+
return has_arm64_image;
1333+
}
1334+
1335+
int EditorExportPlatformIOS::_archive_convert_to_simulator(const String &p_path) const {
1336+
int commands_patched = 0;
1337+
Ref<FileAccess> sim_f = FileAccess::open(p_path, FileAccess::READ_WRITE);
1338+
if (sim_f.is_valid()) {
1339+
char magic[9] = {};
1340+
sim_f->get_buffer((uint8_t *)&magic[0], 8);
1341+
if (String(magic) == String("!<arch>\n")) {
1342+
while (!sim_f->eof_reached()) {
1343+
// Read file metadata.
1344+
char name_short[17] = {};
1345+
char size_short[11] = {};
1346+
sim_f->get_buffer((uint8_t *)&name_short[0], 16);
1347+
sim_f->seek(sim_f->get_position() + 12 + 6 + 6 + 8); // Skip modification time, owner ID, group ID, file mode.
1348+
sim_f->get_buffer((uint8_t *)&size_short[0], 10);
1349+
sim_f->seek(sim_f->get_position() + 2); // Skip end marker.
1350+
1351+
int64_t file_size = String(size_short).to_int();
1352+
int64_t next_off = sim_f->get_position() + file_size;
1353+
1354+
String name = String(name_short); // Skip extended name.
1355+
if (name.is_empty() || file_size == 0) {
1356+
break;
1357+
}
1358+
if (name.begins_with("#1/")) {
1359+
int64_t name_len = String(name_short).replace("#1/", "").to_int();
1360+
sim_f->seek(sim_f->get_position() + name_len);
1361+
}
1362+
1363+
// Read file content.
1364+
uint32_t obj_magic = sim_f->get_32();
1365+
1366+
bool swap = (obj_magic == 0xcffaedfe || obj_magic == 0xcefaedfe);
1367+
if (obj_magic == 0xcefaedfe || obj_magic == 0xfeedface || obj_magic == 0xcffaedfe || obj_magic == 0xfeedfacf) {
1368+
uint32_t cputype = sim_f->get_32();
1369+
uint32_t cpusubtype = sim_f->get_32();
1370+
uint32_t filetype = sim_f->get_32();
1371+
uint32_t ncmds = sim_f->get_32();
1372+
sim_f->get_32(); // Commands total size.
1373+
sim_f->get_32(); // Commands flags.
1374+
if (obj_magic == 0xcffaedfe || obj_magic == 0xfeedfacf) {
1375+
sim_f->get_32(); // Reserved, 64-bit only.
1376+
}
1377+
if (swap) {
1378+
ncmds = BSWAP32(ncmds);
1379+
cputype = BSWAP32(cputype);
1380+
cpusubtype = BSWAP32(cpusubtype);
1381+
filetype = BSWAP32(filetype);
1382+
}
1383+
if (cputype == 0x100000C && cpusubtype == 0 && filetype == 1) {
1384+
// ARM64, object file.
1385+
for (uint32_t i = 0; i < ncmds; i++) {
1386+
int64_t cmdofs = sim_f->get_position();
1387+
uint32_t cmdid = sim_f->get_32();
1388+
uint32_t cmdsize = sim_f->get_32();
1389+
if (swap) {
1390+
cmdid = BSWAP32(cmdid);
1391+
cmdsize = BSWAP32(cmdsize);
1392+
}
1393+
if (cmdid == MachO::LoadCommandID::LC_BUILD_VERSION) {
1394+
int64_t platform = sim_f->get_32();
1395+
if (swap) {
1396+
platform = BSWAP32(platform);
1397+
}
1398+
if (platform == MachO::PlatformID::PLATFORM_IOS) {
1399+
sim_f->seek(cmdofs + 4 + 4);
1400+
uint32_t new_id = MachO::PlatformID::PLATFORM_IOSSIMULATOR;
1401+
if (swap) {
1402+
new_id = BSWAP32(new_id);
1403+
}
1404+
sim_f->store_32(new_id);
1405+
commands_patched++;
1406+
}
1407+
}
1408+
sim_f->seek(cmdofs + cmdsize);
1409+
}
1410+
}
1411+
}
1412+
sim_f->seek(next_off);
1413+
}
1414+
}
1415+
sim_f->close();
1416+
}
1417+
return commands_patched;
1418+
}
1419+
12591420
void EditorExportPlatformIOS::_check_xcframework_content(const String &p_path, int &r_total_libs, int &r_static_libs, int &r_dylibs, int &r_frameworks) const {
12601421
Ref<PList> plist;
12611422
plist.instantiate();
@@ -2260,6 +2421,82 @@ Error EditorExportPlatformIOS::_export_project_helper(const Ref<EditorExportPres
22602421
return ERR_FILE_NOT_FOUND;
22612422
}
22622423

2424+
// HACK: We don't want to run the simulator library generation code anymore after GH-102179, but removing it
2425+
// triggers an internal compiler error with latest mingw-gcc... For now we bring it back as a workaround
2426+
// with a condition that should never be true (that project setting doesn't exist).
2427+
2428+
// Check and generate missing ARM64 simulator library.
2429+
if (ProjectSettings::get_singleton()->has_setting("__dummy_setting_blame_akien_if_you_define_this_somehow")) {
2430+
String sim_lib_path = dest_dir + String(binary_name + ".xcframework").path_join("ios-arm64_x86_64-simulator").path_join("libgodot.a");
2431+
String dev_lib_path = dest_dir + String(binary_name + ".xcframework").path_join("ios-arm64").path_join("libgodot.a");
2432+
String tmp_lib_path = EditorPaths::get_singleton()->get_temp_dir().path_join(binary_name + "_lipo_");
2433+
uint32_t cputype = 0;
2434+
uint32_t cpusubtype = 0;
2435+
if (!_archive_has_arm64(sim_lib_path, &cputype, &cpusubtype) && _archive_has_arm64(dev_lib_path) && FileAccess::exists(dev_lib_path)) {
2436+
add_message(EXPORT_MESSAGE_INFO, TTR("Export"), TTR("ARM64 simulator library, generating from device library."));
2437+
2438+
Vector<String> tmp_lib_files;
2439+
Vector<Vector2i> tmp_lib_cputypes;
2440+
// Extract/copy simulator lib.
2441+
if (FileAccess::exists(sim_lib_path)) {
2442+
if (LipO::is_lipo(sim_lib_path)) {
2443+
Ref<LipO> lipo;
2444+
lipo.instantiate();
2445+
if (lipo->open_file(sim_lib_path)) {
2446+
for (int i = 0; i < lipo->get_arch_count(); i++) {
2447+
const String &f_name = tmp_lib_path + itos(tmp_lib_files.size());
2448+
lipo->extract_arch(i, f_name);
2449+
tmp_lib_files.push_back(f_name);
2450+
tmp_lib_cputypes.push_back(Vector2i(lipo->get_arch_cputype(i), lipo->get_arch_cpusubtype(i)));
2451+
}
2452+
}
2453+
} else {
2454+
const String &f_name = tmp_lib_path + itos(tmp_lib_files.size());
2455+
tmp_app_path->copy(sim_lib_path, f_name);
2456+
tmp_lib_files.push_back(f_name);
2457+
tmp_lib_cputypes.push_back(Vector2i(cputype, cpusubtype));
2458+
}
2459+
}
2460+
// Copy device lib.
2461+
if (LipO::is_lipo(dev_lib_path)) {
2462+
Ref<LipO> lipo;
2463+
lipo.instantiate();
2464+
if (lipo->open_file(dev_lib_path)) {
2465+
for (int i = 0; i < lipo->get_arch_count(); i++) {
2466+
if (lipo->get_arch_cputype(i) == 0x100000c && lipo->get_arch_cpusubtype(i) == 0) {
2467+
const String &f_name = tmp_lib_path + itos(tmp_lib_files.size());
2468+
lipo->extract_arch(i, f_name);
2469+
tmp_lib_files.push_back(f_name);
2470+
tmp_lib_cputypes.push_back(Vector2i(0x100000c, 0)); // ARM64.
2471+
break;
2472+
}
2473+
}
2474+
}
2475+
} else {
2476+
const String &f_name = tmp_lib_path + itos(tmp_lib_files.size());
2477+
tmp_app_path->copy(dev_lib_path, f_name);
2478+
tmp_lib_files.push_back(f_name);
2479+
tmp_lib_cputypes.push_back(Vector2i(0x100000c, 0)); // ARM64.
2480+
}
2481+
2482+
// Patch device lib.
2483+
int patch_count = _archive_convert_to_simulator(tmp_lib_path + itos(tmp_lib_files.size() - 1));
2484+
if (patch_count == 0) {
2485+
add_message(EXPORT_MESSAGE_WARNING, TTR("Export"), TTR("Unable to generate ARM64 simulator library."));
2486+
} else {
2487+
// Repack.
2488+
Ref<LipO> lipo;
2489+
lipo.instantiate();
2490+
lipo->create_file(sim_lib_path, tmp_lib_files, tmp_lib_cputypes);
2491+
}
2492+
2493+
// Cleanup.
2494+
for (const String &E : tmp_lib_files) {
2495+
tmp_app_path->remove(E);
2496+
}
2497+
}
2498+
}
2499+
22632500
// Generate translations files.
22642501

22652502
Dictionary appnames = GLOBAL_GET("application/config/name_localized");

platform/ios/export/export_plugin.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
136136
Vector<ExportArchitecture> _get_supported_architectures() const;
137137
Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset) const;
138138

139+
bool _archive_has_arm64(const String &p_path, uint32_t *r_cputype = nullptr, uint32_t *r_cpusubtype = nullptr) const;
140+
int _archive_convert_to_simulator(const String &p_path) const;
139141
void _check_xcframework_content(const String &p_path, int &r_total_libs, int &r_static_libs, int &r_dylibs, int &r_frameworks) const;
140142
Error _convert_to_framework(const String &p_source, const String &p_destination, const String &p_id) const;
141143

0 commit comments

Comments
 (0)