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

SCons: Refactor LTO options with lto=<none|thin|full> #63288

Merged
merged 1 commit into from Sep 8, 2022

Conversation

akien-mga
Copy link
Member

@akien-mga akien-mga commented Jul 21, 2022

Adds support for LTO on macOS and Android. We don't have much experience
with LTO on these platforms so for now we keep it disabled by default
even when production=yes is set.

Similarly for iOS where we ship object files for the user to link in
Xcode so LTO makes builds extremely slow to link.

production=yes defaults to full LTO.
ThinLTO is much faster for LLVM-based compilers but seems to produce
bigger binaries (at least for the Web platform).

@akien-mga akien-mga added enhancement topic:buildsystem cherrypick:3.x Considered for cherry-picking into a future 3.x release labels Jul 21, 2022
@akien-mga akien-mga added this to the 4.0 milestone Jul 21, 2022
@akien-mga akien-mga requested review from a team as code owners July 21, 2022 13:20
platform/ios/detect.py Outdated Show resolved Hide resolved
@akien-mga akien-mga force-pushed the scons-refactor-lto branch 2 times, most recently from bb7bfed to 6a1a70b Compare July 21, 2022 13:41
Comment on lines +41 to +44
# Disable by default even if production is set, as it makes linking in Xcode
# on exports very slow and that's not what most users expect.
("lto", "none"),
Copy link
Member Author

@akien-mga akien-mga Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea here is to still allow specifying lto=<thin|full> if wanted, but make sure that production=yes will not enable LTO unless requested explicitly.

Seems to work on Linux if I add the same to get_flags, but didn't test this for iOS specifically.

