Skip to content

Commit

Permalink
Fix LTO on newer macOS. (ldc-developers#4548)
Browse files Browse the repository at this point in the history
The trouble was that the libLTO-ldc.dylib was not used by ld64, even though it is explicitly passed using -lto_library. Somehow the library renaming (adding "-ldc" postfix) is not working properly. I did not figure out how to fix it (the usual install-name-tool and resigning did not work), the only fix that worked is to not rename it at all.
This bug went unnoticed because at -O0, there is no LTO object file output at all; hence the -O3 addition to the thinlto testcase.
  • Loading branch information
JohanEngelen authored Dec 27, 2023
1 parent dc393dc commit 2c2c550
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 18 deletions.
35 changes: 20 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -753,6 +753,23 @@ function(copy_and_rename_file source_path target_path)
file(RENAME ${target_dir}/${source_name} ${target_path})
endfunction()


function(copy_and_install_llvm_library llvm_lib_path ldc_lib_name fixup_dylib)
set(ldc_lib_path ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}/${ldc_lib_name})
copy_and_rename_file(${llvm_lib_path} ${ldc_lib_path})
if (APPLE AND fixup_dylib)
execute_process(COMMAND install_name_tool -id @rpath/${ldc_lib_name} ${ldc_lib_path} ERROR_VARIABLE INSTALL_NAME_TOOL_STDERR)
if(${INSTALL_NAME_TOOL_STDERR} MATCHES "warning: changes being made to the file will invalidate the code signature")
# Eat the warning, it's ok.
elseif("${INSTALL_NAME_TOOL_STDERR}" STREQUAL "")
else()
message(WARNING "install_name_tool stderr: ${INSTALL_NAME_TOOL_STDERR}")
endif()
execute_process(COMMAND codesign --force -s - ${ldc_lib_path})
endif()
install(FILES ${ldc_lib_path} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
endfunction()

#
# Locate LLVM's LTO binary and use it
#
Expand All @@ -765,15 +782,14 @@ set(LDC_INSTALL_LTOPLUGIN ${LDC_INSTALL_LTOPLUGIN_DEFAULT} CACHE BOOL "Copy/inst
if (LDC_INSTALL_LTOPLUGIN)
if(APPLE)
set(LLVM_LTO_BINARY ${LLVM_LIBRARY_DIRS}/libLTO.dylib)
set(LDC_LTO_BINARY_NAME libLTO-ldc.dylib)
set(LDC_LTO_BINARY_NAME libLTO.dylib)
elseif(UNIX)
set(LLVM_LTO_BINARY ${LLVM_LIBRARY_DIRS}/LLVMgold.so)
set(LDC_LTO_BINARY_NAME LLVMgold-ldc.so)
endif()
if(EXISTS ${LLVM_LTO_BINARY})
message(STATUS "-- Including LTO linker plugin (LDC_INSTALL_LTOPLUGIN): ON (${LLVM_LTO_BINARY})")
copy_and_rename_file(${LLVM_LTO_BINARY} ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}/${LDC_LTO_BINARY_NAME})
install(PROGRAMS ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}/${LDC_LTO_BINARY_NAME} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
copy_and_install_llvm_library(${LLVM_LTO_BINARY} ${LDC_LTO_BINARY_NAME} TRUE)
else()
message(STATUS "-- Including LTO linker plugin (LDC_INSTALL_LTOPLUGIN): OFF (cannot find ${LLVM_LTO_BINARY})")
endif()
Expand All @@ -799,18 +815,7 @@ function(copy_compilerrt_lib llvm_lib_name ldc_lib_name fixup_dylib)
endif()
if(EXISTS ${llvm_lib_path})
message(STATUS "-- - ${llvm_lib_path} --> ${ldc_lib_name}")
set(ldc_lib_path ${PROJECT_BINARY_DIR}/lib${LIB_SUFFIX}/${ldc_lib_name})
copy_and_rename_file(${llvm_lib_path} ${ldc_lib_path})
if (fixup_dylib)
execute_process(COMMAND install_name_tool -id @rpath/${ldc_lib_name} ${ldc_lib_path} ERROR_VARIABLE INSTALL_NAME_TOOL_STDERR)
if(${INSTALL_NAME_TOOL_STDERR} MATCHES "warning: changes being made to the file will invalidate the code signature")
# Eat the warning, it's ok.
else()
message(WARNING "install_name_tool stderr: ${INSTALL_NAME_TOOL_STDERR}")
endif()
execute_process(COMMAND codesign --force -s - ${ldc_lib_path})
endif()
install(FILES ${ldc_lib_path} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
copy_and_install_llvm_library(${llvm_lib_path} ${ldc_lib_name} ${fixup_dylib})
else()
message(STATUS "-- - not found: ${llvm_lib_path}")
endif()
Expand Down
4 changes: 2 additions & 2 deletions driver/linker-gcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ std::string getLTOdylibPath() {
error(Loc(), "-flto-binary: '%s' not found", ltoLibrary.c_str());
fatal();
} else {
// The plugin packaged with LDC has a "-ldc" suffix.
std::string searchPath = exe_path::prependLibDir("libLTO-ldc.dylib");
// Give priority to the plugin packaged with LDC.
std::string searchPath = exe_path::prependLibDir("libLTO.dylib");
if (llvm::sys::fs::exists(searchPath))
return searchPath;

Expand Down
2 changes: 1 addition & 1 deletion tests/linking/thinlto_1.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// REQUIRES: LTO

// RUN: %ldc %s -of=%t%obj -c -flto=thin -vv | FileCheck %s
// RUN: %ldc -flto=thin -run %s
// RUN: %ldc -flto=thin -O3 -run %s

// CHECK: Writing LLVM bitcode
// CHECK: Creating module summary for ThinLTO
Expand Down

0 comments on commit 2c2c550

Please sign in to comment.