mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 17:43:35 +03:00
Fixed #21 — Added -lib switch
This commit is contained in:
parent
859ae8481f
commit
fdead0d154
8 changed files with 137 additions and 18 deletions
|
@ -72,7 +72,10 @@ Global::Global()
|
||||||
s_ext = "s";
|
s_ext = "s";
|
||||||
obj_ext = "o";
|
obj_ext = "o";
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
lib_ext = "lib";
|
||||||
obj_ext_alt = "obj";
|
obj_ext_alt = "obj";
|
||||||
|
#else
|
||||||
|
lib_ext = "a";
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#if TARGET_WINDOS
|
#if TARGET_WINDOS
|
||||||
|
|
|
@ -39,6 +39,10 @@ cl::opt<bool> compileOnly("c",
|
||||||
cl::desc("Do not link"),
|
cl::desc("Do not link"),
|
||||||
cl::ZeroOrMore);
|
cl::ZeroOrMore);
|
||||||
|
|
||||||
|
cl::opt<bool> createStaticLib("lib",
|
||||||
|
cl::desc("Create static library"),
|
||||||
|
cl::ZeroOrMore);
|
||||||
|
|
||||||
static cl::opt<bool, true> verbose("v",
|
static cl::opt<bool, true> verbose("v",
|
||||||
cl::desc("Verbose"),
|
cl::desc("Verbose"),
|
||||||
cl::ZeroOrMore,
|
cl::ZeroOrMore,
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace opts {
|
||||||
extern cl::list<std::string> fileList;
|
extern cl::list<std::string> fileList;
|
||||||
extern cl::list<std::string> runargs;
|
extern cl::list<std::string> runargs;
|
||||||
extern cl::opt<bool> compileOnly;
|
extern cl::opt<bool> compileOnly;
|
||||||
|
extern cl::opt<bool> createStaticLib;
|
||||||
extern cl::opt<bool> noAsm;
|
extern cl::opt<bool> noAsm;
|
||||||
extern cl::opt<bool> dontWriteObj;
|
extern cl::opt<bool> dontWriteObj;
|
||||||
extern cl::opt<std::string> objectFile;
|
extern cl::opt<std::string> objectFile;
|
||||||
|
|
|
@ -357,6 +357,92 @@ int linkObjToExecutable(const char* argv0)
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void createStaticLibrary()
|
||||||
|
{
|
||||||
|
Logger::println("*** Creating static library ***");
|
||||||
|
|
||||||
|
// error string
|
||||||
|
std::string errstr;
|
||||||
|
|
||||||
|
// find archiver
|
||||||
|
llvm::sys::Path ar = getArchiver();
|
||||||
|
|
||||||
|
// build arguments
|
||||||
|
std::vector<const char*> args;
|
||||||
|
|
||||||
|
// first the program name ??
|
||||||
|
args.push_back(ar.c_str());
|
||||||
|
|
||||||
|
// ask ar to create a new library
|
||||||
|
args.push_back("rcs");
|
||||||
|
|
||||||
|
// output filename
|
||||||
|
std::string libName;
|
||||||
|
if (global.params.objname)
|
||||||
|
{ // explicit
|
||||||
|
libName = global.params.objname;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // inferred
|
||||||
|
// try root module name
|
||||||
|
if (Module::rootModule)
|
||||||
|
libName = Module::rootModule->toChars();
|
||||||
|
else if (global.params.objfiles->dim)
|
||||||
|
libName = FileName::removeExt((char*)global.params.objfiles->data[0]);
|
||||||
|
else
|
||||||
|
libName = "a";
|
||||||
|
}
|
||||||
|
std::string libExt = std::string(".") + global.lib_ext;
|
||||||
|
if (libExt.length() > libName.length() ||
|
||||||
|
!std::equal(libExt.rbegin(), libExt.rend(), libName.rbegin()))
|
||||||
|
{
|
||||||
|
libName.append(libExt);
|
||||||
|
}
|
||||||
|
args.push_back(libName.c_str());
|
||||||
|
|
||||||
|
// object files
|
||||||
|
for (unsigned i = 0; i < global.params.objfiles->dim; i++)
|
||||||
|
{
|
||||||
|
char *p = (char *)global.params.objfiles->data[i];
|
||||||
|
args.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create path to the library
|
||||||
|
llvm::sys::Path libdir(llvm::sys::path::parent_path(libName.c_str()));
|
||||||
|
if (!libdir.empty() && !llvm::sys::fs::exists(libdir.str()))
|
||||||
|
{
|
||||||
|
libdir.createDirectoryOnDisk(true, &errstr);
|
||||||
|
if (!errstr.empty())
|
||||||
|
{
|
||||||
|
error("failed to create path to linking output: %s\n%s", libdir.c_str(), errstr.c_str());
|
||||||
|
fatal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// print the command?
|
||||||
|
if (!quiet || global.params.verbose)
|
||||||
|
{
|
||||||
|
// Print it
|
||||||
|
for (int i = 0; i < args.size(); i++)
|
||||||
|
printf("%s ", args[i]);
|
||||||
|
printf("\n");
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
// terminate args list
|
||||||
|
args.push_back(NULL);
|
||||||
|
|
||||||
|
// try to call archiver
|
||||||
|
if (int status = llvm::sys::Program::ExecuteAndWait(ar, &args[0], NULL, NULL, 0,0, &errstr))
|
||||||
|
{
|
||||||
|
error("archiver failed:\nstatus: %d", status);
|
||||||
|
if (!errstr.empty())
|
||||||
|
error("message: %s", errstr.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void deleteExecutable()
|
void deleteExecutable()
|
||||||
{
|
{
|
||||||
if (!gExePath.isEmpty())
|
if (!gExePath.isEmpty())
|
||||||
|
|
|
@ -32,6 +32,11 @@ int linkExecutable(const char* argv0);
|
||||||
*/
|
*/
|
||||||
int linkObjToExecutable(const char* argv0);
|
int linkObjToExecutable(const char* argv0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a static library from object files.
|
||||||
|
*/
|
||||||
|
void createStaticLibrary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the executable that was previously linked with linkExecutable.
|
* Delete the executable that was previously linked with linkExecutable.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -388,7 +388,7 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
// only link if possible
|
// only link if possible
|
||||||
if (!global.params.obj || !global.params.output_o)
|
if (!global.params.obj || !global.params.output_o || createStaticLib)
|
||||||
global.params.link = 0;
|
global.params.link = 0;
|
||||||
|
|
||||||
if (global.params.link)
|
if (global.params.link)
|
||||||
|
@ -1028,11 +1028,15 @@ LDC_TARGETS
|
||||||
{
|
{
|
||||||
if (global.params.link)
|
if (global.params.link)
|
||||||
error("no object files to link");
|
error("no object files to link");
|
||||||
|
else if (createStaticLib)
|
||||||
|
error("no object files");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (global.params.link)
|
if (global.params.link)
|
||||||
status = linkObjToExecutable(global.params.argv0);
|
status = linkObjToExecutable(global.params.argv0);
|
||||||
|
else if (createStaticLib)
|
||||||
|
createStaticLibrary();
|
||||||
|
|
||||||
if (global.params.run)
|
if (global.params.run)
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,27 +13,42 @@ static cl::opt<std::string> gcc("gcc",
|
||||||
cl::Hidden,
|
cl::Hidden,
|
||||||
cl::ZeroOrMore);
|
cl::ZeroOrMore);
|
||||||
|
|
||||||
|
static cl::opt<std::string> ar("ar",
|
||||||
|
cl::desc("Archiver"),
|
||||||
|
cl::Hidden,
|
||||||
|
cl::ZeroOrMore);
|
||||||
|
|
||||||
sys::Path getGcc() {
|
sys::Path getProgram(const char *name, const cl::opt<std::string> &opt, const char *envVar = 0)
|
||||||
const char *cc = NULL;
|
{
|
||||||
|
const char *prog = NULL;
|
||||||
if (gcc.getNumOccurrences() > 0 && gcc.length() > 0)
|
|
||||||
cc = gcc.c_str();
|
if (opt.getNumOccurrences() > 0 && opt.length() > 0)
|
||||||
|
prog = gcc.c_str();
|
||||||
if (!cc)
|
|
||||||
cc = getenv("CC");
|
if (!prog && envVar)
|
||||||
if (!cc)
|
prog = getenv(envVar);
|
||||||
cc = "gcc";
|
if (!prog)
|
||||||
|
prog = name;
|
||||||
sys::Path path = sys::Program::FindProgramByName(cc);
|
|
||||||
if (path.empty() && !cc) {
|
sys::Path path = sys::Program::FindProgramByName(prog);
|
||||||
if (cc) {
|
if (path.empty() && !prog) {
|
||||||
path.set(cc);
|
if (prog) {
|
||||||
|
path.set(prog);
|
||||||
} else {
|
} else {
|
||||||
error("failed to locate gcc");
|
error("failed to locate %s", name);
|
||||||
fatal();
|
fatal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sys::Path getGcc()
|
||||||
|
{
|
||||||
|
return getProgram("gcc", gcc, "CC");
|
||||||
|
}
|
||||||
|
|
||||||
|
sys::Path getArchiver()
|
||||||
|
{
|
||||||
|
return getProgram("ar", ar);
|
||||||
|
}
|
||||||
|
|
|
@ -4,5 +4,6 @@
|
||||||
#include "llvm/Support/Path.h"
|
#include "llvm/Support/Path.h"
|
||||||
|
|
||||||
llvm::sys::Path getGcc();
|
llvm::sys::Path getGcc();
|
||||||
|
llvm::sys::Path getArchiver();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue