diff --git a/lld/CMakeLists.txt b/lld/CMakeLists.txt --- a/lld/CMakeLists.txt +++ b/lld/CMakeLists.txt @@ -176,6 +176,13 @@ add_definitions("-DLLD_DEFAULT_LD_LLD_IS_MINGW=1") endif() +option(LLD_ENABLE_ELF_LINKER "Build the ELF linker" ON) +option(LLD_ENABLE_COFF_LINKER "Build the COFF linker" ON) +option(LLD_ENABLE_MACHO_LINKER "Build the Mach-O linker" ON) +option(LLD_ENABLE_WASM_LINKER "Build the WASM linker" ON) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/lld/Common/config.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/include/lld/Common/config.h) + if (MSVC) add_definitions(-wd4530) # Suppress 'warning C4530: C++ exception handler used, but unwind semantics are not enabled.' add_definitions(-wd4062) # Suppress 'warning C4062: enumerator X in switch of enum Y is not handled' from system header. @@ -195,7 +202,9 @@ endif() add_subdirectory(Common) -add_subdirectory(lib) +if (LLD_ENABLE_MACHO_LINKER) + add_subdirectory(lib) +endif() add_subdirectory(tools/lld) if (LLVM_INCLUDE_TESTS) @@ -204,10 +213,18 @@ endif() add_subdirectory(docs) -add_subdirectory(COFF) -add_subdirectory(ELF) -add_subdirectory(MachO) -add_subdirectory(MinGW) -add_subdirectory(wasm) +if (LLD_ENABLE_COFF_LINKER) + add_subdirectory(COFF) + add_subdirectory(MinGW) +endif() +if (LLD_ENABLE_ELF_LINKER) + add_subdirectory(ELF) +endif() +if (LLD_ENABLE_MACHO_LINKER) + add_subdirectory(MachO) +endif() +if (LLD_ENABLE_WASM_LINKER) + add_subdirectory(wasm) +endif() add_subdirectory(cmake/modules) diff --git a/lld/include/lld/Common/config.h.cmake b/lld/include/lld/Common/config.h.cmake new file mode 100644 --- /dev/null +++ b/lld/include/lld/Common/config.h.cmake @@ -0,0 +1,4 @@ +#cmakedefine01 LLD_ENABLE_COFF_LINKER +#cmakedefine01 LLD_ENABLE_ELF_LINKER +#cmakedefine01 LLD_ENABLE_MACHO_LINKER +#cmakedefine01 LLD_ENABLE_WASM_LINKER diff --git a/lld/test/COFF/lit.local.cfg b/lld/test/COFF/lit.local.cfg --- a/lld/test/COFF/lit.local.cfg +++ b/lld/test/COFF/lit.local.cfg @@ -1 +1,4 @@ +if 'lld-coff' not in config.available_features: + config.unsupported = True + config.environment['LLD_IN_TEST'] = '2' diff --git a/lld/test/ELF/lit.local.cfg b/lld/test/ELF/lit.local.cfg --- a/lld/test/ELF/lit.local.cfg +++ b/lld/test/ELF/lit.local.cfg @@ -1 +1,4 @@ +if 'lld-elf' not in config.available_features: + config.unsupported = True + config.suffixes = ['.test', '.s', '.ll', '.bat'] diff --git a/lld/test/MachO/lit.local.cfg b/lld/test/MachO/lit.local.cfg --- a/lld/test/MachO/lit.local.cfg +++ b/lld/test/MachO/lit.local.cfg @@ -2,6 +2,9 @@ import os +if 'lld-macho' not in config.available_features: + config.unsupported = True + # We specify the most commonly-used archs and platform versions in our tests # here. Tests which need different settings can just append to this, as only # the last value will be used. diff --git a/lld/test/MinGW/lit.local.cfg b/lld/test/MinGW/lit.local.cfg new file mode 100644 --- /dev/null +++ b/lld/test/MinGW/lit.local.cfg @@ -0,0 +1,2 @@ +if 'lld-coff' not in config.available_features: + config.unsupported = True diff --git a/lld/test/darwin/lit.local.cfg b/lld/test/darwin/lit.local.cfg new file mode 100644 --- /dev/null +++ b/lld/test/darwin/lit.local.cfg @@ -0,0 +1,2 @@ +if 'lld-macho' not in config.available_features: + config.unsupported = True diff --git a/lld/test/lit.cfg.py b/lld/test/lit.cfg.py --- a/lld/test/lit.cfg.py +++ b/lld/test/lit.cfg.py @@ -99,6 +99,15 @@ if config.have_dia_sdk: config.available_features.add("diasdk") +if config.have_lld_coff_linker: + config.available_features.add('lld-coff') +if config.have_lld_elf_linker: + config.available_features.add('lld-elf') +if config.have_lld_macho_linker: + config.available_features.add('lld-macho') +if config.have_lld_wasm_linker: + config.available_features.add('lld-wasm') + if config.sizeof_void_p == 8: config.available_features.add("llvm-64-bits") diff --git a/lld/test/lit.site.cfg.py.in b/lld/test/lit.site.cfg.py.in --- a/lld/test/lit.site.cfg.py.in +++ b/lld/test/lit.site.cfg.py.in @@ -20,6 +20,11 @@ config.sizeof_void_p = @CMAKE_SIZEOF_VOID_P@ config.ld_lld_default_mingw = @LLD_DEFAULT_LD_LLD_IS_MINGW@ +config.have_lld_coff_linker = lit.util.pythonize_bool("@LLD_ENABLE_COFF_LINKER@") +config.have_lld_elf_linker = lit.util.pythonize_bool("@LLD_ENABLE_ELF_LINKER@") +config.have_lld_macho_linker = lit.util.pythonize_bool("@LLD_ENABLE_MACHO_LINKER@") +config.have_lld_wasm_linker = lit.util.pythonize_bool("@LLD_ENABLE_WASM_LINKER@") + # Support substitution of the tools and libs dirs with user parameters. This is # used when we can't determine the tool dir at configuration time. try: diff --git a/lld/test/mach-o/lit.local.cfg b/lld/test/mach-o/lit.local.cfg --- a/lld/test/mach-o/lit.local.cfg +++ b/lld/test/mach-o/lit.local.cfg @@ -1,3 +1,5 @@ +if 'lld-macho' not in config.available_features: + config.unsupported = True # mach-o test cases encode input files in yaml and use .yaml extension config.suffixes = ['.yaml'] diff --git a/lld/test/wasm/lit.local.cfg b/lld/test/wasm/lit.local.cfg --- a/lld/test/wasm/lit.local.cfg +++ b/lld/test/wasm/lit.local.cfg @@ -1,4 +1,4 @@ -if 'wasm' not in config.available_features: +if 'wasm' not in config.available_features or 'lld-wasm' not in config.available_features: config.unsupported = True config.suffixes = ['.test', '.yaml', '.ll', '.s'] diff --git a/lld/tools/lld/CMakeLists.txt b/lld/tools/lld/CMakeLists.txt --- a/lld/tools/lld/CMakeLists.txt +++ b/lld/tools/lld/CMakeLists.txt @@ -12,20 +12,31 @@ target_link_libraries(lld PRIVATE lldCommon - lldCOFF - lldDriver - lldELF - lldMachO - lldMinGW - lldWasm ) +set(LLD_DEFAULT_SYMLINKS) +if (LLD_ENABLE_COFF_LINKER) + target_link_libraries(lld PRIVATE lldCOFF lldMinGW) + list(APPEND LLD_DEFAULT_SYMLINKS ld.lld lld-link) +endif() +if (LLD_ENABLE_ELF_LINKER) + target_link_libraries(lld PRIVATE lldELF) + list(APPEND LLD_DEFAULT_SYMLINKS ld.lld) +endif() +if (LLD_ENABLE_MACHO_LINKER) + target_link_libraries(lld PRIVATE lldDriver lldMachO) + list(APPEND LLD_DEFAULT_SYMLINKS ld64.lld ld64.lld.darwinnew ld64.lld.darwinold) +endif() +if (LLD_ENABLE_WASM_LINKER) + target_link_libraries(lld PRIVATE lldWasm) + list(APPEND LLD_DEFAULT_SYMLINKS wasm-ld) +endif() +list(REMOVE_DUPLICATES LLD_DEFAULT_SYMLINKS) install(TARGETS lld RUNTIME DESTINATION bin) if(NOT LLD_SYMLINKS_TO_CREATE) - set(LLD_SYMLINKS_TO_CREATE - lld-link ld.lld ld64.lld ld64.lld.darwinnew ld64.lld.darwinold wasm-ld) + set(LLD_SYMLINKS_TO_CREATE ${LLD_DEFAULT_SYMLINKS}) endif() foreach(link ${LLD_SYMLINKS_TO_CREATE}) diff --git a/lld/tools/lld/lld.cpp b/lld/tools/lld/lld.cpp --- a/lld/tools/lld/lld.cpp +++ b/lld/tools/lld/lld.cpp @@ -25,6 +25,8 @@ // //===----------------------------------------------------------------------===// +#include "lld/Common/config.h" + #include "lld/Common/Driver.h" #include "lld/Common/ErrorHandler.h" #include "lld/Common/Memory.h" @@ -60,6 +62,11 @@ exit(1); } +[[noreturn]] LLVM_ATTRIBUTE_UNUSED static void +missingLinkerSupport(StringRef format) { + die(format + " support in lld was disabled. Please use a different linker"); +} + static Flavor getFlavor(StringRef s) { return StringSwitch(s) .CasesLower("ld", "ld.lld", "gnu", Gnu) @@ -144,17 +151,42 @@ std::vector args(argv, argv + argc); switch (parseFlavor(args)) { case Gnu: - if (isPETarget(args)) + if (isPETarget(args)) { +#if !LLD_ENABLE_COFF_LINKER + missingLinkerSupport("COFF"); +#else return !mingw::link(args, exitEarly, stdoutOS, stderrOS); +#endif + } +#if !LLD_ENABLE_ELF_LINKER + missingLinkerSupport("ELF"); +#else return !elf::link(args, exitEarly, stdoutOS, stderrOS); +#endif case WinLink: +#if !LLD_ENABLE_COFF_LINKER + missingLinkerSupport("COFF"); +#else return !coff::link(args, exitEarly, stdoutOS, stderrOS); +#endif case Darwin: +#if !LLD_ENABLE_MACHO_LINKER + missingLinkerSupport("Mach-O"); +#else return !macho::link(args, exitEarly, stdoutOS, stderrOS); +#endif case DarwinOld: +#if !LLD_ENABLE_MACHO_LINKER + missingLinkerSupport("Mach-O"); +#else return !mach_o::link(args, exitEarly, stdoutOS, stderrOS); +#endif case Wasm: +#if !LLD_ENABLE_WASM_LINKER + missingLinkerSupport("WASM"); +#else return !lld::wasm::link(args, exitEarly, stdoutOS, stderrOS); +#endif default: die("lld is a generic driver.\n" "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld" diff --git a/lld/unittests/CMakeLists.txt b/lld/unittests/CMakeLists.txt --- a/lld/unittests/CMakeLists.txt +++ b/lld/unittests/CMakeLists.txt @@ -12,5 +12,8 @@ target_link_libraries(${test_dirname} ${LLVM_COMMON_LIBS}) endfunction() -add_subdirectory(DriverTests) -add_subdirectory(MachOTests) +# Currently, all unit tests depend on the old Mach-O linker +if (LLD_ENABLE_MACHO_LINKER) + add_subdirectory(DriverTests) + add_subdirectory(MachOTests) +endif()