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

Integrate LLD for MSVC targets; prepare for other targets #2142

Merged
merged 10 commits into from
Jun 4, 2017
37 changes: 32 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules")

include(FindDCompiler)
include(CheckIncludeFile)
include(CheckIncludeFileCXX)
include(CheckLibraryExists)
include(CheckCXXCompilerFlag)
include(CheckDSourceCompiles)
Expand Down Expand Up @@ -80,7 +81,7 @@ 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.
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")
mark_as_advanced(GENERATE_OFFTI)

Expand Down Expand Up @@ -342,6 +343,8 @@ set(DRV_SRC
driver/tool.cpp
driver/archiver.cpp
driver/linker.cpp
driver/linker-gcc.cpp
driver/linker-msvc.cpp
driver/main.cpp
${CMAKE_BINARY_DIR}/driver/ldc-version.cpp
)
Expand Down Expand Up @@ -426,8 +429,6 @@ include_directories( SYSTEM
)
append("-I${PROJECT_SOURCE_DIR}" DDMD_DFLAGS)
append("-I${PROJECT_BINARY_DIR}" DDMD_DFLAGS)


if(MSVC)
include_directories(${PROJECT_SOURCE_DIR}/vcbuild)
endif()
Expand All @@ -446,12 +447,31 @@ if(GENERATE_OFFTI)
append("-DGENERATE_OFFTI" LDC_CXXFLAGS)
endif()

option(RISCV_LLVM_DEV, "full RISC-V support with riscv-llvm")
mark_as_advanced(RISCV_LLVM_DEV)
#
# LLD integration (requires LLVM >= 3.9 with LLD headers & libs)
#
set(LDC_WITH_LLD OFF)
if(LDC_LLVM_VER GREATER 308)
# check for LLD header
unset(LDC_WITH_LLD)
if(NOT MSVC)
set(CMAKE_REQUIRED_FLAGS -std=c++11)
endif()
set(CMAKE_REQUIRED_INCLUDES ${LLVM_INCLUDE_DIRS})
CHECK_INCLUDE_FILE_CXX(lld/Driver/Driver.h LDC_WITH_LLD)
unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_INCLUDES)
if(LDC_WITH_LLD)
message(STATUS "Building LDC with LLD support")
append("-DLDC_WITH_LLD" LDC_CXXFLAGS)
endif()
endif()

#
# Enable building with riscv-llvm, for full RISC-V support.
#
option(RISCV_LLVM_DEV, "full RISC-V support with riscv-llvm")
mark_as_advanced(RISCV_LLVM_DEV)
if(RISCV_LLVM_DEV)
append("-DRISCV_LLVM_DEV" LDC_CXXFLAGS)
endif()
Expand Down Expand Up @@ -546,6 +566,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
# LLVM flags into account.
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}")
Copy link
Member

Choose a reason for hiding this comment

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

Is there an equivalent of llvm-config for this?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not that I've seen, in fact I didn't find anything about how to embed LLD via CMake. On Linux the order matters (even inbetween these 3 new libs), so I put them in front. As the LLD libs don't have the LLVM prefix, we can't specify them in find_package()...

endif()
endif()

set(LDC_LINK_MANUALLY OFF)
if(UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")))
Expand Down
3 changes: 2 additions & 1 deletion ddmd/mars.d
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,10 @@ version(IN_LLVM)
// in driver/main.cpp
void addDefaultVersionIdentifiers();
void codegenModules(ref Modules modules);
// in driver/archiver.cpp
int createStaticLibrary();
// in driver/linker.cpp
int linkObjToBinary();
int createStaticLibrary();
void deleteExeFile();
int runProgram();
}
Expand Down
140 changes: 122 additions & 18 deletions driver/archiver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@
// License. See LLVM LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Builds up (relatively) standard unix archive files (.a) containing LLVM
// bitcode or other files.
//
//===----------------------------------------------------------------------===//

#if LDC_LLVM_VER >= 309
#include "errors.h"
#include "globals.h"
#include "driver/cl_options.h"
#include "driver/tool.h"
#include "gen/logger.h"
#include "llvm/ADT/Triple.h"

#include "driver/archiver.h"
#if LDC_LLVM_VER >= 309

#include "llvm/ADT/Triple.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ArchiveWriter.h"
#include "llvm/Object/MachO.h"
Expand All @@ -42,7 +41,7 @@ using namespace llvm;
* support for `llvm-ar rcs <archive name> <member> ...`.
* It also makes sure the process isn't simply exited whenever a problem arises.
*/
namespace {
namespace llvm_ar {

StringRef ArchiveName;
std::vector<const char *> Members;
Expand Down Expand Up @@ -237,13 +236,13 @@ int performWriteOperation() {
return performWriteOperation(nullptr, nullptr);
}

} // anonymous namespace
} // namespace llvm_ar

////////////////////////////////////////////////////////////////////////////////

