From 6e554c6647fc53d05c4d95d5499f9c3efc241eaf Mon Sep 17 00:00:00 2001 From: kai Date: Sun, 16 Sep 2012 00:03:27 +0200 Subject: [PATCH] Add support for MS Lib. If the target OS is Windows using the MS runtime then use LIB.EXE as the archiver. --- driver/linker.cpp | 26 +++++++++++++++++++------- driver/main.cpp | 5 +++-- gen/programs.cpp | 20 ++++++++++++++++++++ gen/programs.h | 4 ++++ 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/driver/linker.cpp b/driver/linker.cpp index 067b76d1..9ec866d9 100644 --- a/driver/linker.cpp +++ b/driver/linker.cpp @@ -1,5 +1,6 @@ #include "gen/llvm.h" #include "llvm/Linker.h" +#include "llvm/ADT/Triple.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Program.h" #if _WIN32 @@ -238,20 +239,27 @@ void createStaticLibrary() { Logger::println("*** Creating static library ***"); + const bool isTargetWindows = llvm::Triple(global.params.targetTriple).isOSWindows(); + // error string std::string errstr; // find archiver - llvm::sys::Path ar = getArchiver(); + llvm::sys::Path tool = isTargetWindows ? getLib() : getArchiver(); // build arguments std::vector args; // first the program name ?? - args.push_back(ar.c_str()); + args.push_back(tool.c_str()); // ask ar to create a new library - args.push_back("rcs"); + if (!isTargetWindows) + args.push_back("rcs"); + + // ask lib to be quiet + if (isTargetWindows) + args.push_back("/NOLOGO"); // output filename std::string libName; @@ -272,12 +280,16 @@ void createStaticLibrary() std::string libExt = std::string(".") + global.lib_ext; if (!endsWith(libName, libExt)) { - if (global.params.os != OSWindows) + if (!isTargetWindows) libName = "lib" + libName + libExt; else libName.append(libExt); } - args.push_back(libName.c_str()); + std::string outcmd = "/OUT:" + libName; + if (isTargetWindows) + args.push_back(outcmd.c_str()); + else + args.push_back(libName.c_str()); // object files for (unsigned i = 0; i < global.params.objfiles->dim; i++) @@ -287,7 +299,7 @@ void createStaticLibrary() } // create path to the library - llvm::sys::Path libdir(llvm::sys::path::parent_path(libName.c_str())); + llvm::sys::Path libdir(llvm::sys::path::parent_path(libName)); if (!libdir.empty() && !llvm::sys::fs::exists(libdir.str())) { libdir.createDirectoryOnDisk(true, &errstr); @@ -312,7 +324,7 @@ void createStaticLibrary() args.push_back(NULL); // try to call archiver - if (int status = llvm::sys::Program::ExecuteAndWait(ar, &args[0], NULL, NULL, 0,0, &errstr)) + if (int status = llvm::sys::Program::ExecuteAndWait(tool, &args[0], NULL, NULL, 0,0, &errstr)) { error("archiver failed:\nstatus: %d", status); if (!errstr.empty()) diff --git a/driver/main.cpp b/driver/main.cpp index 677a3364..f7821c26 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -780,10 +780,11 @@ int main(int argc, char** argv) { #if POSIX if (strcmp(ext, global.obj_ext) == 0 || - strcmp(ext, global.bc_ext) == 0) + strcmp(ext, global.bc_ext) == 0) #else if (stricmp(ext, global.obj_ext) == 0 || - stricmp(ext, global.bc_ext) == 0) + stricmp(ext, global.obj_ext_alt) == 0 || + stricmp(ext, global.bc_ext) == 0) #endif { global.params.objfiles->push(static_cast(files.data[i])); diff --git a/gen/programs.cpp b/gen/programs.cpp index 7fb4effe..0e8e8e24 100644 --- a/gen/programs.cpp +++ b/gen/programs.cpp @@ -18,6 +18,16 @@ static cl::opt ar("ar", cl::Hidden, cl::ZeroOrMore); +static cl::opt link("ms-link", + cl::desc("LINK to use for linking on Windows"), + cl::Hidden, + cl::ZeroOrMore); + +static cl::opt lib("ms-lib", + cl::desc("Library Manager to use on Windows"), + cl::Hidden, + cl::ZeroOrMore); + sys::Path getProgram(const char *name, const cl::opt &opt, const char *envVar = 0) { const char *prog = NULL; @@ -52,3 +62,13 @@ sys::Path getArchiver() { return getProgram("ar", ar); } + +sys::Path getLink() +{ + return getProgram("link.exe", link); +} + +sys::Path getLib() +{ + return getProgram("lib.exe", lib); +} diff --git a/gen/programs.h b/gen/programs.h index e3c9c2ee..c0cc44a6 100644 --- a/gen/programs.h +++ b/gen/programs.h @@ -6,4 +6,8 @@ llvm::sys::Path getGcc(); llvm::sys::Path getArchiver(); +// For Windows with MS tool chain +llvm::sys::Path getLink(); +llvm::sys::Path getLib(); + #endif