diff --git a/driver/cl_options.cpp b/driver/cl_options.cpp index 305538274a..c2f12984d1 100644 --- a/driver/cl_options.cpp +++ b/driver/cl_options.cpp @@ -286,6 +286,11 @@ cl::opt "'-deps' alone prints module dependencies " "(imports/file/version/debug/lib)")); +cl::opt + staticFlag("static", llvm::cl::ZeroOrMore, + llvm::cl::desc("Create a statically linked binary, including " + "all system dependencies")); + cl::opt m32bits("m32", cl::desc("32 bit target"), cl::ZeroOrMore); cl::opt m64bits("m64", cl::desc("64 bit target"), cl::ZeroOrMore); diff --git a/driver/cl_options.h b/driver/cl_options.h index ccdfabb976..8f60e7a4e2 100644 --- a/driver/cl_options.h +++ b/driver/cl_options.h @@ -69,6 +69,7 @@ extern cl::opt moduleDeps; extern cl::opt cacheDir; extern cl::list linkerSwitches; extern cl::list ccSwitches; +extern cl::opt staticFlag; extern cl::opt m32bits; extern cl::opt m64bits; diff --git a/driver/linker.cpp b/driver/linker.cpp index 9a37aa3bc6..c933c550f5 100644 --- a/driver/linker.cpp +++ b/driver/linker.cpp @@ -20,11 +20,6 @@ ////////////////////////////////////////////////////////////////////////////// -static llvm::cl::opt - staticFlag("static", llvm::cl::ZeroOrMore, - llvm::cl::desc("Create a statically linked binary, including " - "all system dependencies")); - #if LDC_WITH_LLD static llvm::cl::opt useInternalLinker("link-internally", llvm::cl::ZeroOrMore, llvm::cl::Hidden, @@ -134,10 +129,10 @@ int linkObjToBinary() { createDirectoryForFileOrFail(gExePath); 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); } ////////////////////////////////////////////////////////////////////////////// diff --git a/driver/main.cpp b/driver/main.cpp index 826fc2e950..491dada2d8 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -97,17 +97,34 @@ static cl::list cl::value_desc("directory"), cl::location(impPathsStore), cl::Prefix); +static cl::OptionCategory + defaultLibsCategory("Libraries linked with by default"); + static cl::opt 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 debugLib( - "debuglib", cl::ZeroOrMore, cl::value_desc("lib1,lib2,..."), - cl::desc("Debug versions of default libraries (overrides previous)")); + "debuglib", cl::ZeroOrMore, cl::Hidden, cl::value_desc("lib1,lib2,..."), + 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 linkDebugLib( - "link-debuglib", cl::ZeroOrMore, - cl::desc("Link with libraries specified in -debuglib, not -defaultlib")); +static cl::opt linkDefaultLibDebug( + "link-defaultlib-debug", cl::ZeroOrMore, + 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 linkDefaultLibShared( + "link-defaultlib-shared", cl::ZeroOrMore, + cl::desc("Link with shared versions of default libraries"), + cl::cat(defaultLibsCategory)); // This function exits the program. void printVersion(llvm::raw_ostream &OS) { @@ -485,13 +502,27 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles, } } + // default libraries if (noDefaultLib) { - deprecation(Loc(), "-nodefaultlib is deprecated, as -defaultlib/-debuglib " - "now override the existing list instead of appending to " + deprecation(Loc(), "-nodefaultlib is deprecated, as -defaultlib now " + "overrides the existing list instead of appending to " "it. Please use the latter instead."); } 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. - std::stringstream libNames(linkDebugLib ? debugLib : defaultLib); + std::stringstream libNames( + linkDefaultLibDebug && !addDebugSuffix ? debugLib : defaultLib); while (libNames.good()) { std::string lib; std::getline(libNames, lib, ','); @@ -499,9 +530,14 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles, continue; } - char *arg = static_cast(mem.xmalloc(lib.size() + 3)); - strcpy(arg, "-l"); - strcpy(arg + 2, lib.c_str()); + std::ostringstream os; + os << "-l" << lib; + if (addDebugSuffix) + os << "-debug"; + if (addSharedSuffix) + os << "-shared"; + + char *arg = mem.xstrdup(os.str().c_str()); global.params.linkswitches->push(arg); } } diff --git a/ldc2.conf.in b/ldc2.conf.in index 16ab788b0a..fa68e84c65 100644 --- a/ldc2.conf.in +++ b/ldc2.conf.in @@ -7,8 +7,7 @@ default: // default switches injected before all explicit command-line switches switches = [ "-I@RUNTIME_DIR@/src",@SHARED_LIBS_RPATH@ - "-defaultlib=druntime-ldc", - "-debuglib=druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ + "-defaultlib=druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ ]; // default switches appended after all explicit command-line switches post-switches = [ diff --git a/ldc2_install.conf.in b/ldc2_install.conf.in index e74486d851..937c9b2291 100644 --- a/ldc2_install.conf.in +++ b/ldc2_install.conf.in @@ -8,8 +8,7 @@ default: switches = [ "-I@INCLUDE_INSTALL_DIR@/ldc", "-I@INCLUDE_INSTALL_DIR@", - "-defaultlib=phobos2-ldc,druntime-ldc", - "-debuglib=phobos2-ldc-debug,druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ + "-defaultlib=phobos2-ldc,druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ ]; // default switches appended after all explicit command-line switches post-switches = [ diff --git a/ldc2_phobos.conf.in b/ldc2_phobos.conf.in index 8e37db1208..4270f585e6 100644 --- a/ldc2_phobos.conf.in +++ b/ldc2_phobos.conf.in @@ -10,8 +10,7 @@ default: "-I@PROFILERT_DIR@/d", "-I@JITRT_DIR@/d", "-I@PHOBOS2_DIR@",@SHARED_LIBS_RPATH@ - "-defaultlib=phobos2-ldc,druntime-ldc", - "-debuglib=phobos2-ldc-debug,druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ + "-defaultlib=phobos2-ldc,druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ ]; // default switches appended after all explicit command-line switches post-switches = [ diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 5ed1ad5c4b..1886971359 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -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(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_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(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") @@ -113,11 +113,7 @@ if(NOT ${BUILD_SHARED_LIBS} STREQUAL "OFF") 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.") 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") - endif() + set(SHARED_LIB_SUFFIX "-shared") endif() # Auto-detect C system libraries @@ -270,6 +266,14 @@ if("${TARGET_SYSTEM}" MATCHES "Linux|FreeBSD") 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. if(LDC_EXE) if(PHOBOS2_DIR) diff --git a/tests/codegen/exception_stack_trace.d b/tests/codegen/exception_stack_trace.d index 464aa60e36..03a9701600 100644 --- a/tests/codegen/exception_stack_trace.d +++ b/tests/codegen/exception_stack_trace.d @@ -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 void bar() diff --git a/tests/d2/CMakeLists.txt b/tests/d2/CMakeLists.txt index 1e5a739d59..4b9beeaac4 100644 --- a/tests/d2/CMakeLists.txt +++ b/tests/d2/CMakeLists.txt @@ -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 # tests (e.g. 'testdstress') depend on contracts and invariants being active. # 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}) if(MULTILIB AND host_model EQUAL 64) # 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) endif() diff --git a/tests/driver/mscrtlib.d b/tests/driver/mscrtlib.d index 938588e94b..d6c8831071 100644 --- a/tests/driver/mscrtlib.d +++ b/tests/driver/mscrtlib.d @@ -4,7 +4,7 @@ // REQUIRES: Windows -// 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=msvcrt -link-debuglib -run "%S\..\d2\dmd-testsuite\runnable\eh.d" -// RUN: %ldc -mscrtlib=msvcrtd -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-defaultlib-debug -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"