-
-
Notifications
You must be signed in to change notification settings - Fork 27k
[Export] Linux, Windows: Support exporting with debug symbols #114924
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -33,6 +33,7 @@ | |||||||
| #include "core/config/project_settings.h" | ||||||||
| #include "core/io/dir_access.h" | ||||||||
| #include "core/io/file_access.h" | ||||||||
| #include "core/io/zip_io.h" | ||||||||
| #include "core/os/os.h" | ||||||||
| #include "core/os/shared_object.h" | ||||||||
| #include "scene/resources/image_texture.h" // IWYU pragma: keep. Misdetection of `logo`. | ||||||||
|
|
@@ -61,6 +62,7 @@ void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) c | |||||||
| r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, ext_filter), "")); | ||||||||
|
|
||||||||
| r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "debug/export_console_wrapper", PROPERTY_HINT_ENUM, "No,Debug Only,Debug and Release"), 1)); | ||||||||
| r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "debug/export_debug_symbols", PROPERTY_HINT_ENUM, "No,Debug Only,Debug and Release"), 1)); | ||||||||
|
|
||||||||
| r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/embed_pck"), false)); | ||||||||
|
|
||||||||
|
|
@@ -152,6 +154,98 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr | |||||||
| return err; | ||||||||
| } | ||||||||
|
|
||||||||
| Error EditorExportPlatformPC::_unzip_debugsymbols(Ref<DirAccess> &p_da, const String &p_path, const String &p_symbols_path, const String &p_zip_path) { | ||||||||
| PackedByteArray extracted_data; | ||||||||
| { | ||||||||
| Ref<FileAccess> zip_access; | ||||||||
| zlib_filefunc_def io = zipio_create_io(&zip_access); | ||||||||
| unzFile uzf = unzOpen2(p_zip_path.utf8().get_data(), &io); | ||||||||
| if (!uzf) { | ||||||||
| add_message(EXPORT_MESSAGE_WARNING, TTR("Prepare Templates"), vformat(TTR("Could not find debug symbols to export: \"%s\"."), p_zip_path)); | ||||||||
| return ERR_FILE_NOT_FOUND; | ||||||||
| } | ||||||||
|
|
||||||||
| int err = UNZ_OK; | ||||||||
|
|
||||||||
| // Locate and open the file. | ||||||||
| err = godot_unzip_locate_file(uzf, p_symbols_path, true); | ||||||||
| if (err != UNZ_OK) { | ||||||||
| unzClose(uzf); | ||||||||
| add_message(EXPORT_MESSAGE_WARNING, TTR("Prepare Templates"), vformat(TTR("Could not find debug symbols to export: \"%s\" \"%s\"."), p_symbols_path, p_zip_path)); | ||||||||
| return ERR_FILE_NOT_FOUND; | ||||||||
| } | ||||||||
|
|
||||||||
| err = unzOpenCurrentFile(uzf); | ||||||||
| if (err != UNZ_OK) { | ||||||||
| unzClose(uzf); | ||||||||
| add_message(EXPORT_MESSAGE_WARNING, TTR("Prepare Templates"), vformat(TTR("Could not open debug symbols to export: \"%s\" \"%s\"."), p_symbols_path, p_zip_path)); | ||||||||
| return ERR_FILE_CANT_OPEN; | ||||||||
| } | ||||||||
|
|
||||||||
| // Read the file info. | ||||||||
| unz_file_info info; | ||||||||
| err = unzGetCurrentFileInfo(uzf, &info, nullptr, 0, nullptr, 0, nullptr, 0); | ||||||||
| if (err != UNZ_OK) { | ||||||||
| unzCloseCurrentFile(uzf); | ||||||||
| unzClose(uzf); | ||||||||
| add_message(EXPORT_MESSAGE_WARNING, TTR("Prepare Templates"), vformat(TTR("Could not open debug symbols to export: \"%s\" \"%s\"."), p_symbols_path, p_zip_path)); | ||||||||
| return ERR_FILE_CANT_OPEN; | ||||||||
| } | ||||||||
|
|
||||||||
| // Read the file data. | ||||||||
| extracted_data.resize(info.uncompressed_size); | ||||||||
| uint8_t *buffer = extracted_data.ptrw(); | ||||||||
| int to_read = extracted_data.size(); | ||||||||
| while (to_read > 0) { | ||||||||
| int bytes_read_current = unzReadCurrentFile(uzf, buffer, to_read); | ||||||||
| if (bytes_read_current < 0 || (bytes_read_current == UNZ_EOF && to_read != 0)) { | ||||||||
| unzCloseCurrentFile(uzf); | ||||||||
| unzClose(uzf); | ||||||||
| add_message(EXPORT_MESSAGE_WARNING, TTR("Prepare Templates"), vformat(TTR("Could not open debug symbols to export: \"%s\" \"%s\"."), p_symbols_path, p_zip_path)); | ||||||||
| return ERR_FILE_CANT_READ; | ||||||||
| } | ||||||||
| buffer += bytes_read_current; | ||||||||
| to_read -= bytes_read_current; | ||||||||
| } | ||||||||
|
|
||||||||
| // Verify the data and return. | ||||||||
| err = unzCloseCurrentFile(uzf); | ||||||||
| if (err != UNZ_OK) { | ||||||||
| unzClose(uzf); | ||||||||
| add_message(EXPORT_MESSAGE_WARNING, TTR("Prepare Templates"), vformat(TTR("Could not open debug symbols to export: \"%s\" \"%s\"."), p_symbols_path, p_zip_path)); | ||||||||
| return ERR_FILE_CANT_READ; | ||||||||
| } | ||||||||
| unzClose(uzf); | ||||||||
| } | ||||||||
|
|
||||||||
| // Prepare target file. | ||||||||
| Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::WRITE); | ||||||||
| if (f.is_null()) { | ||||||||
| add_message(EXPORT_MESSAGE_WARNING, TTR("Prepare Templates"), vformat(TTR("Failed to copy file \"%s\"."), p_path)); | ||||||||
| return ERR_CANT_CREATE; | ||||||||
| } | ||||||||
| f->store_buffer(extracted_data); | ||||||||
|
|
||||||||
| return OK; | ||||||||
| } | ||||||||
|
|
||||||||
| bool EditorExportPlatformPC::_copy_debugsymbols(Ref<DirAccess> &p_da, const String &p_path, const String &p_symbols_path, Error &r_err) { | ||||||||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be made into a virtual method but as there's no difference currently I've left it a local method, as it got a bit cluttered with the different options, some of these paths should probably be collapsed and cleaned up |
||||||||
| r_err = OK; | ||||||||
|
|
||||||||
| if (FileAccess::exists(p_symbols_path)) { | ||||||||
| r_err = p_da->copy(p_symbols_path, p_path + ".debugsymbols"); | ||||||||
| } else if (FileAccess::exists(p_symbols_path + ".zip")) { | ||||||||
| r_err = _unzip_debugsymbols(p_da, p_path + ".debugsymbols", p_symbols_path.get_file(), p_symbols_path + ".zip"); | ||||||||
| } else { | ||||||||
| return false; | ||||||||
| } | ||||||||
| if (r_err == OK) { | ||||||||
| r_err = fixup_debug_symbol_link(p_path, p_path.get_file() + ".debugsymbols"); | ||||||||
| } | ||||||||
|
|
||||||||
| return r_err == OK; | ||||||||
| } | ||||||||
|
|
||||||||
| Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags) { | ||||||||
| if (!DirAccess::exists(p_path.get_base_dir())) { | ||||||||
| add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("The given export path doesn't exist.")); | ||||||||
|
|
@@ -182,9 +276,13 @@ Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_ | |||||||
| "console.exe", | ||||||||
| nullptr, | ||||||||
| }; | ||||||||
|
|
||||||||
| int con_wrapper_mode = p_preset->get("debug/export_console_wrapper"); | ||||||||
| bool copy_wrapper = (con_wrapper_mode == 1 && p_debug) || (con_wrapper_mode == 2); | ||||||||
|
|
||||||||
| int debug_symbols_mode = p_preset->get("debug/export_debug_symbols"); | ||||||||
| bool copy_debug_symbols = (debug_symbols_mode == 1 && p_debug) || (debug_symbols_mode == 2); | ||||||||
|
|
||||||||
| Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); | ||||||||
| da->make_dir_recursive(p_path.get_base_dir()); | ||||||||
| Error err = da->copy(template_path, p_path, get_chmod_flags()); | ||||||||
|
|
@@ -197,6 +295,16 @@ Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_ | |||||||
| } | ||||||||
| } | ||||||||
| } | ||||||||
| if (err == OK && copy_debug_symbols) { | ||||||||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section along with the wrapper is getting a bit cluttered but I think it'd be something to clean up in a follow-up PR, properly moving the console wrapper code into the windows platform code to make it easier to maintain |
||||||||
| _copy_debugsymbols(da, p_path, template_path + ".debugsymbols", err); | ||||||||
| if (err == OK && copy_wrapper) { | ||||||||
| for (int i = 0; wrapper_extensions[i]; ++i) { | ||||||||
| if (_copy_debugsymbols(da, p_path.get_basename() + ".console.exe", template_path.get_basename() + wrapper_extensions[i] + ".debugsymbols", err)) { | ||||||||
| break; | ||||||||
| } | ||||||||
| } | ||||||||
| } | ||||||||
| } | ||||||||
|
Comment on lines
+298
to
+307
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Windows export templates compiled with MSVC use a This is not needed for official export templates as they use MinGW, but it can be needed for custom export templates.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is that fetched automatically like the
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have this rename check for the godot/platform/windows/crash_handler_windows_signal.cpp Lines 271 to 273 in c12e519
Would this need a different check for that case?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It's an alternative; you can't have both Note that MSVC debug symbols are always separate as
Yes, as this check is only intended to find separate MinGW debug symbols. There is another issue we'll probably need to tackle with MSVC debug symbols: the executable finds the PDB location with a path defined in the @bruvzg Any ideas?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then I think we can leave that as a follow-up including code to integrate that into the system (official builds are made with gcc so will only be relevant for custom builds with msvc)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Official templates are not using MSVC, so I think it's OK to skip it for now. I think path can be set to relative using |
||||||||
| if (err != OK) { | ||||||||
| add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("Failed to copy export template.")); | ||||||||
| return err; | ||||||||
|
|
||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is largely taken from
export_template_manager.cppand can be improved, currently reads the entire file into memory and that's how things are done there too, could change it to read it piecewise to reduce memory overhead if desired