Skip to content

Commit 90d0f6c

Browse files
committed
Merge pull request #429 from redstar/moduleflags
Implement pragma(lib) on Windows using module metadata.
2 parents f80be41 + 4f7bc67 commit 90d0f6c

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

gen/declarations.cpp

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "gen/utils.h"
2525
#include "ir/irtype.h"
2626
#include "ir/irvar.h"
27+
#include "llvm/ADT/SmallString.h"
2728

2829
/* ================================================================== */
2930

@@ -384,13 +385,38 @@ void PragmaDeclaration::codegen(IRState *p)
384385
}
385386
}
386387

387-
size_t const n = nameLen + 3;
388-
char *arg = static_cast<char *>(mem.malloc(n));
389-
arg[0] = '-';
390-
arg[1] = 'l';
391-
memcpy(arg + 2, se->string, nameLen);
392-
arg[n-1] = 0;
393-
global.params.linkswitches->push(arg);
388+
#if LDC_LLVM_VER >= 303
389+
// With LLVM 3.3 or later we can place the library name in the object
390+
// file. This seems to be supported only on Windows.
391+
if (global.params.targetTriple.getOS() == llvm::Triple::Win32)
392+
{
393+
llvm::SmallString<24> LibName(llvm::StringRef(static_cast<const char *>(se->string), nameLen));
394+
395+
// Win32: /DEFAULTLIB:"curl"
396+
if (LibName.endswith(".a"))
397+
LibName = LibName.substr(0, LibName.size()-2);
398+
if (LibName.endswith(".lib"))
399+
LibName = LibName.substr(0, LibName.size()-4);
400+
llvm::SmallString<24> tmp("/DEFAULTLIB:\"");
401+
tmp.append(LibName);
402+
tmp.append("\"");
403+
LibName = tmp;
404+
405+
// Embedd library name as linker option in object file
406+
llvm::Value *Value = llvm::MDString::get(gIR->context(), LibName);
407+
gIR->LinkerMetadataArgs.push_back(llvm::MDNode::get(gIR->context(), Value));
408+
}
409+
else
410+
#endif
411+
{
412+
size_t const n = nameLen + 3;
413+
char *arg = static_cast<char *>(mem.malloc(n));
414+
arg[0] = '-';
415+
arg[1] = 'l';
416+
memcpy(arg + 2, se->string, nameLen);
417+
arg[n-1] = 0;
418+
global.params.linkswitches->push(arg);
419+
}
394420
}
395421
AttribDeclaration::codegen(p);
396422
}

gen/irstate.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ struct IRState
203203

204204
/// Whether to emit array bounds checking in the current function.
205205
bool emitArrayBoundsChecks();
206+
207+
#if LDC_LLVM_VER >= 303
208+
/// Vector of options passed to the linker as metadata in object file.
209+
llvm::SmallVector<llvm::Value *, 5> LinkerMetadataArgs;
210+
#endif
206211
};
207212

208213
template <typename T>

gen/module.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,12 @@ llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context)
414414
// generate ModuleInfo
415415
genmoduleinfo();
416416

417+
#if LDC_LLVM_VER >= 303
418+
// Add the linker options metadata flag.
419+
ir.module->addModuleFlag(llvm::Module::AppendUnique, "Linker Options",
420+
llvm::MDNode::get(ir.context(), ir.LinkerMetadataArgs));
421+
#endif
422+
417423
// verify the llvm
418424
verifyModule(*ir.module);
419425

0 commit comments

Comments
 (0)