mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-09 12:32:33 +03:00
Add -mscrtlib cmdline option and support -static on Windows (#2041)
The default MS C runtime library doesn't depend on the `LINK_WITH_MSVCRT` CMake variable anymore. The user can freely choose among the 4 variants libcmt[d] / msvcrt[d] via -mscrtlib or choose between static/dynamic release variant via -static. LDC keeps on defaulting to the static release C runtime, so `-static=false` or `-mscrtlib=msvcrt[d]` must be used explicitly in order to link against the runtime DLLs.
This commit is contained in:
parent
1dfe11c961
commit
a5139499a3
4 changed files with 44 additions and 27 deletions
|
@ -210,11 +210,9 @@ Where:\n\
|
||||||
" -map generate linker .map file\n"
|
" -map generate linker .map file\n"
|
||||||
#endif
|
#endif
|
||||||
" -mcpu=<id> generate instructions for architecture identified by 'id'\n\
|
" -mcpu=<id> generate instructions for architecture identified by 'id'\n\
|
||||||
-mcpu=? list all architecture options\n"
|
-mcpu=? list all architecture options\n\
|
||||||
#if 0
|
-mscrtlib=<name> MS C runtime library to reference from main/WinMain/DllMain\n\
|
||||||
" -mscrtlib=<name> MS C runtime library to reference from main/WinMain/DllMain\n"
|
-mv=<package.module>=<filespec> use <filespec> as source file for <package.module>\n\
|
||||||
#endif
|
|
||||||
" -mv=<package.module>=<filespec> use <filespec> as source file for <package.module>\n\
|
|
||||||
-noboundscheck no array bounds checking (deprecated, use -boundscheck=off)\n\
|
-noboundscheck no array bounds checking (deprecated, use -boundscheck=off)\n\
|
||||||
-O optimize\n\
|
-O optimize\n\
|
||||||
-o- do not write object file\n\
|
-o- do not write object file\n\
|
||||||
|
@ -421,9 +419,10 @@ void translateArgs(size_t originalArgc, char **originalArgv,
|
||||||
*/
|
*/
|
||||||
else if (strcmp(p + 1, "m32mscoff") == 0) {
|
else if (strcmp(p + 1, "m32mscoff") == 0) {
|
||||||
ldcArgs.push_back("-m32");
|
ldcArgs.push_back("-m32");
|
||||||
} else if (strncmp(p + 1, "mscrtlib=", 9) == 0) {
|
}
|
||||||
goto Lnot_in_ldc;
|
/* -mscrtlib
|
||||||
} else if (strcmp(p + 1, "profile") == 0) {
|
*/
|
||||||
|
else if (strcmp(p + 1, "profile") == 0) {
|
||||||
goto Lnot_in_ldc;
|
goto Lnot_in_ldc;
|
||||||
}
|
}
|
||||||
/* -v
|
/* -v
|
||||||
|
|
|
@ -39,6 +39,12 @@ static llvm::cl::opt<bool> staticFlag(
|
||||||
"Create a statically linked binary, including all system dependencies"),
|
"Create a statically linked binary, including all system dependencies"),
|
||||||
llvm::cl::ZeroOrMore);
|
llvm::cl::ZeroOrMore);
|
||||||
|
|
||||||
|
static llvm::cl::opt<std::string> mscrtlib(
|
||||||
|
"mscrtlib",
|
||||||
|
llvm::cl::desc(
|
||||||
|
"MS C runtime library to link against (libcmt[d] / msvcrt[d])"),
|
||||||
|
llvm::cl::value_desc("name"), llvm::cl::ZeroOrMore);
|
||||||
|
|
||||||
static llvm::cl::opt<std::string>
|
static llvm::cl::opt<std::string>
|
||||||
ltoLibrary("flto-binary",
|
ltoLibrary("flto-binary",
|
||||||
llvm::cl::desc("Set the linker LTO plugin library file (e.g. "
|
llvm::cl::desc("Set the linker LTO plugin library file (e.g. "
|
||||||
|
@ -280,7 +286,7 @@ static void appendObjectFiles(std::vector<std::string> &args) {
|
||||||
|
|
||||||
static std::string gExePath;
|
static std::string gExePath;
|
||||||
|
|
||||||
static int linkObjToBinaryGcc(bool sharedLib, bool fullyStatic) {
|
static int linkObjToBinaryGcc(bool sharedLib) {
|
||||||
Logger::println("*** Linking executable ***");
|
Logger::println("*** Linking executable ***");
|
||||||
|
|
||||||
// find gcc for linking
|
// find gcc for linking
|
||||||
|
@ -317,7 +323,7 @@ static int linkObjToBinaryGcc(bool sharedLib, bool fullyStatic) {
|
||||||
args.push_back("-shared");
|
args.push_back("-shared");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullyStatic) {
|
if (staticFlag) {
|
||||||
args.push_back("-static");
|
args.push_back("-static");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -489,6 +495,26 @@ static int linkObjToBinaryGcc(bool sharedLib, bool fullyStatic) {
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void addMscrtLibs(std::vector<std::string> &args) {
|
||||||
|
llvm::StringRef mscrtlibName = mscrtlib;
|
||||||
|
if (mscrtlibName.empty()) {
|
||||||
|
// default to static release variant
|
||||||
|
mscrtlibName =
|
||||||
|
staticFlag || staticFlag.getNumOccurrences() == 0 ? "libcmt" : "msvcrt";
|
||||||
|
}
|
||||||
|
|
||||||
|
args.push_back(("/DEFAULTLIB:" + mscrtlibName).str());
|
||||||
|
|
||||||
|
const bool isStatic = mscrtlibName.startswith_lower("libcmt");
|
||||||
|
const bool isDebug =
|
||||||
|
mscrtlibName.endswith_lower("d") || mscrtlibName.endswith_lower("d.lib");
|
||||||
|
|
||||||
|
const llvm::StringRef prefix = isStatic ? "lib" : "";
|
||||||
|
const llvm::StringRef suffix = isDebug ? "d" : "";
|
||||||
|
|
||||||
|
args.push_back(("/DEFAULTLIB:" + prefix + "vcruntime" + suffix).str());
|
||||||
|
}
|
||||||
|
|
||||||
static int linkObjToBinaryMSVC(bool sharedLib) {
|
static int linkObjToBinaryMSVC(bool sharedLib) {
|
||||||
Logger::println("*** Linking executable ***");
|
Logger::println("*** Linking executable ***");
|
||||||
|
|
||||||
|
@ -528,6 +554,9 @@ static int linkObjToBinaryMSVC(bool sharedLib) {
|
||||||
args.push_back("/OPT:ICF");
|
args.push_back("/OPT:ICF");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add C runtime libs
|
||||||
|
addMscrtLibs(args);
|
||||||
|
|
||||||
// specify creation of DLL
|
// specify creation of DLL
|
||||||
if (sharedLib) {
|
if (sharedLib) {
|
||||||
args.push_back("/DLL");
|
args.push_back("/DLL");
|
||||||
|
@ -604,11 +633,10 @@ static int linkObjToBinaryMSVC(bool sharedLib) {
|
||||||
|
|
||||||
int linkObjToBinary() {
|
int linkObjToBinary() {
|
||||||
if (global.params.targetTriple->isWindowsMSVCEnvironment()) {
|
if (global.params.targetTriple->isWindowsMSVCEnvironment()) {
|
||||||
// TODO: Choose dynamic/static MSVCRT version based on staticFlag?
|
|
||||||
return linkObjToBinaryMSVC(global.params.dll);
|
return linkObjToBinaryMSVC(global.params.dll);
|
||||||
}
|
}
|
||||||
|
|
||||||
return linkObjToBinaryGcc(global.params.dll, staticFlag);
|
return linkObjToBinaryGcc(global.params.dll);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -15,9 +15,6 @@ set(BUILD_SHARED_LIBS AUTO CACHE STRING
|
||||||
set(D_FLAGS -w CACHE STRING "Runtime build flags, separated by ;")
|
set(D_FLAGS -w CACHE STRING "Runtime build flags, separated by ;")
|
||||||
set(D_FLAGS_DEBUG -g;-link-debuglib CACHE STRING "Runtime build flags (debug libraries), separated by ;")
|
set(D_FLAGS_DEBUG -g;-link-debuglib CACHE STRING "Runtime build flags (debug libraries), separated by ;")
|
||||||
set(D_FLAGS_RELEASE -O3;-release CACHE STRING "Runtime build flags (release libraries), separated by ;")
|
set(D_FLAGS_RELEASE -O3;-release CACHE STRING "Runtime build flags (release libraries), separated by ;")
|
||||||
if(MSVC)
|
|
||||||
set(LINK_WITH_MSVCRT OFF CACHE BOOL "Link with MSVCRT.lib (DLL) instead of LIBCMT.lib (static)")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
|
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
|
||||||
|
|
||||||
|
@ -246,17 +243,10 @@ endforeach()
|
||||||
# of what the user chose for LDC itself.
|
# of what the user chose for LDC itself.
|
||||||
# 1) Set up CMAKE_C_FLAGS_RELEASE
|
# 1) Set up CMAKE_C_FLAGS_RELEASE
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
if(NOT LINK_WITH_MSVCRT)
|
# Omit all references to the default C runtime libs.
|
||||||
string(REGEX REPLACE "(^| )[/-]MD( |$)" "\\2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
# We want to be able to link against all 4 C runtime variants (libcmt[d] / msvcrt[d]).
|
||||||
if(NOT CMAKE_C_FLAGS_RELEASE MATCHES "(^| )[/-]MT( |$)")
|
string(REGEX REPLACE "(^| )[/-]M[TD]d?( |$)" "\\2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||||
append("/MT" CMAKE_C_FLAGS_RELEASE)
|
append("/MT /Zl" CMAKE_C_FLAGS_RELEASE)
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
string(REGEX REPLACE "(^| )[/-]MT( |$)" "\\2" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
|
||||||
if(NOT CMAKE_C_FLAGS_RELEASE MATCHES "(^| )[/-]MD( |$)")
|
|
||||||
append("/MD" CMAKE_C_FLAGS_RELEASE)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
# warning C4996: zlib uses 'deprecated' POSIX names
|
# warning C4996: zlib uses 'deprecated' POSIX names
|
||||||
append("/wd4996" CMAKE_C_FLAGS_RELEASE)
|
append("/wd4996" CMAKE_C_FLAGS_RELEASE)
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit d91c32d44def323910a5e22d9a9739997f80b893
|
Subproject commit 8414f932691e01dc6c174b88f67ffd6e21ba7fcc
|
Loading…
Add table
Add a link
Reference in a new issue