Add -link-defaultlib-shared and rename -link-debuglib (#2443)

... to -link-defaultlib-debug (with alias for backwards compatibility).

-link-defaultlib-shared is to be used for switching between static and
shared default libs to be linked with.

It defaults to true when generating shared libraries (if shared
druntime/Phobos are supported for the target, i.e., not for Windows).
This is a benign breaking change!
This commit is contained in:
Martin Kinkelin 2018-01-12 18:26:19 +01:00 committed by GitHub
parent 3e543120fd
commit 1572c91fc0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 76 additions and 38 deletions

View file

@ -286,6 +286,11 @@ cl::opt<std::string>
"'-deps' alone prints module dependencies " "'-deps' alone prints module dependencies "
"(imports/file/version/debug/lib)")); "(imports/file/version/debug/lib)"));
cl::opt<cl::boolOrDefault>
staticFlag("static", llvm::cl::ZeroOrMore,
llvm::cl::desc("Create a statically linked binary, including "
"all system dependencies"));
cl::opt<bool> m32bits("m32", cl::desc("32 bit target"), cl::ZeroOrMore); cl::opt<bool> m32bits("m32", cl::desc("32 bit target"), cl::ZeroOrMore);
cl::opt<bool> m64bits("m64", cl::desc("64 bit target"), cl::ZeroOrMore); cl::opt<bool> m64bits("m64", cl::desc("64 bit target"), cl::ZeroOrMore);

View file

@ -69,6 +69,7 @@ extern cl::opt<std::string> moduleDeps;
extern cl::opt<std::string> cacheDir; extern cl::opt<std::string> cacheDir;
extern cl::list<std::string> linkerSwitches; extern cl::list<std::string> linkerSwitches;
extern cl::list<std::string> ccSwitches; extern cl::list<std::string> ccSwitches;
extern cl::opt<cl::boolOrDefault> staticFlag;
extern cl::opt<bool> m32bits; extern cl::opt<bool> m32bits;
extern cl::opt<bool> m64bits; extern cl::opt<bool> m64bits;

View file