namespace ldc {
namespace {

int ar(ArrayRef<const char *> args) {
int internalAr(ArrayRef<const char *> args) {
if (args.size() < 4 || strcmp(args[0], "llvm-ar") != 0 ||
strcmp(args[1], "rcs") != 0) {
llvm_unreachable(
Expand All @@ -252,16 +251,17 @@ int ar(ArrayRef<const char *> args) {
return -1;
}

ArchiveName = args[2];
llvm_ar::ArchiveName = args[2];

auto membersSlice = args.slice(3);
Members.clear();
Members.insert(Members.end(), membersSlice.begin(), membersSlice.end());
llvm_ar::Members.clear();
llvm_ar::Members.insert(llvm_ar::Members.end(), membersSlice.begin(),
membersSlice.end());

return performWriteOperation();
return llvm_ar::performWriteOperation();
}

int lib(ArrayRef<const char *> args) {
int internalLib(ArrayRef<const char *> args) {
if (args.size() < 1 || strcmp(args[0], "llvm-lib.exe") != 0) {
llvm_unreachable("Expected archiver command line: llvm-lib.exe ...");
return -1;
Expand All @@ -270,6 +270,110 @@ int lib(ArrayRef<const char *> args) {
return libDriverMain(args);
}

} // namespace ldc
} // anonymous namespace

#endif // LDC_LLVM_VER >= 309

////////////////////////////////////////////////////////////////////////////////

static llvm::cl::opt<std::string> ar("ar", llvm::cl::desc("Archiver"),
llvm::cl::Hidden, llvm::cl::ZeroOrMore);

int createStaticLibrary() {
Logger::println("*** Creating static library ***");

const bool isTargetMSVC =
global.params.targetTriple->isWindowsMSVCEnvironment();

#if LDC_LLVM_VER >= 309
const bool useInternalArchiver = ar.empty();
#else
const bool useInternalArchiver = false;
#endif

// find archiver
std::string tool;
if (useInternalArchiver) {
tool = isTargetMSVC ? "llvm-lib.exe" : "llvm-ar";
} else {
#ifdef _WIN32
if (isTargetMSVC)
windows::setupMsvcEnvironment();
#endif

tool = getProgram(isTargetMSVC ? "lib.exe" : "ar", &ar);
}

// build arguments
std::vector<std::string> args;

// ask ar to create a new library
if (!isTargetMSVC) {
args.push_back("rcs");
}

// ask lib.exe to be quiet
if (isTargetMSVC) {
args.push_back("/NOLOGO");
}

// output filename
std::string libName;
if (global.params.libname) { // explicit
// DMD adds the default extension if there is none
libName = opts::invokedByLDMD
? FileName::defaultExt(global.params.libname, global.lib_ext)
: global.params.libname;
} else { // infer from first object file
libName = global.params.objfiles->dim
? FileName::removeExt((*global.params.objfiles)[0])
: "a.out";
libName += '.';
libName += global.lib_ext;
}

// DMD creates static libraries in the objects directory (unless using an
// absolute output path via `-of`).
if (opts::invokedByLDMD && global.params.objdir &&
!FileName::absolute(libName.c_str())) {
libName = FileName::combine(global.params.objdir, libName.c_str());
}

if (isTargetMSVC) {
args.push_back("/OUT:" + libName);
} else {
args.push_back(libName);
}

// object files
for (auto objfile : *global.params.objfiles) {
args.push_back(objfile);
}

// .res/.def files for lib.exe
if (isTargetMSVC) {
if (global.params.resfile)
args.push_back(global.params.resfile);
if (global.params.deffile)
args.push_back(std::string("/DEF:") + global.params.deffile);
}

// create path to the library
createDirectoryForFileOrFail(libName);

#if LDC_LLVM_VER >= 309
if (useInternalArchiver) {
const auto fullArgs = getFullArgs(tool, args, global.params.verbose);

const int exitCode =
isTargetMSVC ? internalLib(fullArgs) : internalAr(fullArgs);
if (exitCode)
error(Loc(), "%s failed with status: %d", tool.c_str(), exitCode);

return exitCode;
}
#endif

// invoke external archiver
return executeToolAndWait(tool, args, global.params.verbose);
}
20 changes: 6 additions & 14 deletions driver/archiver.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
//===-- driver/archiver.h - Creating static libs via LLVM--------*- C++ -*-===//
//===-- driver/archiver.h - Creating static libraries -----------*- C++ -*-===//
//
// LDC � the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
//
// Provides an interface to LLVM built-in static lib generation via llvm-lib
// (MSVC targets) or llvm-ar (all other targets).
//
//===----------------------------------------------------------------------===//

#ifndef LDC_DRIVER_ARCHIVER_H
#define LDC_DRIVER_ARCHIVER_H

#if LDC_LLVM_VER >= 309
#include "llvm/ADT/ArrayRef.h"

namespace ldc {
int ar(llvm::ArrayRef<const char *> args);
int lib(llvm::ArrayRef<const char *> args);
}
#endif // LDC_LLVM_VER >= 309
/**
* Create a static library from object files.
* @return 0 on success.
*/
int createStaticLibrary();

#endif // !LDC_DRIVER_ARCHIVER_H
Loading