diff --git a/.travis.yml b/.travis.yml index 7b0b1b38283..78107faeba5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -96,6 +96,9 @@ script: if [[ "${OPTS}" == *-DMULTILIB?ON* ]]; then ninja -j2 phobos2-ldc-unittest-debug phobos2-ldc-unittest phobos2-ldc-unittest-debug_32 phobos2-ldc-unittest_32; ninja -j3 druntime-ldc-unittest-debug druntime-ldc-unittest druntime-ldc-unittest-debug_32 druntime-ldc-unittest_32; + elif [[ "${OPTS}" == *-DBUILD_SHARED_LIBS?ON* ]]; then + ninja -j2 phobos2-ldc-unittest-debug-shared phobos2-ldc-unittest-shared; + ninja -j3 druntime-ldc-unittest-debug-shared druntime-ldc-unittest-shared; else ninja -j2 phobos2-ldc-unittest-debug phobos2-ldc-unittest; ninja -j3 druntime-ldc-unittest-debug druntime-ldc-unittest; diff --git a/driver/cl_options.cpp b/driver/cl_options.cpp index 9cac488403f..42469019f08 100644 --- a/driver/cl_options.cpp +++ b/driver/cl_options.cpp @@ -86,6 +86,10 @@ static cl::opt createSharedLib("shared", cl::desc("Create shared library (DLL)"), cl::ZeroOrMore, cl::location(global.params.dll)); +cl::opt staticFlag("static", cl::ZeroOrMore, + cl::desc("Create a statically linked binary, " + "including all system dependencies")); + static cl::opt verbose("v", cl::desc("Verbose"), cl::ZeroOrMore, cl::location(global.params.verbose)); diff --git a/driver/cl_options.h b/driver/cl_options.h index aa76b0b2ac2..7d4707d8c86 100644 --- a/driver/cl_options.h +++ b/driver/cl_options.h @@ -46,6 +46,7 @@ extern cl::list fileList; extern cl::list runargs; extern cl::opt invokedByLDMD; extern cl::opt compileOnly; +extern cl::opt staticFlag; extern cl::opt useDIP1000; extern cl::opt noAsm; extern cl::opt dontWriteObj; diff --git a/driver/linker.cpp b/driver/linker.cpp index e995048de1f..660b67bcb63 100644 --- a/driver/linker.cpp +++ b/driver/linker.cpp @@ -33,12 +33,6 @@ ////////////////////////////////////////////////////////////////////////////// -static llvm::cl::opt staticFlag( - "static", - llvm::cl::desc( - "Create a statically linked binary, including all system dependencies"), - llvm::cl::ZeroOrMore); - static llvm::cl::opt mscrtlib( "mscrtlib", llvm::cl::desc( @@ -323,7 +317,7 @@ static int linkObjToBinaryGcc(bool sharedLib) { args.push_back("-shared"); } - if (staticFlag) { + if (opts::staticFlag) { args.push_back("-static"); } @@ -499,8 +493,9 @@ static void addMscrtLibs(std::vector &args) { llvm::StringRef mscrtlibName = mscrtlib; if (mscrtlibName.empty()) { // default to static release variant - mscrtlibName = - staticFlag || staticFlag.getNumOccurrences() == 0 ? "libcmt" : "msvcrt"; + mscrtlibName = opts::staticFlag || opts::staticFlag.getNumOccurrences() == 0 + ? "libcmt" + : "msvcrt"; } args.push_back(("/DEFAULTLIB:" + mscrtlibName).str()); diff --git a/driver/main.cpp b/driver/main.cpp index 0efa58ff407..a9e6f027c59 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -99,13 +99,20 @@ static cl::opt static cl::opt debugLib( "debuglib", - cl::desc("Debug versions of default libraries (overrides previous)"), - cl::value_desc("lib1,lib2,..."), cl::ZeroOrMore); + 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-debuglib"), + cl::value_desc("lib1,lib2,..."), cl::ZeroOrMore, cl::Hidden); -static cl::opt linkDebugLib( - "link-debuglib", - cl::desc("Link with libraries specified in -debuglib, not -defaultlib"), - cl::ZeroOrMore); +static cl::opt + linkDebugLib("link-debuglib", + cl::desc("Link with debug versions of default libraries"), + cl::ZeroOrMore); + +static cl::opt + linkSharedLib("link-sharedlib", + cl::desc("Link with shared versions of default libraries"), + cl::ZeroOrMore); #if LDC_LLVM_VER >= 309 static inline llvm::Optional getRelocModel() { @@ -493,15 +500,25 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles, } } + if (linkSharedLib && staticFlag) { + error(Loc(), "Can't use -link-sharedlib and -static together"); + } + + // default libraries if (noDefaultLib) { - deprecation( - Loc(), - "-nodefaultlib is deprecated, as " - "-defaultlib/-debuglib now override the existing list instead of " - "appending to it. Please use the latter instead."); + deprecation(Loc(), "-nodefaultlib is deprecated, as -defaultlib now " + "overrides the existing list instead of appending to " + "it. Please use the latter instead."); } else { + const bool addDebugSuffix = + (linkDebugLib && debugLib.getNumOccurrences() == 0); + const bool addSharedSuffix = + linkSharedLib || (linkSharedLib.getNumOccurrences() == 0 && + global.params.dll && !staticFlag); + // Parse comma-separated default library list. - std::stringstream libNames(linkDebugLib ? debugLib : defaultLib); + std::stringstream libNames(linkDebugLib && !addDebugSuffix ? debugLib + : defaultLib); while (libNames.good()) { std::string lib; std::getline(libNames, lib, ','); @@ -509,9 +526,16 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles, continue; } - char *arg = static_cast(mem.xmalloc(lib.size() + 3)); + const size_t size = + lib.size() + 3 + (addDebugSuffix ? 6 : 0) + (addSharedSuffix ? 7 : 0); + char *arg = static_cast(mem.xmalloc(size)); strcpy(arg, "-l"); strcpy(arg + 2, lib.c_str()); + if (addDebugSuffix) + strcpy(arg + 2 + lib.length(), "-debug"); + if (addSharedSuffix) + strcpy(arg + size - 8, "-shared"); + global.params.linkswitches->push(arg); } } diff --git a/ldc2.conf.in b/ldc2.conf.in index f5a9b9290a3..7605478fffb 100644 --- a/ldc2.conf.in +++ b/ldc2.conf.in @@ -9,7 +9,6 @@ default: switches = [ "-I@RUNTIME_DIR@/src", "-L-L@PROJECT_BINARY_DIR@/../lib@LIB_SUFFIX@", @MULTILIB_ADDITIONAL_PATH@@SHARED_LIBS_RPATH@ - "-defaultlib=druntime-ldc", - "-debuglib=druntime-ldc-debug"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ + "-defaultlib=druntime-ldc"@ADDITIONAL_DEFAULT_LDC_SWITCHES@ ]; }; diff --git a/ldc2_install.conf.in b/ldc2_install.conf.in index c73b7424522..07caa5f1aee 100644 --- a/ldc2_install.conf.in +++ b/ldc2_install.conf.in @@ -10,7 +10,6 @@ default: "-I@INCLUDE_INSTALL_DIR@/ldc", "-I@INCLUDE_INSTALL_DIR@", "-L-L@CMAKE_INSTALL_LIBDIR@", @MULTILIB_ADDITIONAL_INSTALL_PATH@ - "-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@ ]; }; diff --git a/ldc2_phobos.conf.in b/ldc2_phobos.conf.in index 02e87e444fc..b0d04512d0a 100644 --- a/ldc2_phobos.conf.in +++ b/ldc2_phobos.conf.in @@ -11,7 +11,6 @@ default: "-I@PROFILERT_DIR@/d", "-I@PHOBOS2_DIR@", "-L-L@CMAKE_BINARY_DIR@/lib@LIB_SUFFIX@", @MULTILIB_ADDITIONAL_PATH@@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@ ]; }; diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 66f34efb3ae..6ab0a58f523 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -49,10 +49,7 @@ if(NOT ${BUILD_SHARED_LIBS} STREQUAL "OFF") 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() get_directory_property(PROJECT_PARENT_DIR DIRECTORY ${PROJECT_SOURCE_DIR} PARENT_DIRECTORY) @@ -206,6 +203,14 @@ if((${CMAKE_SYSTEM_NAME} MATCHES "Linux") OR (${CMAKE_SYSTEM_NAME} MATCHES "Free 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-sharedlib\"") +elseif(${BUILD_SHARED_LIBS} STREQUAL "OFF") + set(ADDITIONAL_DEFAULT_LDC_SWITCHES ",\n \"-link-sharedlib=false\"") +endif() + configure_file(${PROJECT_PARENT_DIR}/${CONFIG_NAME}.conf.in ${PROJECT_BINARY_DIR}/../bin/${LDC_EXE}.conf) # Prepare the config files we are going to install later in bin. configure_file(${PROJECT_PARENT_DIR}/${LDC_EXE}_install.conf.in ${PROJECT_BINARY_DIR}/../bin/${LDC_EXE}_install.conf) @@ -667,8 +672,8 @@ function(build_test_runners name_suffix path_suffix is_shared) add_test(NAME build-druntime-test-runner${target_suffix} COMMAND ${LDC_EXE_FULL} -of${PROJECT_BINARY_DIR}/druntime-test-runner${target_suffix}${CMAKE_EXECUTABLE_SUFFIX} - -defaultlib= -debuglib= - ${tmpflags} ${RUNTIME_DIR}/src/test_runner.d + ${tmpflags} -defaultlib= + ${RUNTIME_DIR}/src/test_runner.d ) set_tests_properties(build-druntime-test-runner${target_suffix} PROPERTIES DEPENDS build-druntime-ldc-unittest${target_suffix}) @@ -680,8 +685,8 @@ function(build_test_runners name_suffix path_suffix is_shared) add_test(NAME build-phobos2-test-runner${target_suffix} COMMAND ${LDC_EXE_FULL} -of${PROJECT_BINARY_DIR}/phobos2-test-runner${target_suffix}${CMAKE_EXECUTABLE_SUFFIX} - -defaultlib=${libarg} -debuglib=${libarg} - ${tmpflags} ${RUNTIME_DIR}/src/test_runner.d + ${tmpflags} -defaultlib=${libarg} -link-debuglib=false -link-sharedlib=false + ${RUNTIME_DIR}/src/test_runner.d ) set_tests_properties(build-phobos2-test-runner${target_suffix} PROPERTIES DEPENDS "build-druntime-ldc-unittest${target_suffix};build-phobos2-ldc-unittest${target_suffix}"