@ -20,11 +20,6 @@
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
static llvm::cl::opt<llvm::cl::boolOrDefault>
staticFlag("static", llvm::cl::ZeroOrMore,
llvm::cl::desc("Create a statically linked binary, including "
"all system dependencies"));
#if LDC_WITH_LLD #if LDC_WITH_LLD
static llvm::cl::opt<bool> static llvm::cl::opt<bool>
useInternalLinker("link-internally", llvm::cl::ZeroOrMore, llvm::cl::Hidden, useInternalLinker("link-internally", llvm::cl::ZeroOrMore, llvm::cl::Hidden,
@ -134,10 +129,10 @@ int linkObjToBinary() {
createDirectoryForFileOrFail(gExePath); createDirectoryForFileOrFail(gExePath);
if (global.params.targetTriple->isWindowsMSVCEnvironment()) { if (global.params.targetTriple->isWindowsMSVCEnvironment()) {
return linkObjToBinaryMSVC(gExePath, useInternalLinker, staticFlag); return linkObjToBinaryMSVC(gExePath, useInternalLinker, opts::staticFlag);
} }
return linkObjToBinaryGcc(gExePath, useInternalLinker, staticFlag); return linkObjToBinaryGcc(gExePath, useInternalLinker, opts::staticFlag);
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View file

@ -97,17 +97,34 @@ static cl::list<std::string, StringsAdapter>
cl::value_desc("directory"), cl::location(impPathsStore), cl::value_desc("directory"), cl::location(impPathsStore),
cl::Prefix); cl::Prefix);
static cl::OptionCategory
defaultLibsCategory("Libraries linked with by default");
static cl::opt<std::string> static cl::opt<std::string>
defaultLib("defaultlib", cl::ZeroOrMore, cl::value_desc("lib1,lib2,..."), defaultLib("defaultlib", cl::ZeroOrMore, cl::value_desc("lib1,lib2,..."),
cl::desc("Default libraries to link with (overrides previous)")); cl::desc("Default libraries to link with (overrides previous)"),
cl::cat(defaultLibsCategory));
static cl::opt<std::string> debugLib( static cl::opt<std::string> debugLib(
"debuglib", cl::ZeroOrMore, cl::value_desc("lib1,lib2,..."), "debuglib", cl::ZeroOrMore, cl::Hidden, cl::value_desc("lib1,lib2,..."),
cl::desc("Debug versions of default libraries (overrides previous)")); cl::desc("Debug versions of default libraries (overrides previous). If the "
"option is omitted, LDC will append -debug to the -defaultlib "
"names when linking with -link-defaultlib-debug"),
cl::cat(defaultLibsCategory));
static cl::opt<bool> linkDebugLib( static cl::opt<bool> linkDefaultLibDebug(
"link-debuglib", cl::ZeroOrMore, "link-defaultlib-debug", cl::ZeroOrMore,
cl::desc("Link with libraries specified in -debuglib, not -defaultlib")); cl::desc("Link with debug versions of default libraries"),
cl::cat(defaultLibsCategory));
static cl::alias _linkDebugLib("link-debuglib", cl::Hidden,
cl::aliasopt(linkDefaultLibDebug),
cl::desc("Alias for -link-defaultlib-debug"),
cl::cat(defaultLibsCategory));
static cl::opt<bool> linkDefaultLibShared(
"link-defaultlib-shared", cl::ZeroOrMore,
cl::desc("Link with shared versions of default libraries"),
cl::cat(defaultLibsCategory));
// This function exits the program. // This function exits the program.
void printVersion(llvm::raw_ostream &OS) { void printVersion(llvm::raw_ostream &OS) {
@ -485,13 +502,27 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles,
} }
} }
// default libraries
if (noDefaultLib) { if (noDefaultLib) {
deprecation(Loc(), "-nodefaultlib is deprecated, as -defaultlib/-debuglib " deprecation(Loc(), "-nodefaultlib is deprecated, as -defaultlib now "
"now override the existing list instead of appending to " "overrides the existing list instead of appending to "
"it. Please use the latter instead."); "it. Please use the latter instead.");
} else if (!global.params.betterC) { } else if (!global.params.betterC) {
if (linkDefaultLibShared && staticFlag == cl::BOU_TRUE) {
error(Loc(), "Can't use -link-defaultlib-shared and -static together");
}
const bool addDebugSuffix =
(linkDefaultLibDebug && debugLib.getNumOccurrences() == 0);
// Default to shared default libs for DLLs compiled without -static.
const bool addSharedSuffix =
linkDefaultLibShared ||
(linkDefaultLibShared.getNumOccurrences() == 0 && global.params.dll &&
staticFlag != cl::BOU_TRUE);
// Parse comma-separated default library list. // Parse comma-separated default library list.
std::stringstream libNames(linkDebugLib ? debugLib : defaultLib); std::stringstream libNames(
linkDefaultLibDebug && !addDebugSuffix ? debugLib : defaultLib);
while (libNames.good()) { while (libNames.good()) {
std::string lib; std::string lib;
std::getline(libNames, lib, ','); std::getline(libNames, lib, ',');
@ -499,9 +530,14 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles,
continue; continue;
} }
char *arg = static_cast<char *>(mem.xmalloc(lib.size() + 3)); std::ostringstream os;
strcpy(arg, "-l"); os << "-l" << lib;
strcpy(arg + 2, lib.c_str()); if (addDebugSuffix)
os << "-debug";
if (addSharedSuffix)
os << "-shared";
char *arg = mem.xstrdup(os.str().c_str());
global.params.linkswitches->push(arg); global.params.linkswitches->push(arg);
} }
} }

View file

