mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-04 17:11:44 +03:00
Integrate LLD for MSVC targets via experimental CMake option LDC_WITH_LLD
Results in a 7.5% bigger RelWithDebInfo ldc2.exe on Win64 with LLVM 3.9.1. LLD is currently enforced when building with LDC_WITH_LLD=ON. And LLD still doesn't support debuginfo (.pdb) generation for MSVC targets.
This commit is contained in:
parent
ede23642ef
commit
00d5f9b5b5
5 changed files with 62 additions and 32 deletions
|
@ -80,10 +80,12 @@ set(CONF_INST_DIR ${SYSCONF_INSTALL_DIR} CACHE PATH "Directory ldc.conf is insta
|
||||||
# Note: LIB_SUFFIX should perhaps be renamed to LDC_LIBDIR_SUFFIX.
|
# Note: LIB_SUFFIX should perhaps be renamed to LDC_LIBDIR_SUFFIX.
|
||||||
set(LIB_SUFFIX "" CACHE STRING "Appended to the library installation directory. Set to '64' to install libraries into ${PREFIX}/lib64.")
|
set(LIB_SUFFIX "" CACHE STRING "Appended to the library installation directory. Set to '64' to install libraries into ${PREFIX}/lib64.")
|
||||||
|
|
||||||
# The following flags are currently not well tested, expect the build to fail.
|
# The following flag is currently not well tested, expect the build to fail.
|
||||||
option(GENERATE_OFFTI "generate complete ClassInfo.offTi arrays")
|
option(GENERATE_OFFTI "generate complete ClassInfo.offTi arrays")
|
||||||
mark_as_advanced(GENERATE_OFFTI)
|
mark_as_advanced(GENERATE_OFFTI)
|
||||||
|
|
||||||
|
option(LDC_WITH_LLD "Integrate LLD, the LLVM cross-linker")
|
||||||
|
|
||||||
if(D_VERSION EQUAL 1)
|
if(D_VERSION EQUAL 1)
|
||||||
message(FATAL_ERROR "D version 1 is no longer supported.
|
message(FATAL_ERROR "D version 1 is no longer supported.
|
||||||
Please consider using D version 2 or checkout the 'd1' git branch for the last version supporting D version 1.")
|
Please consider using D version 2 or checkout the 'd1' git branch for the last version supporting D version 1.")
|
||||||
|
@ -428,8 +430,6 @@ include_directories( SYSTEM
|
||||||
)
|
)
|
||||||
append("-I${PROJECT_SOURCE_DIR}" DDMD_DFLAGS)
|
append("-I${PROJECT_SOURCE_DIR}" DDMD_DFLAGS)
|
||||||
append("-I${PROJECT_BINARY_DIR}" DDMD_DFLAGS)
|
append("-I${PROJECT_BINARY_DIR}" DDMD_DFLAGS)
|
||||||
|
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
include_directories(${PROJECT_SOURCE_DIR}/vcbuild)
|
include_directories(${PROJECT_SOURCE_DIR}/vcbuild)
|
||||||
endif()
|
endif()
|
||||||
|
@ -448,6 +448,10 @@ if(GENERATE_OFFTI)
|
||||||
append("-DGENERATE_OFFTI" LDC_CXXFLAGS)
|
append("-DGENERATE_OFFTI" LDC_CXXFLAGS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(LDC_WITH_LLD)
|
||||||
|
append("-DLDC_WITH_LLD" LDC_CXXFLAGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
option(RISCV_LLVM_DEV, "full RISC-V support with riscv-llvm")
|
option(RISCV_LLVM_DEV, "full RISC-V support with riscv-llvm")
|
||||||
mark_as_advanced(RISCV_LLVM_DEV)
|
mark_as_advanced(RISCV_LLVM_DEV)
|
||||||
|
|
||||||
|
@ -548,6 +552,13 @@ 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
|
# Figure out how to link the main LDC executable, for which we need to take the
|
||||||
# LLVM flags into account.
|
# 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)
|
||||||
|
if(MSVC)
|
||||||
|
list(APPEND LDC_LINKERFLAG_LIST lldCOFF.lib lldCore.lib lldDriver.lib)
|
||||||
|
else()
|
||||||
|
set(LDC_LINKERFLAG_LIST "-llldCOFF;-llldCore;-llldDriver;${LDC_LINKERFLAG_LIST}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
set(LDC_LINK_MANUALLY OFF)
|
set(LDC_LINK_MANUALLY OFF)
|
||||||
if(UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")))
|
if(UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")))
|
||||||
|
|
|
@ -362,19 +362,7 @@ int createStaticLibrary() {
|
||||||
|
|
||||||
#if LDC_LLVM_VER >= 309
|
#if LDC_LLVM_VER >= 309
|
||||||
if (useInternalArchiver) {
|
if (useInternalArchiver) {
|
||||||
std::vector<const char *> fullArgs;
|
const auto fullArgs = getFullArgs(tool, args, global.params.verbose);
|
||||||
fullArgs.reserve(1 + args.size());
|
|
||||||
fullArgs.push_back(tool.c_str());
|
|
||||||
for (const auto &arg : args)
|
|
||||||
fullArgs.push_back(arg.c_str());
|
|
||||||
|
|
||||||
if (global.params.verbose) {
|
|
||||||
for (auto arg : fullArgs) {
|
|
||||||
fprintf(global.stdmsg, "%s ", arg);
|
|
||||||
}
|
|
||||||
fprintf(global.stdmsg, "\n");
|
|
||||||
fflush(global.stdmsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int exitCode =
|
const int exitCode =
|
||||||
isTargetMSVC ? internalLib(fullArgs) : internalAr(fullArgs);
|
isTargetMSVC ? internalLib(fullArgs) : internalAr(fullArgs);
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
#include "driver/tool.h"
|
#include "driver/tool.h"
|
||||||
#include "gen/logger.h"
|
#include "gen/logger.h"
|
||||||
|
|
||||||
|
#if LDC_WITH_LLD
|
||||||
|
#include "lld/Driver/Driver.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static llvm::cl::opt<std::string> mscrtlib(
|
static llvm::cl::opt<std::string> mscrtlib(
|
||||||
|
@ -160,6 +164,20 @@ int linkObjToBinaryMSVC(llvm::StringRef outputPath,
|
||||||
}
|
}
|
||||||
logstr << "\n"; // FIXME where's flush ?
|
logstr << "\n"; // FIXME where's flush ?
|
||||||
|
|
||||||
|
#if LDC_WITH_LLD
|
||||||
|
const bool useInternalLinker = true; // TODO
|
||||||
|
if (useInternalLinker) {
|
||||||
|
const auto fullArgs =
|
||||||
|
getFullArgs("lld-link.exe", args, global.params.verbose);
|
||||||
|
|
||||||
|
const bool success = lld::coff::link(fullArgs);
|
||||||
|
if (!success)
|
||||||
|
error(Loc(), "linking with LLD failed");
|
||||||
|
|
||||||
|
return success ? 0 : 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// try to call linker
|
// try to call linker
|
||||||
return executeToolAndWait(tool, args, global.params.verbose);
|
return executeToolAndWait(tool, args, global.params.verbose);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,30 @@ void createDirectoryForFileOrFail(llvm::StringRef fileName) {
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::vector<const char *> getFullArgs(const std::string &tool,
|
||||||
|
const std::vector<std::string> &args,
|
||||||
|
bool printVerbose) {
|
||||||
|
std::vector<const char *> fullArgs;
|
||||||
|
fullArgs.reserve(args.size() +
|
||||||
|
2); // executeToolAndWait() appends an additional null
|
||||||
|
|
||||||
|
fullArgs.push_back(tool.c_str());
|
||||||
|
for (const auto &arg : args)
|
||||||
|
fullArgs.push_back(arg.c_str());
|
||||||
|
|
||||||
|
// Print command line if requested
|
||||||
|
if (printVerbose) {
|
||||||
|
for (auto arg : fullArgs)
|
||||||
|
fprintf(global.stdmsg, "%s ", arg);
|
||||||
|
fprintf(global.stdmsg, "\n");
|
||||||
|
fflush(global.stdmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
int executeToolAndWait(const std::string &tool_,
|
int executeToolAndWait(const std::string &tool_,
|
||||||
std::vector<std::string> const &args, bool verbose) {
|
std::vector<std::string> const &args, bool verbose) {
|
||||||
const auto tool = findProgramByName(tool_);
|
const auto tool = findProgramByName(tool_);
|
||||||
|
@ -99,24 +123,9 @@ int executeToolAndWait(const std::string &tool_,
|
||||||
|
|
||||||
// Construct real argument list.
|
// Construct real argument list.
|
||||||
// First entry is the tool itself, last entry must be NULL.
|
// First entry is the tool itself, last entry must be NULL.
|
||||||
std::vector<const char *> realargs;
|
auto realargs = getFullArgs(tool, args, verbose);
|
||||||
realargs.reserve(args.size() + 2);
|
|
||||||
realargs.push_back(tool.c_str());
|
|
||||||
for (const auto &arg : args) {
|
|
||||||
realargs.push_back(arg.c_str());
|
|
||||||
}
|
|
||||||
realargs.push_back(nullptr);
|
realargs.push_back(nullptr);
|
||||||
|
|
||||||
// Print command line if requested
|
|
||||||
if (verbose) {
|
|
||||||
// Print it
|
|
||||||
for (size_t i = 0; i < realargs.size() - 1; i++) {
|
|
||||||
fprintf(global.stdmsg, "%s ", realargs[i]);
|
|
||||||
}
|
|
||||||
fprintf(global.stdmsg, "\n");
|
|
||||||
fflush(global.stdmsg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute tool.
|
// Execute tool.
|
||||||
std::string errstr;
|
std::string errstr;
|
||||||
if (int status = llvm::sys::ExecuteAndWait(tool, &realargs[0], nullptr,
|
if (int status = llvm::sys::ExecuteAndWait(tool, &realargs[0], nullptr,
|
||||||
|
|
|
@ -28,6 +28,10 @@ std::string getProgram(const char *name,
|
||||||
|
|
||||||
void createDirectoryForFileOrFail(llvm::StringRef fileName);
|
void createDirectoryForFileOrFail(llvm::StringRef fileName);
|
||||||
|
|
||||||
|
std::vector<const char *> getFullArgs(const std::string &tool,
|
||||||
|
const std::vector<std::string> &args,
|
||||||
|
bool printVerbose);
|
||||||
|
|
||||||
int executeToolAndWait(const std::string &tool,
|
int executeToolAndWait(const std::string &tool,
|
||||||
std::vector<std::string> const &args,
|
std::vector<std::string> const &args,
|
||||||
bool verbose = false);
|
bool verbose = false);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue