Enable cross-static-lib generation for LLVM 3.9+

By directly integrating LLVM's `llvm-lib.exe` driver to generate static
libs for MSVC targets and a stripped-down version of the `llvm-ar` tool
for the other targets.

Introduce command-line option `-archiver=<file>` to allow the user to
specify an external archiver to be invoked.
This commit is contained in:
Martin 2017-03-11 21:27:25 +01:00
parent c5565d7955
commit ad3294b3ae
5 changed files with 356 additions and 8 deletions

View file

@ -11,6 +11,7 @@
#include "mars.h"
#include "module.h"
#include "root.h"
#include "driver/archiver.h"
#include "driver/cl_options.h"
#include "driver/exe_path.h"
#include "driver/tool.h"
@ -51,6 +52,11 @@ static llvm::cl::opt<std::string>
"LLVMgold.so (Unixes) or libLTO.dylib (Darwin))"),
llvm::cl::value_desc("file"), llvm::cl::ZeroOrMore);
static llvm::cl::opt<std::string>
externalArchiver("archiver",
llvm::cl::desc("External static library archiver"),
llvm::cl::value_desc("file"), llvm::cl::ZeroOrMore);
//////////////////////////////////////////////////////////////////////////////
static void CreateDirectoryOnDisk(llvm::StringRef fileName) {
@ -815,8 +821,21 @@ int createStaticLibrary() {
const bool isTargetMSVC =
global.params.targetTriple->isWindowsMSVCEnvironment();
#if LDC_LLVM_VER >= 309
const bool useInternalArchiver = externalArchiver.empty();
#else
const bool useInternalArchiver = false;
#endif
// find archiver
std::string tool(isTargetMSVC ? "lib.exe" : getArchiver());
std::string tool;
if (useInternalArchiver) {
tool = isTargetMSVC ? "llvm-lib.exe" : "llvm-ar";
} else if (!externalArchiver.empty()) {
tool = externalArchiver;
} else {
tool = isTargetMSVC ? "lib.exe" : getArchiver();
}
// build arguments
std::vector<std::string> args;
@ -869,13 +888,35 @@ int createStaticLibrary() {
// create path to the library
CreateDirectoryOnDisk(libName);
// try to call archiver
int exitCode;
if (isTargetMSVC) {
exitCode = executeMsvcToolAndWait(tool, args, global.params.verbose);
} else {
exitCode = executeToolAndWait(tool, args, global.params.verbose);
#if LDC_LLVM_VER >= 309
if (useInternalArchiver) {
std::vector<const char *> fullArgs;
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 = isTargetMSVC ? ldc::lib(fullArgs) : ldc::ar(fullArgs);
if (exitCode)
error(Loc(), "%s failed with status: %d", tool.c_str(), exitCode);
return exitCode;
}
#endif
// try to call archiver
const int exitCode =
isTargetMSVC ? executeMsvcToolAndWait(tool, args, global.params.verbose)
: executeToolAndWait(tool, args, global.params.verbose);
return exitCode;
}