@ -7,8 +7,7 @@ default:
// default switches injected before all explicit command-line switches // default switches injected before all explicit command-line switches
switches = [ switches = [
"-I@RUNTIME_DIR@/src",@SHARED_LIBS_RPATH@ "-I@RUNTIME_DIR@/src",@SHARED_LIBS_RPATH@
"-defaultlib=druntime-ldc", "-defaultlib=druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
"-debuglib=druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
]; ];
// default switches appended after all explicit command-line switches // default switches appended after all explicit command-line switches
post-switches = [ post-switches = [

View file

@ -8,8 +8,7 @@ default:
switches = [ switches = [
"-I@INCLUDE_INSTALL_DIR@/ldc", "-I@INCLUDE_INSTALL_DIR@/ldc",
"-I@INCLUDE_INSTALL_DIR@", "-I@INCLUDE_INSTALL_DIR@",
"-defaultlib=phobos2-ldc,druntime-ldc", "-defaultlib=phobos2-ldc,druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
"-debuglib=phobos2-ldc-debug,druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
]; ];
// default switches appended after all explicit command-line switches // default switches appended after all explicit command-line switches
post-switches = [ post-switches = [

View file

@ -10,8 +10,7 @@ default:
"-I@PROFILERT_DIR@/d", "-I@PROFILERT_DIR@/d",
"-I@JITRT_DIR@/d", "-I@JITRT_DIR@/d",
"-I@PHOBOS2_DIR@",@SHARED_LIBS_RPATH@ "-I@PHOBOS2_DIR@",@SHARED_LIBS_RPATH@
"-defaultlib=phobos2-ldc,druntime-ldc", "-defaultlib=phobos2-ldc,druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
"-debuglib=phobos2-ldc-debug,druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@
]; ];
// default switches appended after all explicit command-line switches // default switches appended after all explicit command-line switches
post-switches = [ post-switches = [

View file

@ -38,7 +38,7 @@ set(BUILD_BC_LIBS OFF CACHE BOOL "Buil
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/d CACHE PATH "Path to install D modules to") set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/include/d CACHE PATH "Path to install D modules to")
set(BUILD_SHARED_LIBS AUTO CACHE STRING "Whether to build the runtime as a shared library (ON|OFF|BOTH)") set(BUILD_SHARED_LIBS AUTO CACHE STRING "Whether to build the runtime as a shared library (ON|OFF|BOTH)")
set(D_FLAGS -w CACHE STRING "Runtime D compiler flags, separated by ';'") set(D_FLAGS -w CACHE STRING "Runtime D compiler flags, separated by ';'")
set(D_FLAGS_DEBUG -g;-link-debuglib CACHE STRING "Runtime D compiler flags (debug libraries), separated by ';'") set(D_FLAGS_DEBUG -g;-link-defaultlib-debug CACHE STRING "Runtime D compiler flags (debug libraries), separated by ';'")
set(D_FLAGS_RELEASE -O3;-release CACHE STRING "Runtime D compiler flags (release libraries), separated by ';'") set(D_FLAGS_RELEASE -O3;-release CACHE STRING "Runtime D compiler flags (release libraries), separated by ';'")
set(COMPILE_ALL_D_FILES_AT_ONCE ON CACHE BOOL "Compile all D files for a lib in a single command line instead of separately") set(COMPILE_ALL_D_FILES_AT_ONCE ON CACHE BOOL "Compile all D files for a lib in a single command line instead of separately")
set(RT_ARCHIVE_WITH_LDC AUTO CACHE STRING "Whether to archive the static runtime libs via LDC instead of CMake archiver") set(RT_ARCHIVE_WITH_LDC AUTO CACHE STRING "Whether to archive the static runtime libs via LDC instead of CMake archiver")
@ -113,11 +113,7 @@ if(NOT ${BUILD_SHARED_LIBS} STREQUAL "OFF")
if(NOT SHARED_LIBS_SUPPORTED) if(NOT SHARED_LIBS_SUPPORTED)
message(FATAL_ERROR "Shared libraries (BUILD_SHARED_LIBS) are only supported on Linux, macOS and FreeBSD for the time being.") message(FATAL_ERROR "Shared libraries (BUILD_SHARED_LIBS) are only supported on Linux, macOS and FreeBSD for the time being.")
endif() endif()
# Only use the `-shared` lib suffix if static libs are generated too
if(NOT ${BUILD_SHARED_LIBS} STREQUAL "ON")
set(SHARED_LIB_SUFFIX "-shared") set(SHARED_LIB_SUFFIX "-shared")
endif()
endif() endif()
# Auto-detect C system libraries # Auto-detect C system libraries
@ -270,6 +266,14 @@ if("${TARGET_SYSTEM}" MATCHES "Linux|FreeBSD")
endif() endif()
endif() endif()
# Only have either shared or static libs?
# Then explicitly default to linking against them via default LDC switch.
if(${BUILD_SHARED_LIBS} STREQUAL "ON")
set(ADDITIONAL_DEFAULT_LDC_SWITCHES ",\n \"-link-defaultlib-shared\"")
elseif(${BUILD_SHARED_LIBS} STREQUAL "OFF")
set(ADDITIONAL_DEFAULT_LDC_SWITCHES ",\n \"-link-defaultlib-shared=false\"")
endif()
# Only generate the config files if this CMake project is embedded in the LDC CMake project. # Only generate the config files if this CMake project is embedded in the LDC CMake project.
if(LDC_EXE) if(LDC_EXE)
if(PHOBOS2_DIR) if(PHOBOS2_DIR)

View file

@ -1,4 +1,4 @@
// RUN: %ldc -g -disable-fp-elim -link-debuglib %s -of=%t%exe // RUN: %ldc -g -disable-fp-elim -link-defaultlib-debug %s -of=%t%exe
// RUN: %t%exe | FileCheck %s // RUN: %t%exe | FileCheck %s
void bar() void bar()

View file

@ -48,11 +48,11 @@ string(REGEX REPLACE "[^0-9]*([0-9]+[0-9.]*).*" "\\1" GDB_VERSION "${GDB_VERSION
# Would like to specify the "-release" flag for release builds, but some of the # Would like to specify the "-release" flag for release builds, but some of the
# tests (e.g. 'testdstress') depend on contracts and invariants being active. # tests (e.g. 'testdstress') depend on contracts and invariants being active.
# Need a solution integrated with d_do_test. # Need a solution integrated with d_do_test.
add_testsuite("-debug" "-g -link-debuglib" "${gdb_flags}" ${host_model}) add_testsuite("-debug" "-g -link-defaultlib-debug" "${gdb_flags}" ${host_model})
add_testsuite("" -O "OFF" ${host_model}) add_testsuite("" -O "OFF" ${host_model})
if(MULTILIB AND host_model EQUAL 64) if(MULTILIB AND host_model EQUAL 64)
# Also test in 32 bit mode on x86_64 multilib builds. # Also test in 32 bit mode on x86_64 multilib builds.
add_testsuite("-debug_32" "-g -link-debuglib" "${gdb_flags}" 32) add_testsuite("-debug_32" "-g -link-defaultlib-debug" "${gdb_flags}" 32)
add_testsuite("_32" -O "OFF" 32) add_testsuite("_32" -O "OFF" 32)
endif() endif()

View file

@ -5,6 +5,6 @@
// REQUIRES: Windows // REQUIRES: Windows
// RUN: %ldc -mscrtlib=libcmt -run "%S\..\d2\dmd-testsuite\runnable\eh.d" // RUN: %ldc -mscrtlib=libcmt -run "%S\..\d2\dmd-testsuite\runnable\eh.d"
// RUN: %ldc -mscrtlib=libcmtd -link-debuglib -run "%S\..\d2\dmd-testsuite\runnable\eh.d" // RUN: %ldc -mscrtlib=libcmtd -link-defaultlib-debug -run "%S\..\d2\dmd-testsuite\runnable\eh.d"
// RUN: %ldc -mscrtlib=msvcrt -link-debuglib -run "%S\..\d2\dmd-testsuite\runnable\eh.d" // RUN: %ldc -mscrtlib=msvcrt -link-defaultlib-debug -run "%S\..\d2\dmd-testsuite\runnable\eh.d"
// RUN: %ldc -mscrtlib=msvcrtd -run "%S\..\d2\dmd-testsuite\runnable\eh.d" // RUN: %ldc -mscrtlib=msvcrtd -run "%S\..\d2\dmd-testsuite\runnable\eh.d"