Comment on lines +161 to +179
# LTO
if env["lto"] != "none":
if env["lto"] == "thin":
env.Append(CCFLAGS=["-flto=thin"])
env.Append(LINKFLAGS=["-flto=thin"])
else:
env.Append(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto"])
Copy link
Member Author

@akien-mga akien-mga Jul 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know why we never added LTO support to macOS. Does it work? Should we start using it in production builds too?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works, but potential benefits need to be tested, I have not built Godot with LTO for a long time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested it with osxcross on the official buildsystem with my 3.x backport, it seems to fail linking with lto=full at least:

/root/osxcross/target/bin/x86_64-apple-darwin21.4-c++ -o bin/godot.osx.opt.tools.x86_64 -arch x86_64 -mmacosx-version-min=10.12 -flto -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 platform/osx/crash_handler_osx.osx.opt.tools.x86_64.o platform/osx/os_osx.osx.opt.tools.x86_64.o platform/osx/godot_main_osx.osx.opt.tools.x86_64.o platform/osx/dir_access_osx.osx.opt.tools.x86_64.o platform/osx/joypad_osx.osx.opt.tools.x86_64.o platform/osx/power_osx.osx.opt.tools.x86_64.o main/libmain.osx.opt.tools.x86_64.a main/tests/libtests.osx.opt.tools.x86_64.a modules/libmodules.osx.opt.tools.x86_64.a platform/libplatform.osx.opt.tools.x86_64.a drivers/libdrivers.osx.opt.tools.x86_64.a editor/libeditor.osx.opt.tools.x86_64.a scene/libscene.osx.opt.tools.x86_64.a servers/libservers.osx.opt.tools.x86_64.a core/libcore.osx.opt.tools.x86_64.a modules/freetype/libfreetype_builtin.osx.opt.tools.x86_64.a -lpthread
undef: __ZN13DirAccessUnix14list_dir_beginEv
undef: __ZNK13DirAccessUnix14current_is_dirEv
undef: __ZN13DirAccessUnix17get_current_driveEv
undef: __ZN13DirAccessUnix15get_current_dirEv
undef: __ZN9DirAccess29get_current_dir_without_driveEv
undef: __ZN13DirAccessUnix8make_dirE6String
undef: __ZN13DirAccessUnix10change_dirE6String
undef: __ZN9DirAccess18make_dir_recursiveE6String
undef: __ZN13DirAccessUnix11file_existsE6String
undef: __ZNK12AtlasTexture9get_atlasEv
undef: __ZTI12AtlasTexture
undef: __ZTI7Texture
undef: __ZN5Image4lockEv
undef: __ZNK5Image9get_pixelEii
undef: __ZN13DirAccessUnixD2Ev
undef: __ZN2OS11dialog_showE6StringS0_6VectorIS0_EP6ObjectS0_
undef: __ZN6Engine13get_singletonEv
undef: __ZN10MemoryPool11allocs_usedE
undef: __ZN6RefPtrD1Ev
undef: __ZN7OS_Unix15initialize_coreEv
undef: __ZN13DirAccessUnixC2Ev
undef: __ZNK6String12get_base_dirEv
undef: __ZNK6String9plus_fileERKS_
undef: __Z16_err_print_errorPKcS0_iS0_16ErrorHandlerType
undef: __ZNK6StringplERKS_
undef: __ZTI10InputEvent
undef: __ZN13InputEventKey8set_echoEb
undef: __Z10print_line6String
undef: __ZNK2OS25is_no_window_mode_enabledEv
undef: __ZN7VariantaSERKS_
undef: __ZN2OS21set_update_vital_onlyEb
undef: __ZNK6StringeqEPKc
undef: __ZN2OS13set_use_vsyncEb
undef: __ZN12InputDefault10joy_buttonEiib
undef: __ZN2OSD2Ev
undef: __ZN2OS39set_low_processor_usage_mode_sleep_usecEi
undef: __ZNK7VariantcvbEv
undef: __ZN15RasterizerGLES29is_viableEv
undef: __ZN5ArrayC1Ev
undef: __Z16_err_print_errorPKcS0_iS0_S0_16ErrorHandlerType
undef: __ZN15RasterizerGLES315register_configEv
undef: __ZN7OS_Unix33get_dynamic_library_symbol_handleEPv6StringRS0_b
undef: __ZN15RasterizerGLES39is_viableEv
undef: __ZN15RasterizerGLES212make_currentEv
undef: __ZN18MIDIDriverCoreMidi5closeEv
undef: __ZNK6String8get_fileEv
undef: __ZN21InputEventMouseButtonC1Ev
undef: __ZNK2OS19get_executable_pathEv
undef: __ZNK7OS_Unix15has_environmentERK6String
undef: __ZN6StringpLERKS_
undef: __ZN20InputEventPanGestureC1Ev
undef: __ZN18VisualServerWrapMTC1EP12VisualServerb
undef: __ZN15InputEventMouse15set_button_maskEi
undef: __ZN21InputEventMouseMotion8set_tiltERK7Vector2
undef: __ZNK7Variantcv6StringEv
undef: __ZNK13DirAccessUnix19get_filesystem_typeEv
undef: __ZNK6StringeqERKS_
undef: __ZnwmPFPvmE
undef: __ZN21InputEventMouseMotion12set_relativeERK7Vector2
undef: __ZNK7OS_Unix13get_unix_timeEv
undef: __ZNK5Color9to_argb32Ev
undef: __ZNK7VarianteqERKS_
undef: __ZNK2OS22get_screen_orientationEv
undef: __ZNK7OS_Unix18get_time_zone_infoEv
undef: __ZN6Object12notificationEib
undef: __ZNK6String7replaceEPKcS1_
undef: __ZN2OS21show_virtual_keyboardERK6StringRK5Rect2biii
undef: __ZN13InputEventKey11set_pressedEb
undef: __ZN21InputEventMouseButton10set_factorEf
undef: __ZN7VariantC1ERK6String
undef: __ZN4Main12force_redrawEv
undef: __Z11print_error6String
undef: __ZN6StringaSEPKc
undef: __ZTI9Reference
undef: __ZNK10CharString8get_dataEv
undef: __ZplPKcRK6String
undef: __ZNK2OS23has_touchscreen_ui_hintEv
undef: __ZN6Memory14realloc_staticEPvmb
undef: __Z17_err_flush_stdoutv
undef: __ZN6Memory11free_staticEPvb
undef: __ZN2OS11_set_loggerEP15CompositeLogger
undef: __ZN7OS_Unix16get_stdin_stringEb
undef: __ZN18MIDIDriverCoreMidiD1Ev
undef: __ZN21InputEventMouseMotion9set_speedERK7Vector2
undef: __ZNK6String4utf8Ev
undef: __ZN7VariantC1Ei
undef: __ZN23InputEventWithModifiers9set_shiftEb
undef: __ZN9StdLogger4logvEPKcP13__va_list_tagb
undef: __ZN21InputEventMouseMotion12set_pressureEf
undef: __ZN6Memory12alloc_staticEmb
undef: __ZNK2OS17get_iso_date_timeEb
undef: __ZN6String5eraseEii
undef: __ZNK6String10capitalizeEv
undef: __ZN20InputEventPanGesture9set_deltaERK7Vector2
undef: __ZNK2OS13get_exit_codeEv
undef: __ZN15RasterizerGLES312make_currentEv
undef: __ZNK6String6substrEii
undef: __ZN7VariantC1Ex
undef: __ZN17InputEventGesture12set_positionERK7Vector2
undef: __ZN4Main5startEv
undef: __ZN13DirAccessUnix14get_space_leftEv
undef: __ZN13InputEventKey12set_scancodeEj
undef: __ZnwmPKc
undef: __ZN7VariantC1EPKc
undef: __Z16_err_print_errorPKcS0_iS0_RK6String16ErrorHandlerType
undef: __ZN18AudioDriverManager10initializeEi
undef: __ZN24InputEventMagnifyGestureC1Ev
undef: __ZN20AudioDriverCoreAudioD1Ev
undef: __ZNK7OS_Unix21get_system_time_msecsEv
undef: __ZN15InputEventMouse12set_positionERK7Vector2
undef: __ZTI5Image
undef: __ZN9DirAccess11create_funcE
undef: __ZN2OS13get_singletonEv
undef: __ZN7Variant5clearEv
undef: __ZNK2OS30is_in_low_processor_usage_modeEv
undef: __ZN12InputDefaultC1Ev
undef: __ZTI6Object
undef: __ZNK2OS16get_resource_dirEv
undef: __ZNK2OS21get_clipboard_primaryEv
undef: _VERSION_HASH
undef: __ZN13DirAccessUnix9is_hiddenERK6String
undef: __ZN21InputEventMouseMotionC1Ev
undef: __ZN13DirAccessUnix10dir_existsE6String
undef: __ZN15ProjectSettings13get_singletonEv
undef: __ZN10StringNameD1Ev
undef: __ZN4Main5setupEPKciPPcb
undef: __ZN23InputEventWithModifiers7set_altEb
undef: __ZN9Reference11unreferenceEv
undef: __Z22_err_print_index_errorPKcS0_ixxS0_S0_S0_b
undef: __ZN7OS_Unix4killERKx
undef: __ZN13InputEventKey21set_physical_scancodeEj
undef: __ZN7VariantC1ERK6RefPtr
undef: __ZTI9StdLogger
undef: __ZN13DirAccessUnix8get_nextEv
undef: __ZN13DirAccessUnix20drives_are_shortcutsEv
undef: __ZN15RasterizerGLES215register_configEv
undef: __ZN9Reference8init_refEv
undef: __ZNK2OS23native_video_is_playingEv
undef: __ZNK2OS23get_embedded_pck_offsetEv
undef: __ZN23InputEventWithModifiers11set_metakeyEb
undef: __ZN7VariantC1ERKS_
undef: __ZN21InputEventMouseButton15set_doubleclickEb
undef: __ZN23InputEventWithModifiers11set_controlEb
undef: __ZN21InputEventMouseButton11set_pressedEb
undef: __ZN4Main9iterationEv
undef: __ZN9Reference9referenceEv
undef: __ZNK6StringneEPKc
undef: __ZN2OS22print_resources_in_useEb
undef: __ZNK2OS14get_model_nameEv
undef: __ZN2OS13center_windowEv
undef: __ZN7OS_Unix7set_cwdERK6String
undef: __ZN6StringC1EPKc
undef: __ZN13InputEventKeyC1Ev
undef: __Z17predelete_handlerP6Object
undef: __ZN7OS_Unix21unix_initialize_audioEi
undef: __ZN6String10parse_utf8EPKci
undef: __ZN2OS19is_custom_exit_codeEv
undef: __ZN21InputEventMouseMotion16set_pen_invertedEb
undef: __ZN12InputDefault18set_mouse_positionERK7Vector2
undef: __ZN7OS_Unix7executeERK6StringRK4ListIS0_16DefaultAllocatorEbPxPS0_PibP9MutexImplINSt3__115recursive_mutexEEb
undef: __ZN21InputEventMouseButton16set_button_indexEi
undef: __ZN10StringNameC1EPKc
undef: __ZN5Image7convertENS_6FormatE
undef: __ZN4Main12is_iteratingEv
undef: __ZN2OS15add_frame_delayEb
undef: __ZNK2OS39get_low_processor_usage_mode_sleep_usecEv
undef: __ZN4Main7cleanupEb
undef: __Z16_err_print_errorPKcS0_iRK6String16ErrorHandlerType
undef: __ZN7OS_Unix20initialize_debuggingEv
undef: __ZN6String4utf8EPKci
undef: __ZNK7OS_Unix15get_environmentERK6String
undef: __ZN10FileAccess4openERK6StringiP5Error
undef: __ZTI13DirAccessUnix
undef: __ZN15InputEventMouse19set_global_positionERK7Vector2
undef: __ZNK5Image9get_widthEv
undef: __ZNK7Vector23dotERKS_
undef: __ZN7VariantC1ERK7Vector2
undef: __ZN20AudioDriverCoreAudioC1Ev
undef: __ZN13InputEventKey11set_unicodeEj
undef: __ZN10MemoryPool9free_listE
undef: __ZN18AudioDriverManager10add_driverEP11AudioDriver
undef: __ZN10MemoryPool11memory_poolE
undef: __Z22postinitialize_handlerP6Object
undef: __ZNK6String11is_abs_pathEv
undef: __ZN2OS17native_video_playE6StringfS0_S0_
undef: __ZTV7OS_Unix
undef: __ZN10MemoryPool12total_memoryE
undef: __ZN9DirAccess24erase_contents_recursiveEv
undef: __ZN6Logger10logf_errorEPKcz
undef: __ZN2OS21hide_virtual_keyboardEv
undef: __ZN2OS25get_connected_midi_inputsEv
undef: __ZN13DirAccessUnix12list_dir_endEv
undef: __ZN15CompositeLoggerC1E6VectorIP6LoggerE
undef: __ZN15_GlobalNilClass4_nilE
undef: __ZN18MIDIDriverCoreMidiC1Ev
undef: __ZN7OS_UnixC2Ev
undef: __ZTI7OS_Unix
undef: __ZN12InputDefault8joy_axisEiif
undef: __Z7vformatRK6StringRK7VariantS4_S4_S4_S4_
undef: __ZN6StringpLEPKc
undef: __ZN2OS11set_contextEi
undef: __ZN2OS19print_all_resourcesE6String
undef: __ZN5Image6unlockEv
undef: __ZNK2OS21get_audio_driver_nameEi
undef: __ZN5Input13get_singletonEv
undef: __ZN13DirAccessUnix7is_linkE6String
undef: __ZN2OS12is_joy_knownEi
undef: __ZNK6StringltERKS_
undef: __ZN2OS17dialog_input_textE6StringS0_S0_P6ObjectS0_
undef: __ZN6RefPtrC1Ev
undef: __ZNK2OS15can_use_threadsEv
undef: __ZN2OS17native_video_stopEv
undef: __ZN9StdLoggerD2Ev
undef: __ZN2OS20native_video_unpauseEv
undef: __ZN2OS13set_exit_codeEi
undef: __ZN2OS18native_video_pauseEv
undef: __ZN2OS5yieldEv
undef: __ZNK7OS_Unix14get_ticks_usecEv
undef: __ZNK2OS13has_clipboardEv
undef: __ZNK7OS_Unix19get_processor_countEv
undef: __ZN7OS_Unix11debug_breakEv
undef: __ZN2OS22set_screen_orientationENS_17ScreenOrientationE
undef: __ZNK2OS21get_video_driver_nameEi
undef: __ZN2OS18set_no_window_modeEb
undef: __ZNK12AtlasTexture10get_regionEv
undef: __ZN6Logger10should_logEb
undef: __ZNK7OS_Unix17get_user_data_dirEv
undef: __ZNK2OS22get_free_static_memoryEv
undef: __ZNK2OS24get_dynamic_memory_usageEv
undef: __Z19keycode_has_unicodej
undef: __ZNK2OS28get_static_memory_peak_usageEv
undef: __ZN7OS_Unix13finalize_coreEv
undef: __ZNK2OS23get_static_memory_usageEv
undef: __ZNK7OS_Unix10delay_usecEj
undef: __ZNK7OS_Unix15set_environmentERK6StringS2_
undef: __ZN2OS22dump_resources_to_fileEPKc
undef: __ZN10FileAccess6existsERK6String
undef: __ZN24InputEventMagnifyGesture10set_factorEf
undef: __ZN2OS19dump_memory_to_fileEPKc
undef: __ZN12InputDefault17get_unused_joy_idEv
undef: __ZNK2OS27get_virtual_keyboard_heightEv
undef: __ZN18VisualServerRasterC1Ev
undef: __ZNK2OS20has_virtual_keyboardEv
undef: __ZNK7OS_Unix20get_system_time_secsEv
undef: __ZNK7OS_Unix8get_dateEb
undef: __ZN13DirAccessUnix11create_linkE6StringS0_
undef: __ZN12InputDefault13set_main_loopEP8MainLoop
undef: __ZNK7OS_Unix8get_timeEb
undef: __ZN10MemoryPool11alloc_mutexE
undef: __ZN2OS16vibrate_handheldEi
undef: __ZNK5Image8get_dataEv
undef: __ZNK7OS_Unix18is_process_runningERKx
undef: __ZNK7OS_Unix14get_process_idEv
undef: __ZN2OS28set_low_processor_usage_modeEb
undef: __ZNK2OS17is_keep_screen_onEv
undef: __ZNK6Object3getERK10StringNamePb
undef: __ZNK5Image10get_heightEv
undef: __ZN2OS18set_keep_screen_onEb
undef: __ZN7OS_Unix21close_dynamic_libraryEPv
undef: __ZN2OS17close_midi_inputsEv
undef: __ZNK2OS22get_audio_driver_countEv
undef: __ZNK2OS22get_video_driver_countEv
undef: __ZNK13DirAccessUnix17current_is_hiddenEv
undef: __ZN2OS21set_clipboard_primaryERK6String
undef: __ZN12InputDefault7joy_hatEii
undef: __ZN2OS16open_midi_inputsEv
undef: __ZN2OS11set_cmdlineEPKcRK4ListI6String16DefaultAllocatorE
undef: __ZNK12InputDefault21get_joy_guid_remappedEi
undef: __ZN13DirAccessUnix17get_modified_timeE6String
undef: __ZN13DirAccessUnix9read_linkE6String
undef: __ZN13DirAccessUnix6removeE6String
undef: __ZN13DirAccessUnix6renameE6StringS0_
undef: __ZN9DirAccess4copyE6StringS0_i
Undefined symbols for architecture x86_64:
  "DirAccessUnix::list_dir_begin()", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccessUnix::current_is_dir() const", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccessUnix::get_current_drive()", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccessUnix::get_current_dir()", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccess::get_current_dir_without_drive()", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccessUnix::make_dir(String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccessUnix::change_dir(String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccess::make_dir_recursive(String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccessUnix::file_exists(String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "AtlasTexture::get_atlas() const", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "typeinfo for AtlasTexture", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "typeinfo for Texture", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "Image::lock()", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "Image::get_pixel(int, int) const", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "DirAccessUnix::~DirAccessUnix()", referenced from:
      DirAccessOSX::~DirAccessOSX() in lto.o
      DirAccessOSX::~DirAccessOSX() in lto.o
  "OS::dialog_show(String, String, Vector<String>, Object*, String)", referenced from:
      vtable for OS_OSX in lto.o
  "Engine::get_singleton()", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "MemoryPool::allocs_used", referenced from:
      PoolVector<unsigned char>::_unreference() in lto.o
  "RefPtr::~RefPtr()", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "OS_Unix::initialize_core()", referenced from:
      OS_OSX::initialize_core() in lto.o
  "DirAccessUnix::DirAccessUnix()", referenced from:
      DirAccess* DirAccess::_create_builtin<DirAccessOSX>() in lto.o
  "String::get_base_dir() const", referenced from:
      OS_OSX::open_dynamic_library(String, void*&, bool) in lto.o
  "String::plus_file(String const&) const", referenced from:
      OS_OSX::open_dynamic_library(String, void*&, bool) in lto.o
      OS_OSX::get_config_path() const in lto.o
      OS_OSX::get_cache_path() const in lto.o
      DirAccessOSX::is_hidden(String const&) in lto.o
  "_err_print_error(char const*, char const*, int, char const*, ErrorHandlerType)", referenced from:
      List<String, DefaultAllocator>::~List() in lto.o
      List<String, DefaultAllocator>::_Data::erase(List<String, DefaultAllocator>::Element const*) in lto.o
      List<OS_OSX::WarpEvent, DefaultAllocator>::~List() in lto.o
      Map<String, Vector<OS_OSX::GlobalMenuItem>, Comparator<String>, DefaultAllocator>::operator[](String const&) in lto.o
      -[GodotContentView performDragOperation:] in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      push_to_key_event_buffer(OS_OSX::KeyEvent const&) in lto.o
      ...
  "String::operator+(String const&) const", referenced from:
      OS_OSX::alert(String const&, String const&) in lto.o
      OS_OSX::open_dynamic_library(String, void*&, bool) in lto.o
  "typeinfo for InputEvent", referenced from:
      Ref<InputEvent>::Ref<InputEventKey>(Ref<InputEventKey> const&) in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
      Ref<InputEvent>::Ref<InputEventMouseButton>(Ref<InputEventMouseButton> const&) in lto.o
      typeinfo for InputEventWithModifiers in lto.o
  "InputEventKey::set_echo(bool)", referenced from:
      -[GodotApplication sendEvent:] in lto.o
      OS_OSX::process_events() in lto.o
  "print_line(String)", referenced from:
      OS_OSX::alert(String const&, String const&) in lto.o
  "OS::is_no_window_mode_enabled() const", referenced from:
      vtable for OS_OSX in lto.o
  "Variant::operator=(Variant const&)", referenced from:
      OS_OSX::global_menu_add_item(String const&, String const&, Variant const&, Variant const&) in lto.o
      Vector<Variant>::push_back(Variant) in lto.o
      OS_OSX::GlobalMenuItem::operator=(OS_OSX::GlobalMenuItem const&) in lto.o
  "OS::set_update_vital_only(bool)", referenced from:
      vtable for OS_OSX in lto.o
  "String::operator==(char const*) const", referenced from:
      OS_OSX::_check_internal_feature_support(String const&) in lto.o
  "OS::set_use_vsync(bool)", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "InputDefault::joy_button(int, int, bool)", referenced from:
      JoypadOSX::process_joypads() in lto.o
  "OS::~OS()", referenced from:
      OS_OSX::~OS_OSX() in lto.o
      OS_OSX::OS_OSX() in lto.o
  "OS::set_low_processor_usage_mode_sleep_usec(int)", referenced from:
      vtable for OS_OSX in lto.o
  "Variant::operator bool() const", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "RasterizerGLES2::is_viable()", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "Array::Array()", referenced from:
      OS::get_display_cutouts() const in lto.o
  "_err_print_error(char const*, char const*, int, char const*, char const*, ErrorHandlerType)", referenced from:
      OS_OSX::execute(String const&, List<String, DefaultAllocator> const&, bool, long long*, String*, int*, bool, MutexImpl<std::__1::recursive_mutex>*, bool) in lto.o
      OS_OSX::set_native_icon(String const&) in lto.o
  "RasterizerGLES3::register_config()", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "OS_Unix::get_dynamic_library_symbol_handle(void*, String, void*&, bool)", referenced from:
      vtable for OS_OSX in lto.o
  "RasterizerGLES3::is_viable()", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "RasterizerGLES2::make_current()", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "MIDIDriverCoreMidi::close()", referenced from:
      OS_OSX::finalize() in lto.o
  "String::get_file() const", referenced from:
      OS_OSX::open_dynamic_library(String, void*&, bool) in lto.o
  "InputEventMouseButton::InputEventMouseButton()", referenced from:
      Ref<InputEventMouseButton>::instance() in lto.o
  "OS::get_executable_path() const", referenced from:
      OS_OSX::get_executable_path() const in lto.o
  "OS_Unix::has_environment(String const&) const", referenced from:
      vtable for OS_OSX in lto.o
  "String::operator+=(String const&)", referenced from:
      joypad_added_callback(void*, int, void*, __IOHIDDevice*) in lto.o
  "InputEventPanGesture::InputEventPanGesture()", referenced from:
      -[GodotContentView scrollWheel:] in lto.o
  "VisualServerWrapMT::VisualServerWrapMT(VisualServer*, bool)", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "InputEventMouse::set_button_mask(int)", referenced from:
      -[GodotContentView mouseMoved:] in lto.o
      sendScrollEvent(int, double, int) in lto.o
      _mouseDownEvent(NSEvent*, int, int, bool) in lto.o
  "InputEventMouseMotion::set_tilt(Vector2 const&)", referenced from:
      -[GodotContentView mouseMoved:] in lto.o
  "Variant::operator String() const", referenced from:
      handle_crash(int) in lto.o
  "DirAccessUnix::get_filesystem_type() const", referenced from:
      vtable for DirAccessOSX in lto.o
  "String::operator==(String const&) const", referenced from:
      -[GodotApplicationDelegate applicationDockMenu:] in lto.o
      OS_OSX::global_menu_clear(String const&) in lto.o
      OS_OSX::execute(String const&, List<String, DefaultAllocator> const&, bool, long long*, String*, int*, bool, MutexImpl<std::__1::recursive_mutex>*, bool) in lto.o
      OS_OSX::_update_global_menu() in lto.o
  "operator new(unsigned long, void* (*)(unsigned long))", referenced from:
      List<String, DefaultAllocator>::push_back(String const&) in lto.o
      Map<String, Vector<OS_OSX::GlobalMenuItem>, Comparator<String>, DefaultAllocator>::operator[](String const&) in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "InputEventMouseMotion::set_relative(Vector2 const&)", referenced from:
      -[GodotContentView mouseMoved:] in lto.o
  "OS_Unix::get_unix_time() const", referenced from:
      vtable for OS_OSX in lto.o
  "Color::to_argb32() const", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "Variant::operator==(Variant const&) const", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "OS::get_screen_orientation() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::get_time_zone_info() const", referenced from:
      vtable for OS_OSX in lto.o
  "Object::notification(int, bool)", referenced from:
      handle_crash(int) in lto.o
      -[GodotApplicationDelegate applicationShouldTerminate:] in lto.o
      -[GodotApplicationDelegate showAbout:] in lto.o
      -[GodotWindowDelegate windowShouldClose:] in lto.o
      -[GodotWindowDelegate windowDidBecomeKey:] in lto.o
      -[GodotWindowDelegate windowDidResignKey:] in lto.o
      -[GodotWindowDelegate windowDidMiniaturize:] in lto.o
      ...
  "String::replace(char const*, char const*) const", referenced from:
      OS_OSX::get_locale() const in lto.o
  "OS::show_virtual_keyboard(String const&, Rect2 const&, bool, int, int, int)", referenced from:
      vtable for OS_OSX in lto.o
  "InputEventKey::set_pressed(bool)", referenced from:
      -[GodotApplication sendEvent:] in lto.o
      OS_OSX::process_events() in lto.o
  "InputEventMouseButton::set_factor(float)", referenced from:
      sendScrollEvent(int, double, int) in lto.o
  "Variant::Variant(String const&)", referenced from:
      handle_crash(int) in lto.o
  "Main::force_redraw()", referenced from:
      -[GodotContentView drawRect:] in lto.o
      OS_OSX::pre_wait_observer_cb(__CFRunLoopObserver*, unsigned long, void*) in lto.o
  "print_error(String)", referenced from:
      handle_crash(int) in lto.o
  "String::operator=(char const*)", referenced from:
      OS_OSX::get_unique_id() const in lto.o
      joypad_added_callback(void*, int, void*, __IOHIDDevice*) in lto.o
  "typeinfo for Reference", referenced from:
      void Ref<Reference>::operator=<Resource>(Ref<Resource> const&) in lto.o
  "CharString::get_data() const", referenced from:
      _main in lto.o
      -[GodotApplicationDelegate applicationDockMenu:] in lto.o
      OS_OSX::alert(String const&, String const&) in lto.o
      OS_OSX::set_window_title(String const&) in lto.o
      OS_OSX::set_clipboard(String const&) in lto.o
      OS_OSX::set_borderless_window(bool) in lto.o
      OS_OSX::open_dynamic_library(String, void*&, bool) in lto.o
      ...
  "operator+(char const*, String const&)", referenced from:
      OS_OSX::alert(String const&, String const&) in lto.o
      OS_OSX::open_dynamic_library(String, void*&, bool) in lto.o
      OS_OSX::move_to_trash(String const&) in lto.o
      OS_OSX::run() in lto.o
  "OS::has_touchscreen_ui_hint() const", referenced from:
      vtable for OS_OSX in lto.o
  "Memory::realloc_static(void*, unsigned long, bool)", referenced from:
      -[GodotContentView performDragOperation:] in lto.o
      push_to_key_event_buffer(OS_OSX::KeyEvent const&) in lto.o
      OS_OSX::set_window_mouse_passthrough(PoolVector<Vector2> const&) in lto.o
      Vector<LayoutInfo>::push_back(LayoutInfo) in lto.o
      Vector<Variant>::push_back(Variant) in lto.o
      CowData<OS_OSX::GlobalMenuItem>::resize(int) in lto.o
      hid_element_added(void const*, void*) in lto.o
      ...
  "_err_flush_stdout()", referenced from:
      -[GodotApplicationDelegate applicationDockMenu:] in lto.o
      -[GodotContentView performDragOperation:] in lto.o
      push_to_key_event_buffer(OS_OSX::KeyEvent const&) in lto.o
      OS_OSX::set_window_mouse_passthrough(PoolVector<Vector2> const&) in lto.o
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
      OS_OSX::set_native_icon(String const&) in lto.o
      OS_OSX::process_events() in lto.o
      ...
  "Memory::free_static(void*, bool)", referenced from:
      String::~String() in lto.o
      List<String, DefaultAllocator>::push_back(String const&) in lto.o
      List<String, DefaultAllocator>::~List() in lto.o
      List<String, DefaultAllocator>::_Data::erase(List<String, DefaultAllocator>::Element const*) in lto.o
      CharString::~CharString() in lto.o
      OS_OSX::~OS_OSX() in lto.o
      void memdelete_allocator<Map<OS::CursorShape, Vector<Variant>, Comparator<OS::CursorShape>, DefaultAllocator>::Element, DefaultAllocator>(Map<OS::CursorShape, Vector<Variant>, Comparator<OS::CursorShape>, DefaultAllocator>::Element*) in lto.o
      ...
  "OS::_set_logger(CompositeLogger*)", referenced from:
      OS_OSX::OS_OSX() in lto.o
  "OS_Unix::get_stdin_string(bool)", referenced from:
      vtable for OS_OSX in lto.o
  "MIDIDriverCoreMidi::~MIDIDriverCoreMidi()", referenced from:
      OS_OSX::~OS_OSX() in lto.o
      OS_OSX::OS_OSX() in lto.o
  "InputEventMouseMotion::set_speed(Vector2 const&)", referenced from:
      -[GodotContentView mouseMoved:] in lto.o
  "String::utf8() const", referenced from:
      _main in lto.o
      -[GodotApplicationDelegate applicationDockMenu:] in lto.o
      OS_OSX::alert(String const&, String const&) in lto.o
      OS_OSX::set_window_title(String const&) in lto.o
      OS_OSX::set_clipboard(String const&) in lto.o
      OS_OSX::set_borderless_window(bool) in lto.o
      OS_OSX::open_dynamic_library(String, void*&, bool) in lto.o
      ...
  "Variant::Variant(int)", referenced from:
      handle_crash(int) in lto.o
  "InputEventWithModifiers::set_shift(bool)", referenced from:
      -[GodotApplication sendEvent:] in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
      sendScrollEvent(int, double, int) in lto.o
      _mouseDownEvent(NSEvent*, int, int, bool) in lto.o
      OS_OSX::process_events() in lto.o
      ...
  "StdLogger::logv(char const*, __va_list_tag*, bool)", referenced from:
      vtable for OSXTerminalLogger in lto.o
  "InputEventMouseMotion::set_pressure(float)", referenced from:
      -[GodotContentView mouseMoved:] in lto.o
  "Memory::alloc_static(unsigned long, bool)", referenced from:
      DefaultAllocator::alloc(unsigned long) in lto.o
      -[GodotContentView performDragOperation:] in lto.o
      push_to_key_event_buffer(OS_OSX::KeyEvent const&) in lto.o
      CowData<String>::_copy_on_write() in lto.o
      OS_OSX::set_window_mouse_passthrough(PoolVector<Vector2> const&) in lto.o
      OS_OSX::set_native_icon(String const&) in lto.o
      Vector<LayoutInfo>::push_back(LayoutInfo) in lto.o
      ...
  "OS::get_iso_date_time(bool) const", referenced from:
      vtable for OS_OSX in lto.o
  "String::erase(int, int)", referenced from:
      handle_crash(int) in lto.o
  "String::capitalize() const", referenced from:
      OS_OSX::get_godot_dir_name() const in lto.o
  "InputEventPanGesture::set_delta(Vector2 const&)", referenced from:
      -[GodotContentView scrollWheel:] in lto.o
  "OS::get_exit_code() const", referenced from:
      _main in lto.o
      vtable for OS_OSX in lto.o
  "RasterizerGLES3::make_current()", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "String::substr(int, int) const", referenced from:
      handle_crash(int) in lto.o
  "Variant::Variant(long long)", referenced from:
      handle_crash(int) in lto.o
  "InputEventGesture::set_position(Vector2 const&)", referenced from:
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
  "Main::start()", referenced from:
      _main in lto.o
  "DirAccessUnix::get_space_left()", referenced from:
      vtable for DirAccessOSX in lto.o
  "InputEventKey::set_scancode(unsigned int)", referenced from:
      -[GodotApplication sendEvent:] in lto.o
      OS_OSX::process_events() in lto.o
  "operator new(unsigned long, char const*)", referenced from:
      Ref<InputEventKey>::instance() in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
      Ref<InputEventMouseButton>::instance() in lto.o
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
      DirAccess* DirAccess::_create_builtin<DirAccessOSX>() in lto.o
      ...
  "Variant::Variant(char const*)", referenced from:
      handle_crash(int) in lto.o
  "_err_print_error(char const*, char const*, int, char const*, String const&, ErrorHandlerType)", referenced from:
      OS_OSX::open_dynamic_library(String, void*&, bool) in lto.o
      OS_OSX::get_processor_name() const in lto.o
  "AudioDriverManager::initialize(int)", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "InputEventMagnifyGesture::InputEventMagnifyGesture()", referenced from:
      -[GodotContentView magnifyWithEvent:] in lto.o
  "AudioDriverCoreAudio::~AudioDriverCoreAudio()", referenced from:
      OS_OSX::~OS_OSX() in lto.o
      OS_OSX::OS_OSX() in lto.o
  "OS_Unix::get_system_time_msecs() const", referenced from:
      vtable for OS_OSX in lto.o
  "InputEventMouse::set_position(Vector2 const&)", referenced from:
      -[GodotContentView mouseMoved:] in lto.o
      sendScrollEvent(int, double, int) in lto.o
      _mouseDownEvent(NSEvent*, int, int, bool) in lto.o
  "typeinfo for Image", referenced from:
      OS_OSX::set_icon(Ref<Image> const&) in lto.o
  "DirAccess::create_func", referenced from:
      OS_OSX::initialize_core() in lto.o
  "OS::get_singleton()", referenced from:
      handle_crash(int) in lto.o
      -[GodotApplicationDelegate application:openFile:] in lto.o
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
      OS_OSX::get_screen_refresh_rate(int) const in lto.o
      OS_OSX::pre_wait_observer_cb(__CFRunLoopObserver*, unsigned long, void*) in lto.o
  "Variant::clear()", referenced from:
      void memdelete_allocator<Map<OS::CursorShape, Vector<Variant>, Comparator<OS::CursorShape>, DefaultAllocator>::Element, DefaultAllocator>(Map<OS::CursorShape, Vector<Variant>, Comparator<OS::CursorShape>, DefaultAllocator>::Element*) in lto.o
      handle_crash(int) in lto.o
      CowData<OS_OSX::GlobalMenuItem>::_unref(void*) in lto.o
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
      OS_OSX::global_menu_add_item(String const&, String const&, Variant const&, Variant const&) in lto.o
      OS_OSX::global_menu_add_separator(String const&) in lto.o
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
      ...
  "OS::is_in_low_processor_usage_mode() const", referenced from:
      vtable for OS_OSX in lto.o
  "InputDefault::InputDefault()", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "typeinfo for Object", referenced from:
      Ref<InputEventWithModifiers>::Ref<InputEventKey>(Ref<InputEventKey> const&) in lto.o
      Ref<InputEvent>::Ref<InputEventKey>(Ref<InputEventKey> const&) in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
      Ref<InputEventWithModifiers>::Ref<InputEventMouseButton>(Ref<InputEventMouseButton> const&) in lto.o
      Ref<InputEvent>::Ref<InputEventMouseButton>(Ref<InputEventMouseButton> const&) in lto.o
      ...
  "OS::get_resource_dir() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_clipboard_primary() const", referenced from:
      vtable for OS_OSX in lto.o
  "_VERSION_HASH", referenced from:
      handle_crash(int) in lto.o
  "DirAccessUnix::is_hidden(String const&)", referenced from:
      DirAccessOSX::is_hidden(String const&) in lto.o
  "InputEventMouseMotion::InputEventMouseMotion()", referenced from:
      -[GodotContentView mouseMoved:] in lto.o
  "DirAccessUnix::dir_exists(String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "ProjectSettings::get_singleton()", referenced from:
      handle_crash(int) in lto.o
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "StringName::~StringName()", referenced from:
      handle_crash(int) in lto.o
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "Main::setup(char const*, int, char**, bool)", referenced from:
      _main in lto.o
  "InputEventWithModifiers::set_alt(bool)", referenced from:
      -[GodotApplication sendEvent:] in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
      sendScrollEvent(int, double, int) in lto.o
      _mouseDownEvent(NSEvent*, int, int, bool) in lto.o
      OS_OSX::process_events() in lto.o
      ...
  "Reference::unreference()", referenced from:
      -[GodotApplication sendEvent:] in lto.o
      Ref<InputEventKey>::instance() in lto.o
      Ref<InputEventWithModifiers>::Ref<InputEventKey>(Ref<InputEventKey> const&) in lto.o
      Ref<InputEvent>::Ref<InputEventKey>(Ref<InputEventKey> const&) in lto.o
      OS_OSX::push_input(Ref<InputEvent> const&) in lto.o
      Ref<InputEventWithModifiers>::~Ref() in lto.o
      Ref<InputEvent>::~Ref() in lto.o
      ...
  "_err_print_index_error(char const*, char const*, int, long long, long long, char const*, char const*, char const*, bool)", referenced from:
      -[GodotApplicationDelegate applicationDockMenu:] in lto.o
      -[GodotContentView performDragOperation:] in lto.o
      push_to_key_event_buffer(OS_OSX::KeyEvent const&) in lto.o
      OS_OSX::global_menu_remove_item(String const&, int) in lto.o
      OS_OSX::set_window_mouse_passthrough(PoolVector<Vector2> const&) in lto.o
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
      OS_OSX::set_native_icon(String const&) in lto.o
      ...
  "OS_Unix::kill(long long const&)", referenced from:
      vtable for OS_OSX in lto.o
  "InputEventKey::set_physical_scancode(unsigned int)", referenced from:
      -[GodotApplication sendEvent:] in lto.o
      OS_OSX::process_events() in lto.o
  "Variant::Variant(RefPtr const&)", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "typeinfo for StdLogger", referenced from:
      typeinfo for OSXTerminalLogger in lto.o
  "DirAccessUnix::get_next()", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccessUnix::drives_are_shortcuts()", referenced from:
      vtable for DirAccessOSX in lto.o
  "RasterizerGLES2::register_config()", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "Reference::init_ref()", referenced from:
      Ref<InputEventKey>::instance() in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
      Ref<InputEventMouseButton>::instance() in lto.o
  "OS::native_video_is_playing() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_embedded_pck_offset() const", referenced from:
      vtable for OS_OSX in lto.o
  "InputEventWithModifiers::set_metakey(bool)", referenced from:
      -[GodotApplication sendEvent:] in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
      sendScrollEvent(int, double, int) in lto.o
      _mouseDownEvent(NSEvent*, int, int, bool) in lto.o
      OS_OSX::process_events() in lto.o
      ...
  "Variant::Variant(Variant const&)", referenced from:
      CowData<Variant>::_copy_on_write() in lto.o
      CowData<OS_OSX::GlobalMenuItem>::_copy_on_write() in lto.o
  "InputEventMouseButton::set_doubleclick(bool)", referenced from:
      _mouseDownEvent(NSEvent*, int, int, bool) in lto.o
  "InputEventWithModifiers::set_control(bool)", referenced from:
      -[GodotApplication sendEvent:] in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
      sendScrollEvent(int, double, int) in lto.o
      _mouseDownEvent(NSEvent*, int, int, bool) in lto.o
      OS_OSX::process_events() in lto.o
      ...
  "InputEventMouseButton::set_pressed(bool)", referenced from:
      sendScrollEvent(int, double, int) in lto.o
      _mouseDownEvent(NSEvent*, int, int, bool) in lto.o
  "Main::iteration()", referenced from:
      -[GodotContentView drawRect:] in lto.o
      OS_OSX::pre_wait_observer_cb(__CFRunLoopObserver*, unsigned long, void*) in lto.o
      OS_OSX::run() in lto.o
  "Reference::reference()", referenced from:
      Ref<InputEventKey>::instance() in lto.o
      Ref<InputEventWithModifiers>::Ref<InputEventKey>(Ref<InputEventKey> const&) in lto.o
      Ref<InputEvent>::Ref<InputEventKey>(Ref<InputEventKey> const&) in lto.o
      OS_OSX::push_input(Ref<InputEvent> const&) in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
      ...
  "String::operator!=(char const*) const", referenced from:
      _main in lto.o
      handle_crash(int) in lto.o
      OS_OSX::global_menu_add_item(String const&, String const&, Variant const&, Variant const&) in lto.o
      OS_OSX::global_menu_add_separator(String const&) in lto.o
      OS_OSX::global_menu_clear(String const&) in lto.o
  "OS::print_resources_in_use(bool)", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_model_name() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::center_window()", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::set_cwd(String const&)", referenced from:
      vtable for OS_OSX in lto.o
  "String::String(char const*)", referenced from:
      handle_crash(int) in lto.o
      -[GodotApplicationDelegate applicationDockMenu:] in lto.o
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
      OS_OSX::alert(String const&, String const&) in lto.o
      OS_OSX::get_clipboard() const in lto.o
      OS::get_tablet_driver_name(int) const in lto.o
      OS::get_current_tablet_driver() const in lto.o
      ...
  "InputEventKey::InputEventKey()", referenced from:
      Ref<InputEventKey>::instance() in lto.o
  "predelete_handler(Object*)", referenced from:
      -[GodotApplication sendEvent:] in lto.o
      Ref<InputEventKey>::instance() in lto.o
      Ref<InputEventWithModifiers>::Ref<InputEventKey>(Ref<InputEventKey> const&) in lto.o
      Ref<InputEvent>::Ref<InputEventKey>(Ref<InputEventKey> const&) in lto.o
      OS_OSX::push_input(Ref<InputEvent> const&) in lto.o
      Ref<InputEventWithModifiers>::~Ref() in lto.o
      Ref<InputEvent>::~Ref() in lto.o
      ...
  "OS_Unix::unix_initialize_audio(int)", referenced from:
      vtable for OS_OSX in lto.o
  "String::parse_utf8(char const*, int)", referenced from:
      -[GodotApplicationDelegate application:openFile:] in lto.o
      -[GodotContentView setMarkedText:selectedRange:replacementRange:] in lto.o
      -[GodotContentView performDragOperation:] in lto.o
      OS_OSX::get_clipboard() const in lto.o
      OS_OSX::get_executable_path() const in lto.o
      OS_OSX::get_bundle_resource_dir() const in lto.o
      OS_OSX::get_bundle_icon_path() const in lto.o
      ...
  "OS::is_custom_exit_code()", referenced from:
      vtable for OS_OSX in lto.o
  "InputEventMouseMotion::set_pen_inverted(bool)", referenced from:
      -[GodotContentView mouseMoved:] in lto.o
  "InputDefault::set_mouse_position(Vector2 const&)", referenced from:
      -[GodotWindowDelegate windowDidBecomeKey:] in lto.o
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
      OS_OSX::set_window_position(Vector2 const&) in lto.o
  "OS_Unix::execute(String const&, List<String, DefaultAllocator> const&, bool, long long*, String*, int*, bool, MutexImpl<std::__1::recursive_mutex>*, bool)", referenced from:
      OS_OSX::execute(String const&, List<String, DefaultAllocator> const&, bool, long long*, String*, int*, bool, MutexImpl<std::__1::recursive_mutex>*, bool) in lto.o
  "InputEventMouseButton::set_button_index(int)", referenced from:
      sendScrollEvent(int, double, int) in lto.o
      _mouseDownEvent(NSEvent*, int, int, bool) in lto.o
  "StringName::StringName(char const*)", referenced from:
      handle_crash(int) in lto.o
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "Image::convert(Image::Format)", referenced from:
      OS_OSX::set_icon(Ref<Image> const&) in lto.o
  "Main::is_iterating()", referenced from:
      -[GodotContentView drawRect:] in lto.o
      OS_OSX::pre_wait_observer_cb(__CFRunLoopObserver*, unsigned long, void*) in lto.o
  "OS::add_frame_delay(bool)", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_low_processor_usage_mode_sleep_usec() const", referenced from:
      vtable for OS_OSX in lto.o
  "Main::cleanup(bool)", referenced from:
      _main in lto.o
  "_err_print_error(char const*, char const*, int, String const&, ErrorHandlerType)", referenced from:
      OS_OSX::move_to_trash(String const&) in lto.o
      OS_OSX::run() in lto.o
  "OS_Unix::initialize_debugging()", referenced from:
      vtable for OS_OSX in lto.o
  "String::utf8(char const*, int)", referenced from:
      OS_OSX::move_to_trash(String const&) in lto.o
      OS_OSX::get_processor_name() const in lto.o
      OS_OSX::run() in lto.o
  "OS_Unix::get_environment(String const&) const", referenced from:
      vtable for OS_OSX in lto.o
  "FileAccess::open(String const&, int, Error*)", referenced from:
      OS_OSX::set_native_icon(String const&) in lto.o
  "typeinfo for DirAccessUnix", referenced from:
      typeinfo for DirAccessOSX in lto.o
  "InputEventMouse::set_global_position(Vector2 const&)", referenced from:
      -[GodotContentView mouseMoved:] in lto.o
      sendScrollEvent(int, double, int) in lto.o
      _mouseDownEvent(NSEvent*, int, int, bool) in lto.o
  "Image::get_width() const", referenced from:
      OS_OSX::set_icon(Ref<Image> const&) in lto.o
  "Vector2::dot(Vector2 const&) const", referenced from:
      OS_OSX::process_events() in lto.o
  "Variant::Variant(Vector2 const&)", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "AudioDriverCoreAudio::AudioDriverCoreAudio()", referenced from:
      OS_OSX::OS_OSX() in lto.o
  "InputEventKey::set_unicode(unsigned int)", referenced from:
      OS_OSX::process_events() in lto.o
  "MemoryPool::free_list", referenced from:
      PoolVector<unsigned char>::_unreference() in lto.o
  "AudioDriverManager::add_driver(AudioDriver*)", referenced from:
      OS_OSX::OS_OSX() in lto.o
  "MemoryPool::memory_pool", referenced from:
      PoolVector<unsigned char>::_unreference() in lto.o
  "postinitialize_handler(Object*)", referenced from:
      Ref<InputEventKey>::instance() in lto.o
      -[GodotContentView mouseMoved:] in lto.o
      -[GodotContentView magnifyWithEvent:] in lto.o
      -[GodotContentView scrollWheel:] in lto.o
      Ref<InputEventMouseButton>::instance() in lto.o
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "String::is_abs_path() const", referenced from:
      OS_OSX::get_data_path() const in lto.o
      OS_OSX::get_config_path() const in lto.o
      OS_OSX::get_cache_path() const in lto.o
  "OS::native_video_play(String, float, String, String)", referenced from:
      vtable for OS_OSX in lto.o
  "vtable for OS_Unix", referenced from:
      OS_OSX::~OS_OSX() in lto.o
      OS_OSX::OS_OSX() in lto.o
  NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
  "MemoryPool::total_memory", referenced from:
      PoolVector<unsigned char>::_unreference() in lto.o
  "DirAccess::erase_contents_recursive()", referenced from:
      vtable for DirAccessOSX in lto.o
  "Logger::logf_error(char const*, ...)", referenced from:
      OSXTerminalLogger::log_error(char const*, char const*, int, char const*, char const*, Logger::ErrorType) in lto.o
  "OS::hide_virtual_keyboard()", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_connected_midi_inputs()", referenced from:
      vtable for OS_OSX in lto.o
  "DirAccessUnix::list_dir_end()", referenced from:
      vtable for DirAccessOSX in lto.o
  "CompositeLogger::CompositeLogger(Vector<Logger*>)", referenced from:
      OS_OSX::OS_OSX() in lto.o
  "_GlobalNilClass::_nil", referenced from:
      OS_OSX::OS_OSX() in lto.o
  "MIDIDriverCoreMidi::MIDIDriverCoreMidi()", referenced from:
      OS_OSX::OS_OSX() in lto.o
  "OS_Unix::OS_Unix()", referenced from:
      OS_OSX::OS_OSX() in lto.o
  "typeinfo for OS_Unix", referenced from:
      typeinfo for OS_OSX in lto.o
  "InputDefault::joy_axis(int, int, float)", referenced from:
      JoypadOSX::process_joypads() in lto.o
  "vformat(String const&, Variant const&, Variant const&, Variant const&, Variant const&, Variant const&)", referenced from:
      handle_crash(int) in lto.o
  "String::operator+=(char const*)", referenced from:
      joypad_added_callback(void*, int, void*, __IOHIDDevice*) in lto.o
  "OS::set_context(int)", referenced from:
      vtable for OS_OSX in lto.o
  "OS::print_all_resources(String)", referenced from:
      vtable for OS_OSX in lto.o
  "Image::unlock()", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "OS::get_audio_driver_name(int) const", referenced from:
      vtable for OS_OSX in lto.o
  "Input::get_singleton()", referenced from:
      JoypadOSX::JoypadOSX() in lto.o
  "DirAccessUnix::is_link(String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "OS::is_joy_known(int)", referenced from:
      vtable for OS_OSX in lto.o
  "String::operator<(String const&) const", referenced from:
      Map<String, Vector<OS_OSX::GlobalMenuItem>, Comparator<String>, DefaultAllocator>::operator[](String const&) in lto.o
      OS_OSX::global_menu_add_item(String const&, String const&, Variant const&, Variant const&) in lto.o
      OS_OSX::global_menu_add_separator(String const&) in lto.o
      OS_OSX::global_menu_clear(String const&) in lto.o
  "OS::dialog_input_text(String, String, String, Object*, String)", referenced from:
      vtable for OS_OSX in lto.o
  "RefPtr::RefPtr()", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "OS::can_use_threads() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::native_video_stop()", referenced from:
      vtable for OS_OSX in lto.o
  "StdLogger::~StdLogger()", referenced from:
      OSXTerminalLogger::~OSXTerminalLogger() in lto.o
      OSXTerminalLogger::~OSXTerminalLogger() in lto.o
  "OS::native_video_unpause()", referenced from:
      vtable for OS_OSX in lto.o
  "OS::set_exit_code(int)", referenced from:
      vtable for OS_OSX in lto.o
  "OS::native_video_pause()", referenced from:
      vtable for OS_OSX in lto.o
  "OS::yield()", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::get_ticks_usec() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::has_clipboard() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::get_processor_count() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::debug_break()", referenced from:
      vtable for OS_OSX in lto.o
  "OS::set_screen_orientation(OS::ScreenOrientation)", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_video_driver_name(int) const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::set_no_window_mode(bool)", referenced from:
      vtable for OS_OSX in lto.o
  "AtlasTexture::get_region() const", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
  "Logger::should_log(bool)", referenced from:
      OSXTerminalLogger::log_error(char const*, char const*, int, char const*, char const*, Logger::ErrorType) in lto.o
  "OS_Unix::get_user_data_dir() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_free_static_memory() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_dynamic_memory_usage() const", referenced from:
      vtable for OS_OSX in lto.o
  "keycode_has_unicode(unsigned int)", referenced from:
      -[GodotContentView keyDown:] in lto.o
      -[GodotContentView keyUp:] in lto.o
  "OS::get_static_memory_peak_usage() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::finalize_core()", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_static_memory_usage() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::delay_usec(unsigned int) const", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::set_environment(String const&, String const&) const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::dump_resources_to_file(char const*)", referenced from:
      vtable for OS_OSX in lto.o
  "FileAccess::exists(String const&)", referenced from:
      OS_OSX::open_dynamic_library(String, void*&, bool) in lto.o
  "InputEventMagnifyGesture::set_factor(float)", referenced from:
      -[GodotContentView magnifyWithEvent:] in lto.o
  "OS::dump_memory_to_file(char const*)", referenced from:
      vtable for OS_OSX in lto.o
  "InputDefault::get_unused_joy_id()", referenced from:
      joypad_added_callback(void*, int, void*, __IOHIDDevice*) in lto.o
  "OS::get_virtual_keyboard_height() const", referenced from:
      vtable for OS_OSX in lto.o
  "VisualServerRaster::VisualServerRaster()", referenced from:
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "OS::has_virtual_keyboard() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::get_system_time_secs() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::get_date(bool) const", referenced from:
      vtable for OS_OSX in lto.o
  "DirAccessUnix::create_link(String, String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "InputDefault::set_main_loop(MainLoop*)", referenced from:
      OS_OSX::set_main_loop(MainLoop*) in lto.o
  "OS_Unix::get_time(bool) const", referenced from:
      vtable for OS_OSX in lto.o
  "MemoryPool::alloc_mutex", referenced from:
      PoolVector<unsigned char>::_unreference() in lto.o
  "OS::vibrate_handheld(int)", referenced from:
      vtable for OS_OSX in lto.o
  "Image::get_data() const", referenced from:
      OS_OSX::set_custom_mouse_cursor(Ref<Resource> const&, OS::CursorShape, Vector2 const&) in lto.o
      OS_OSX::set_icon(Ref<Image> const&) in lto.o
  "OS_Unix::is_process_running(long long const&) const", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::get_process_id() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::set_low_processor_usage_mode(bool)", referenced from:
      vtable for OS_OSX in lto.o
  "OS::is_keep_screen_on() const", referenced from:
      vtable for OS_OSX in lto.o
  "Object::get(StringName const&, bool*) const", referenced from:
      handle_crash(int) in lto.o
      OS_OSX::initialize(OS::VideoMode const&, int, int) in lto.o
  "Image::get_height() const", referenced from:
      OS_OSX::set_icon(Ref<Image> const&) in lto.o
  "OS::set_keep_screen_on(bool)", referenced from:
      vtable for OS_OSX in lto.o
  "OS_Unix::close_dynamic_library(void*)", referenced from:
      vtable for OS_OSX in lto.o
  "OS::close_midi_inputs()", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_audio_driver_count() const", referenced from:
      vtable for OS_OSX in lto.o
  "OS::get_video_driver_count() const", referenced from:
      vtable for OS_OSX in lto.o
  "DirAccessUnix::current_is_hidden() const", referenced from:
      vtable for DirAccessOSX in lto.o
  "OS::set_clipboard_primary(String const&)", referenced from:
      vtable for OS_OSX in lto.o
  "InputDefault::joy_hat(int, int)", referenced from:
      JoypadOSX::process_joypads() in lto.o
  "OS::open_midi_inputs()", referenced from:
      vtable for OS_OSX in lto.o
  "OS::set_cmdline(char const*, List<String, DefaultAllocator> const&)", referenced from:
      vtable for OS_OSX in lto.o
  "InputDefault::get_joy_guid_remapped(int) const", referenced from:
      OS_OSX::get_joy_guid(int) const in lto.o
  "DirAccessUnix::get_modified_time(String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccessUnix::read_link(String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccessUnix::remove(String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccessUnix::rename(String, String)", referenced from:
      vtable for DirAccessOSX in lto.o
  "DirAccess::copy(String, String, int)", referenced from:
      vtable for DirAccessOSX in lto.o
ld: symbol(s) not found for architecture x86_64
clang-13: [0;1;31merror: [0m[1mlinker command failed with exit code 1 (use -v to see invocation)[0m
scons: *** [bin/godot.osx.opt.tools.x86_64] Error 1
scons: building terminated because of errors.
[Time elapsed: 00:01:32.196]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering if it was using the wrong ld but checking with -v it seems fine:

/root/osxcross/target/bin/x86_64-apple-darwin21.4-c++ -o bin/godot.osx.opt.tools.x86_64 -v -arch x86_64 -mmacosx-version-min=10.12 -flto -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 platform/osx/crash_handler_osx.osx.opt.tools.x86_64.o platform/osx/os_osx.osx.opt.tools.x86_64.o platform/osx/godot_main_osx.osx.opt.tools.x86_64.o platform/osx/dir_access_osx.osx.opt.tools.x86_64.o platform/osx/joypad_osx.osx.opt.tools.x86_64.o platform/osx/power_osx.osx.opt.tools.x86_64.o main/libmain.osx.opt.tools.x86_64.a main/tests/libtests.osx.opt.tools.x86_64.a modules/libmodules.osx.opt.tools.x86_64.a platform/libplatform.osx.opt.tools.x86_64.a drivers/libdrivers.osx.opt.tools.x86_64.a editor/libeditor.osx.opt.tools.x86_64.a scene/libscene.osx.opt.tools.x86_64.a servers/libservers.osx.opt.tools.x86_64.a core/libcore.osx.opt.tools.x86_64.a modules/freetype/libfreetype_builtin.osx.opt.tools.x86_64.a -lpthread
clang version 13.0.1 (https://github.com/tpoechtrager/osxcross.git 17bb5e2d0a46533c1dd525cf4e9a80d88bd9f00e)
Target: x86_64-apple-darwin21.4
Thread model: posix
InstalledDir: /usr/bin
 "/root/osxcross/target/bin/x86_64-apple-darwin21.4-ld" -demangle -lto_library /usr/lib/libLTO.dylib -dynamic -arch x86_64 -platform_version macos 10.12.0 12.3 -syslibroot /root/osxcross/target/bin/../SDK/MacOSX12.3.sdk -o bin/godot.osx.opt.tools.x86_64 -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 platform/osx/crash_handler_osx.osx.opt.tools.x86_64.o platform/osx/os_osx.osx.opt.tools.x86_64.o platform/osx/godot_main_osx.osx.opt.tools.x86_64.o platform/osx/dir_access_osx.osx.opt.tools.x86_64.o platform/osx/joypad_osx.osx.opt.tools.x86_64.o platform/osx/power_osx.osx.opt.tools.x86_64.o main/libmain.osx.opt.tools.x86_64.a main/tests/libtests.osx.opt.tools.x86_64.a modules/libmodules.osx.opt.tools.x86_64.a platform/libplatform.osx.opt.tools.x86_64.a drivers/libdrivers.osx.opt.tools.x86_64.a editor/libeditor.osx.opt.tools.x86_64.a scene/libscene.osx.opt.tools.x86_64.a servers/libservers.osx.opt.tools.x86_64.a core/libcore.osx.opt.tools.x86_64.a modules/freetype/libfreetype_builtin.osx.opt.tools.x86_64.a -lpthread -lc++ -lSystem /usr/lib/clang/13.0.1/lib/darwin/libclang_rt.osx.a

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing it on Mac right now, full LTO is 5 min into linking and it already using 19 GB of ram and hitting the swap, so I guess it will take a while.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yell full LTO seems really slow with LLVM as it doesn't use parallelism. ThinLTO seems to be a much better option for LLVM so current version of that PR defaults to it with production=yes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done some testing with editor release-debug builds on ARM64 macOS, and do a comparison for the performance of opening large project in the editor, and stripped executable sizes:

LTO Link time (real) Link time (CPU time) Memory used by linker Executable size Speed improvement
No LTO < 1 min < 1 min ~ 500 MB 109 MB Reference
Full LTO 2:30 h 1:20 h ~ 48 GB 120 MB ~ 1-2%
Thin LTO 16 min 1:50 h ~ 6 GB 132 MB ~ 1%

Seems like LTO is almost entirely useless.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woah. That's pretty surprising numbers. But definitely seems like something we should keep off for macOS.

If you still have the builds around, it could be worth checking the impact on performance for GDScript, as on Linux/Windows last we compared we got some pretty good numbers for LTO.

I guess we can set ("lto", "none") default option for macOS like done for iOS, but keep it exposed for those who want to experiment?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think adding the option to experiment makes sense, but make sure to print a warning if it's enabled on macOS.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested it with GDScript, results are similar, about 2% improvement. I'll re-test it with the x86_64 versions later, maybe it's M1 only case.

platform/linuxbsd/detect.py Outdated Show resolved Hide resolved
SConstruct Outdated Show resolved Hide resolved
platform/ios/detect.py Show resolved Hide resolved
platform/linuxbsd/detect.py Outdated Show resolved Hide resolved
platform/linuxbsd/detect.py Outdated Show resolved Hide resolved
@akien-mga akien-mga force-pushed the scons-refactor-lto branch 2 times, most recently from 37d3975 to 4ea9d22 Compare July 22, 2022 09:48
@akien-mga akien-mga requested a review from a team as a code owner July 22, 2022 09:48
@akien-mga
Copy link
Member Author

Added code to enable LTO on Android too. I have yet to test it and see how it works (and notably if that slows down custom build exports like it does for iOS, or if it doesn't need relinking but only packaging).

@akien-mga akien-mga removed the cherrypick:3.x Considered for cherry-picking into a future 3.x release label Jul 22, 2022
@akien-mga akien-mga marked this pull request as draft July 22, 2022 11:43
@akien-mga
Copy link
Member Author

Added code to enable LTO on Android too. I have yet to test it and see how it works (and notably if that slows down custom build exports like it does for iOS, or if it doesn't need relinking but only packaging).

Tested -flto=full on Android (default with production=yes as of this PR) and it's egregiously slow, more than 25 minutes to link a single binary (Clang -flto=full is sadly single threaded unlike GCC's). On the other hand -flto=thin seems much faster and utilizes all available threads (just a couple of minutes).

I'll rework this PR so that production=yes defaults to thin LTO for LLVM and full for GCC/MSVC.

@akien-mga akien-mga force-pushed the scons-refactor-lto branch 2 times, most recently from 2ba0b03 to a39fb89 Compare July 22, 2022 13:25
SConstruct Outdated
env["tests"] = methods.get_cmdline_bool("tests", True)
if env["production"]:
env["use_static_cpp"] = methods.get_cmdline_bool("use_static_cpp", True)
env["lto"] = ARGUMENTS.get("lto", "thin" if (methods.using_clang(env) or methods.using_emcc(env)) else "full")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to move the block after parsing the platform configure so that methods.using_clang(env) or methods.using_emcc(env) works (on Linux/Windows it depends on handling use_llvm=yes in configure).

As a side note, we really need better code to handle knowing which toolchain we're using.

@akien-mga
Copy link
Member Author

I'll rework this PR so that production=yes defaults to thin LTO for LLVM and full for GCC/MSVC.

Did so, I could test that it works as intended for:

  • Linux GCC and Clang
  • Windows GCC and Clang, cross-compiling from Linux
  • JavaScript
  • Android

Don't have the setup to check iOS, macOS and MSVC right now.

@akien-mga akien-mga force-pushed the scons-refactor-lto branch 2 times, most recently from 012bc72 to 93ff597 Compare September 5, 2022 12:27
@akien-mga akien-mga marked this pull request as ready for review September 5, 2022 12:28
@akien-mga
Copy link
Member Author

akien-mga commented Sep 5, 2022

I reworked this PR to use more conservative defaults:

  • production=yes defaults to lto=full. @Faless tested for the Web platform and "full" LTO builds are significantly smaller than "thin" LTO ones (see Web: Refactor build script to run in parallel with full LTO godot-build-scripts#66), and size matters for the Web platform so we should still default to full. Thin LTO can still be enabled with lto=thin, including to supersede the default from production=yes.
  • Since @bruvzg got unsatisfactory results for LTO on macOS, I disabled it by default (so production=yes won't enable LTO on macOS). Likewise I kept it disabled by default for iOS (makes linking too slow on export) and Android (not tested enough to know if it's good).

Adds support for LTO on macOS and Android. We don't have much experience
with LTO on these platforms so for now we keep it disabled by default
even when `production=yes` is set.

Similarly for iOS where we ship object files for the user to link in
Xcode so LTO makes builds extremely slow to link.

`production=yes` defaults to full LTO.
ThinLTO is much faster for LLVM-based compilers but seems to produce
bigger binaries (at least for the Web platform).
@akien-mga akien-mga merged commit 8b79a19 into godotengine:master Sep 8, 2022
@akien-mga akien-mga deleted the scons-refactor-lto branch September 8, 2022 09:24
akien-mga added a commit to akien-mga/godot that referenced this pull request Sep 13, 2022
akien-mga added a commit to akien-mga/godot that referenced this pull request Sep 13, 2022
Fixup to godotengine#63288.
See godotengine#65583 for the bug report.

Co-authored-by: Cyberrebell <chainsaw75@web.de>
akien-mga added a commit to akien-mga/godot that referenced this pull request Sep 19, 2022
…faults

Fixup to godotengine#63288.
See godotengine#65583 for the bug report.

Co-authored-by: Cyberrebell <chainsaw75@web.de>
akien-mga added a commit to akien-mga/godot that referenced this pull request Sep 20, 2022
…faults

Fixup to godotengine#63288.
See godotengine#65583 for the bug report.

Co-authored-by: Cyberrebell <chainsaw75@web.de>
(cherry picked from commit 35a15e6)
akien-mga added a commit to akien-mga/godot that referenced this pull request Sep 20, 2022
…faults

Fixup to godotengine#63288.
See godotengine#65583 for the bug report.

Co-authored-by: Cyberrebell <chainsaw75@web.de>
(cherry picked from commit 35a15e6)
Fran6nd pushed a commit to Fran6nd/godot that referenced this pull request Sep 20, 2022
…faults

Fixup to godotengine#63288.
See godotengine#65583 for the bug report.

Co-authored-by: Cyberrebell <chainsaw75@web.de>
volokh0x pushed a commit to volokh0x/godot that referenced this pull request Sep 23, 2022
…faults

Fixup to godotengine#63288.
See godotengine#65583 for the bug report.

Co-authored-by: Cyberrebell <chainsaw75@web.de>
schme pushed a commit to schme/godot that referenced this pull request Sep 24, 2022
…faults

Fixup to godotengine#63288.
See godotengine#65583 for the bug report.

Co-authored-by: Cyberrebell <chainsaw75@web.de>
Riordan-DC pushed a commit to Riordan-DC/godot that referenced this pull request Jan 23, 2023
…faults

Fixup to godotengine#63288.
See godotengine#65583 for the bug report.

Co-authored-by: Cyberrebell <chainsaw75@web.de>
(cherry picked from commit 35a15e6)
Riordan-DC pushed a commit to Riordan-DC/godot that referenced this pull request Jan 24, 2023
…faults

Fixup to godotengine#63288.
See godotengine#65583 for the bug report.

Co-authored-by: Cyberrebell <chainsaw75@web.de>
(cherry picked from commit 35a15e6)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants