diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bfcfc321c..de28d19c10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -449,14 +449,20 @@ if(NOT DEFINED LDC_WITH_LLD) endif() unset(CMAKE_REQUIRED_FLAGS) unset(CMAKE_REQUIRED_INCLUDES) + # translate 1/0 to ON/OFF + if(LDC_WITH_LLD) + set(LDC_WITH_LLD ON) + else() + set(LDC_WITH_LLD OFF) + endif() else() set(LDC_WITH_LLD OFF) endif() endif() if(LDC_WITH_LLD) - message(STATUS "Building LDC with LLD support") append("-DLDC_WITH_LLD" LDC_CXXFLAGS) endif() +message(STATUS "Building LDC with integrated LLD: ${LDC_WITH_LLD} (LDC_WITH_LLD=${LDC_WITH_LLD})") # # Enable building with riscv-llvm, for full RISC-V support. @@ -560,21 +566,23 @@ add_custom_target(${LDMD_EXE} ALL DEPENDS ${LDMD_EXE_FULL}) # Figure out how to link the main LDC executable, for which we need to take the # LLVM flags into account. -set(LDC_LINKERFLAG_LIST "${SANITIZE_LDFLAGS};${LLVM_LIBRARIES};${LLVM_LDFLAGS}") +set(LDC_LINKERFLAG_LIST ${SANITIZE_LDFLAGS} ${LLVM_LIBRARIES} ${LLVM_LDFLAGS}) if(LDC_WITH_LLD) + # ELF and Mach-O formats supported since LLD 6.0.0, otherwise just Windows COFF if(NOT (LDC_LLVM_VER LESS 600)) if(MSVC) - list(APPEND LDC_LINKERFLAG_LIST lldCOFF.lib lldCommon.lib lldCore.lib lldDriver.lib) - elseif(APPLE) - set(LDC_LINKERFLAG_LIST "-llldCOFF;-llldCommon;-llldCore;-llldDriver;${LDC_LINKERFLAG_LIST};-lxml2") + list(APPEND LDC_LINKERFLAG_LIST lldDriver.lib lldCOFF.lib lldELF.lib lldMachO.lib lldYAML.lib lldReaderWriter.lib lldCommon.lib lldCore.lib) else() - set(LDC_LINKERFLAG_LIST "-llldCOFF;-llldCommon;-llldCore;-llldDriver;${LDC_LINKERFLAG_LIST}") + set(LDC_LINKERFLAG_LIST -llldDriver -llldCOFF -llldELF -llldMachO -llldYAML -llldReaderWriter -llldCommon -llldCore ${LDC_LINKERFLAG_LIST}) + endif() + if(APPLE) # bug, should be fixed in LLVM 6.0.1 + list(APPEND LDC_LINKERFLAG_LIST -lxml2) endif() else() if(MSVC) list(APPEND LDC_LINKERFLAG_LIST lldCOFF.lib lldCore.lib lldDriver.lib) else() - set(LDC_LINKERFLAG_LIST "-llldCOFF;-llldCore;-llldDriver;${LDC_LINKERFLAG_LIST}") + set(LDC_LINKERFLAG_LIST -llldCOFF -llldCore -llldDriver ${LDC_LINKERFLAG_LIST}) endif() endif() endif() @@ -593,7 +601,7 @@ if(LDC_ENABLE_PLUGINS) set(LDC_LINKERFLAG_LIST "${LDC_LINKERFLAG_LIST};-Wl,--export-dynamic") endif() endif() -message(STATUS "Building LDC with plugin support ${LDC_ENABLE_PLUGINS} (LDC_ENABLE_PLUGINS=${LDC_ENABLE_PLUGINS})") +message(STATUS "Building LDC with plugin support: ${LDC_ENABLE_PLUGINS} (LDC_ENABLE_PLUGINS=${LDC_ENABLE_PLUGINS})") set(LDC_LINK_MANUALLY OFF) if(UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang"))) diff --git a/driver/linker-gcc.cpp b/driver/linker-gcc.cpp index e8e28044ef..c7df14fc10 100644 --- a/driver/linker-gcc.cpp +++ b/driver/linker-gcc.cpp @@ -23,6 +23,10 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" +#if LDC_WITH_LLD && LDC_LLVM_VER >= 600 +#include "lld/Common/Driver.h" +#endif + ////////////////////////////////////////////////////////////////////////////// static llvm::cl::opt @@ -594,7 +598,7 @@ void ArgsBuilder::addTargetFlags() { } ////////////////////////////////////////////////////////////////////////////// -// (Yet unused) specialization for plain ld. +// Specialization for plain ld. class LdArgsBuilder : public ArgsBuilder { void addSanitizers(const llvm::Triple &triple) override {} @@ -628,6 +632,30 @@ class LdArgsBuilder : public ArgsBuilder { int linkObjToBinaryGcc(llvm::StringRef outputPath, bool useInternalLinker, llvm::cl::boolOrDefault fullyStaticFlag) { +#if LDC_WITH_LLD && LDC_LLVM_VER >= 600 + if (useInternalLinker) { + LdArgsBuilder argsBuilder; + argsBuilder.build(outputPath, fullyStaticFlag); + + const auto fullArgs = + getFullArgs("ld.lld", argsBuilder.args, global.params.verbose); + + bool success = false; + if (global.params.targetTriple->isOSBinFormatELF()) { + success = lld::elf::link(fullArgs, /*CanExitEarly*/ false); + } else if (global.params.targetTriple->isOSBinFormatMachO()) { + success = lld::mach_o::link(fullArgs); + } else { + error(Loc(), "unknown target binary format for internal linking"); + } + + if (!success) + error(Loc(), "linking with LLD failed"); + + return success ? 0 : 1; + } +#endif + // find gcc for linking const std::string tool = getGcc(); diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index e88ffe6781..873e6e95ad 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -255,9 +255,9 @@ endif() # The installed config file doesn't use SHARED_LIBS_RPATH. if(NOT ${BUILD_SHARED_LIBS} STREQUAL "OFF") if(MULTILIB AND NOT "${TARGET_SYSTEM}" MATCHES "APPLE") - set(SHARED_LIBS_RPATH "\n \"-L-Wl,-rpath,${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}:${CMAKE_BINARY_DIR}/lib${MULTILIB_SUFFIX}\",") + set(SHARED_LIBS_RPATH "\n \"-L-rpath\", \"-L${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}:${CMAKE_BINARY_DIR}/lib${MULTILIB_SUFFIX}\",") else() - set(SHARED_LIBS_RPATH "\n \"-L-Wl,-rpath,${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}\",") + set(SHARED_LIBS_RPATH "\n \"-L-rpath\", \"-L${CMAKE_BINARY_DIR}/lib${LIB_SUFFIX}\",") endif() endif()