Skip to content

Commit e2aa7a6

Browse files
committed
[Driver] Infer target-specific dylib names
When the Swift driver is invoked with the `-emit-library` option, but without an `-o` option that specifies the emitted library's filename, logic in the `getOutputFilename()` function derives a filename: `"lib" + <a plasible base name>"`, and then the value of the `LTDL_SHLIB_EXT` macro. There are two problems here: 1. Windows shared library file names, by convention, do not begin with "lib". 2. The `LTDL_SHLIB_EXT` macro is set by `llvm/cmake/modules/HandleLLVMOptions.cmake`, based on `CMAKE_SHARED_LIBRARY_SUFFIX`, a built-in CMake variable that is set at the time LLVM is configured to be built. So, if LLVM and Swift were built on a Linux machine, but the `swiftc` executable that was built was then invoked to produce a shared library for a Darwin target, the library would have a ".so" suffix, not ".dylib". (It's for this reason that the tests for this name inference, in `test/Driver/linker.swift`, must use a regular expression that matches both ".dylib" and ".so", despite specifying a Darwin `-target`.) In order to produce conventionally correct prefixes and suffixes based on the target, modify the `getOutputFilename()` function to take an `llvm::Triple` argument.
1 parent 92d9b3a commit e2aa7a6

File tree

2 files changed

+31
-15
lines changed

2 files changed

+31
-15
lines changed

lib/Driver/Driver.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,7 @@ static StringRef getOutputFilename(Compilation &C,
17261726
const JobAction *JA,
17271727
const OutputInfo &OI,
17281728
const TypeToPathMap *OutputMap,
1729+
const llvm::Triple &Triple,
17291730
const llvm::opt::DerivedArgList &Args,
17301731
bool AtTopLevel,
17311732
StringRef BaseInput,
@@ -1814,10 +1815,17 @@ static StringRef getOutputFilename(Compilation &C,
18141815
BaseName = llvm::sys::path::stem(BaseInput);
18151816
if (auto link = dyn_cast<LinkJobAction>(JA)) {
18161817
if (link->getKind() == LinkKind::DynamicLibrary) {
1817-
// FIXME: This should be target-specific.
1818-
Buffer = "lib";
1818+
if (Triple.isOSWindows())
1819+
Buffer = "";
1820+
else
1821+
Buffer = "lib";
18191822
Buffer.append(BaseName);
1820-
Buffer.append(LTDL_SHLIB_EXT);
1823+
if (Triple.isOSDarwin())
1824+
Buffer.append(".dylib");
1825+
else if (Triple.isOSWindows())
1826+
Buffer.append(".dll");
1827+
else
1828+
Buffer.append(".so");
18211829
return Buffer.str();
18221830
}
18231831
}
@@ -2030,9 +2038,9 @@ Job *Driver::buildJobsForAction(Compilation &C, const JobAction *JA,
20302038
const TypeToPathMap *OMForInput = nullptr;
20312039
if (OFM)
20322040
OMForInput = OFM->getOutputMapForInput(Input);
2033-
2034-
OutputFile = getOutputFilename(C, JA, OI, OMForInput, C.getArgs(),
2035-
AtTopLevel, Input, InputJobs,
2041+
2042+
OutputFile = getOutputFilename(C, JA, OI, OMForInput, TC.getTriple(),
2043+
C.getArgs(), AtTopLevel, Input, InputJobs,
20362044
Diags, Buf);
20372045
Output->addPrimaryOutput(OutputFile, Input);
20382046
};
@@ -2048,9 +2056,9 @@ Job *Driver::buildJobsForAction(Compilation &C, const JobAction *JA,
20482056
}
20492057
} else {
20502058
// The common case: there is a single output file.
2051-
OutputFile = getOutputFilename(C, JA, OI, OutputMap, C.getArgs(),
2052-
AtTopLevel, BaseInput, InputJobs,
2053-
Diags, Buf);
2059+
OutputFile = getOutputFilename(C, JA, OI, OutputMap, TC.getTriple(),
2060+
C.getArgs(), AtTopLevel, BaseInput,
2061+
InputJobs, Diags, Buf);
20542062
Output->addPrimaryOutput(OutputFile, BaseInput);
20552063
}
20562064

test/Driver/linker.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,14 @@
5151
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 %s %t/a.o -o linker 2>&1 | %FileCheck -check-prefix COMPILE_AND_LINK %s
5252
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 %s %t/a.o -driver-use-filelists -o linker 2>&1 | %FileCheck -check-prefix FILELIST %s
5353

54-
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 -emit-library %s -module-name LINKER | %FileCheck -check-prefix INFERRED_NAME %s
55-
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 -emit-library %s -o libLINKER.dylib | %FileCheck -check-prefix INFERRED_NAME %s
54+
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 -emit-library %s -module-name LINKER | %FileCheck -check-prefix INFERRED_NAME_DARWIN %s
55+
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-unknown-linux-gnu -emit-library %s -module-name LINKER | %FileCheck -check-prefix INFERRED_NAME_LINUX %s
56+
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-unknown-windows-cygnus -emit-library %s -module-name LINKER | %FileCheck -check-prefix INFERRED_NAME_WINDOWS %s
57+
58+
// Here we specify an output file name using '-o'. For ease of writing these
59+
// tests, we happen to specify the same file name as is inferred in the
60+
// INFERRED_NAMED_DARWIN tests above: 'libLINKER.dylib'.
61+
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 -emit-library %s -o libLINKER.dylib | %FileCheck -check-prefix INFERRED_NAME_DARWIN %s
5662

5763
// There are more RUN lines further down in the file.
5864

@@ -285,10 +291,12 @@
285291
// FILELIST: -o linker
286292

287293

288-
// INFERRED_NAME: bin/swift
289-
// INFERRED_NAME: -module-name LINKER
290-
// INFERRED_NAME: bin/ld{{"? }}
291-
// INFERRED_NAME: -o libLINKER.{{dylib|so}}
294+
// INFERRED_NAME_DARWIN: bin/swift
295+
// INFERRED_NAME_DARWIN: -module-name LINKER
296+
// INFERRED_NAME_DARWIN: bin/ld{{"? }}
297+
// INFERRED_NAME_DARWIN: -o libLINKER.dylib
298+
// INFERRED_NAME_LINUX: -o libLINKER.so
299+
// INFERRED_NAME_WINDOWS: -o LINKER.dll
292300

293301

294302
// Test ld detection. We use hard links to make sure

0 commit comments

Comments
 (0)