diff --git a/CMakeLists.txt b/CMakeLists.txt index 5bfcfc321ce..de28d19c101 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/cache.cpp b/driver/cache.cpp index 8c6931074f9..9f2adf15d64 100644 --- a/driver/cache.cpp +++ b/driver/cache.cpp @@ -312,7 +312,13 @@ void outputIR2ObjRelevantCmdlineArgs(llvm::raw_ostream &hash_os) { #else hash_os << opts::getRelocModel(); #endif +#if LDC_LLVM_VER >= 600 + const auto codeModel = opts::getCodeModel(); + if (codeModel.hasValue()) + hash_os << codeModel.getValue(); +#else hash_os << opts::getCodeModel(); +#endif hash_os << opts::disableFPElim(); } diff --git a/driver/cl_options-llvm.cpp b/driver/cl_options-llvm.cpp index 90b9e1c8fd1..feabbf2929b 100644 --- a/driver/cl_options-llvm.cpp +++ b/driver/cl_options-llvm.cpp @@ -33,7 +33,11 @@ Optional getRelocModel() { return ::getRelocModel(); } Reloc::Model getRelocModel() { return ::RelocModel; } #endif +#if LDC_LLVM_VER >= 600 +Optional getCodeModel() { return ::getCodeModel(); } +#else CodeModel::Model getCodeModel() { return ::CMModel; } +#endif cl::boolOrDefault disableFPElim() { return ::DisableFPElim.getNumOccurrences() == 0 @@ -67,6 +71,12 @@ TargetOptions InitTargetOptionsFromCodeGenFlags() { return ::InitTargetOptionsFromCodeGenFlags(); } -CodeModel::Model GetCodeModelFromCMModel() { return CMModel; } +#if LDC_LLVM_VER >= 600 +Optional GetCodeModelFromCMModel() { + return ::getCodeModel(); +} +#else +CodeModel::Model GetCodeModelFromCMModel() { return ::CMModel; } +#endif } #endif // LDC_WITH_LLD && LDC_LLVM_VER >= 500 diff --git a/driver/cl_options-llvm.h b/driver/cl_options-llvm.h index d17101c2b39..9d6214882be 100644 --- a/driver/cl_options-llvm.h +++ b/driver/cl_options-llvm.h @@ -23,7 +23,11 @@ llvm::Optional getRelocModel(); #else llvm::Reloc::Model getRelocModel(); #endif +#if LDC_LLVM_VER >= 600 +llvm::Optional getCodeModel(); +#else llvm::CodeModel::Model getCodeModel(); +#endif llvm::cl::boolOrDefault disableFPElim(); bool disableRedZone(); bool printTargetFeaturesHelp(); diff --git a/driver/linker-gcc.cpp b/driver/linker-gcc.cpp index e8e28044ef6..c7df14fc105 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/driver/targetmachine.cpp b/driver/targetmachine.cpp index 70a09127c21..25949deb45f 100644 --- a/driver/targetmachine.cpp +++ b/driver/targetmachine.cpp @@ -351,7 +351,11 @@ createTargetMachine(const std::string targetTriple, const std::string arch, #else llvm::Reloc::Model relocModel, #endif - const llvm::CodeModel::Model codeModel, +#if LDC_LLVM_VER >= 600 + llvm::Optional codeModel, +#else + llvm::CodeModel::Model codeModel, +#endif const llvm::CodeGenOpt::Level codeGenOptLevel, const bool noLinkerStripDead) { // Determine target triple. If the user didn't explicitly specify one, use @@ -513,7 +517,7 @@ createTargetMachine(const std::string targetTriple, const std::string arch, } return target->createTargetMachine(triple.str(), cpu, finalFeaturesString, - targetOptions, relocModel, opts::getCodeModel(), + targetOptions, relocModel, codeModel, codeGenOptLevel); } diff --git a/driver/targetmachine.h b/driver/targetmachine.h index 6033694b68a..2de1d777783 100644 --- a/driver/targetmachine.h +++ b/driver/targetmachine.h @@ -62,7 +62,11 @@ createTargetMachine(std::string targetTriple, std::string arch, std::string cpu, #else llvm::Reloc::Model relocModel, #endif +#if LDC_LLVM_VER >= 600 + llvm::Optional codeModel, +#else llvm::CodeModel::Model codeModel, +#endif llvm::CodeGenOpt::Level codeGenOptLevel, bool noLinkerStripDead); diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index e88ffe6781b..873e6e95ada 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()