Skip to content

Driver: prevent C++ runtime linkage #26110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions lib/Driver/UnixToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,29 @@ toolchains::GenericUnix::constructInvocation(const DynamicLinkJobAction &job,
}

// Configure the toolchain.
// By default, use the system clang++ to link.
const char *Clang = "clang++";
//
// By default use the system `clang` to perform the link. We use `clang` for
// the driver here because we do not wish to select a particular C++ runtime.
// Furthermore, until C++ interop is enabled, we cannot have a dependency on
// C++ code from pure Swift code. If linked libraries are C++ based, they
// should properly link C++. In the case of static linking, the user can
// explicitly specify the C++ runtime to link against. This is particularly
// important for platforms like android where as it is a Linux platform, the
// default C++ runtime is `libstdc++` which is unsupported on the target but
// as the builds are usually cross-compiled from Linux, libstdc++ is going to
// be present. This results in linking the wrong version of libstdc++
// generating invalid binaries. It is also possible to use different C++
// runtimes than the default C++ runtime for the platform (e.g. libc++ on
// Windows rather than msvcprt). When C++ interop is enabled, we will need to
// surface this via a driver flag. For now, opt for the simpler approach of
// just using `clang` and avoid a dependency on the C++ runtime.
const char *Clang = "clang";
if (const Arg *A = context.Args.getLastArg(options::OPT_tools_directory)) {
StringRef toolchainPath(A->getValue());

// If there is a clang in the toolchain folder, use that instead.
if (auto toolchainClang =
llvm::sys::findProgramByName("clang++", {toolchainPath})) {
Clang = context.Args.MakeArgString(toolchainClang.get());
if (auto tool = llvm::sys::findProgramByName("clang", {toolchainPath})) {
Clang = context.Args.MakeArgString(tool.get());
}

// Look for binutils in the toolchain folder.
Expand Down
24 changes: 19 additions & 5 deletions lib/Driver/WindowsToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,29 @@ toolchains::Windows::constructInvocation(const DynamicLinkJobAction &job,
}

// Configure the toolchain.
// By default, use the system clang++ to link.
const char *Clang = "clang++";
//
// By default use the system `clang` to perform the link. We use `clang` for
// the driver here because we do not wish to select a particular C++ runtime.
// Furthermore, until C++ interop is enabled, we cannot have a dependency on
// C++ code from pure Swift code. If linked libraries are C++ based, they
// should properly link C++. In the case of static linking, the user can
// explicitly specify the C++ runtime to link against. This is particularly
// important for platforms like android where as it is a Linux platform, the
// default C++ runtime is `libstdc++` which is unsupported on the target but
// as the builds are usually cross-compiled from Linux, libstdc++ is going to
// be present. This results in linking the wrong version of libstdc++
// generating invalid binaries. It is also possible to use different C++
// runtimes than the default C++ runtime for the platform (e.g. libc++ on
// Windows rather than msvcprt). When C++ interop is enabled, we will need to
// surface this via a driver flag. For now, opt for the simpler approach of
// just using `clang` and avoid a dependency on the C++ runtime.
const char *Clang = "clang";
if (const Arg *A = context.Args.getLastArg(options::OPT_tools_directory)) {
StringRef toolchainPath(A->getValue());

// If there is a clang in the toolchain folder, use that instead.
if (auto toolchainClang =
llvm::sys::findProgramByName("clang++", {toolchainPath}))
Clang = context.Args.MakeArgString(toolchainClang.get());
if (auto tool = llvm::sys::findProgramByName("clang", {toolchainPath}))
Clang = context.Args.MakeArgString(tool.get());
}

std::string Target = getTriple().str();
Expand Down
4 changes: 2 additions & 2 deletions test/Driver/embed-bitcode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
// CHECK-macho: "ld", inputs: ["[[OBJECT]]"], output: {image: "embed-bitcode"}
// CHECK-coff: "swiftc.EXE", inputs: ["{{.*}}embed-bitcode.swift"], output: {llvm-bc: "[[BC:.*\.bc]]"}
// CHECK-coff: "swiftc.EXE", inputs: ["[[BC]]"], output: {object: "[[OBJECT:.*\.o]]"}
// CHECK-coff: "clang++.exe", inputs: ["[[OBJECT]]"], output: {image: "embed-bitcode"}
// CHECK-coff: "clang.exe", inputs: ["[[OBJECT]]"], output: {image: "embed-bitcode"}

// CHECK-elf: "swift", inputs: ["{{.*}}embed-bitcode.swift"], output: {llvm-bc: "[[BC:.*\.bc]]"}
// CHECK-elf: "swift", inputs: ["[[BC]]"], output: {object: "[[OBJECT:.*\.o]]"}
// CHECK-elf: "swift-autolink-extract", inputs: ["[[OBJECT]]"], output: {autolink: "[[AUTOLINK:.*\.autolink]]"}
// CHECK-elf: "clang++", inputs: ["[[OBJECT]]", "[[AUTOLINK]]"], output: {image: "main"}
// CHECK-elf: "clang", inputs: ["[[OBJECT]]", "[[AUTOLINK]]"], output: {image: "main"}

// RUN: %target-swiftc_driver -embed-bitcode %s 2>&1 -### | %FileCheck %s -check-prefix=CHECK-FRONT -check-prefix=CHECK-FRONT-%target-object-format
// CHECK-FRONT: -frontend
Expand Down
2 changes: 1 addition & 1 deletion test/Driver/linker-autolink-extract.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// DEBUG_LINUX-NEXT: bin/swift-autolink-extract
// DEBUG_LINUX-NEXT: bin/swift
// DEBUG_LINUX-NEXT: bin/swift -modulewrap
// DEBUG_LINUX-NEXT: bin/clang++{{"? }}
// DEBUG_LINUX-NEXT: bin/clang{{"? }}
// DEBUG_LINUX: -o main
// DEBUG_LINUX-NOT: dsymutil

22 changes: 11 additions & 11 deletions test/Driver/linker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@
// LINUX-x86_64: swift
// LINUX-x86_64: -o [[OBJECTFILE:.*]]

// LINUX-x86_64: clang++{{(\.exe)?"? }}
// LINUX-x86_64: clang{{(\.exe)?"? }}
// LINUX-x86_64-DAG: -pie
// LINUX-x86_64-DAG: [[OBJECTFILE]]
// LINUX-x86_64-DAG: -lswiftCore
Expand All @@ -163,7 +163,7 @@
// LINUX-armv6: swift
// LINUX-armv6: -o [[OBJECTFILE:.*]]

// LINUX-armv6: clang++{{(\.exe)?"? }}
// LINUX-armv6: clang{{(\.exe)?"? }}
// LINUX-armv6-DAG: -pie
// LINUX-armv6-DAG: [[OBJECTFILE]]
// LINUX-armv6-DAG: -lswiftCore
Expand All @@ -180,7 +180,7 @@
// LINUX-armv7: swift
// LINUX-armv7: -o [[OBJECTFILE:.*]]

// LINUX-armv7: clang++{{(\.exe)?"? }}
// LINUX-armv7: clang{{(\.exe)?"? }}
// LINUX-armv7-DAG: -pie
// LINUX-armv7-DAG: [[OBJECTFILE]]
// LINUX-armv7-DAG: -lswiftCore
Expand All @@ -197,7 +197,7 @@
// LINUX-thumbv7: swift
// LINUX-thumbv7: -o [[OBJECTFILE:.*]]

// LINUX-thumbv7: clang++{{(\.exe)?"? }}
// LINUX-thumbv7: clang{{(\.exe)?"? }}
// LINUX-thumbv7-DAG: -pie
// LINUX-thumbv7-DAG: [[OBJECTFILE]]
// LINUX-thumbv7-DAG: -lswiftCore
Expand All @@ -214,7 +214,7 @@
// ANDROID-armv7: swift
// ANDROID-armv7: -o [[OBJECTFILE:.*]]

// ANDROID-armv7: clang++{{(\.exe)?"? }}
// ANDROID-armv7: clang{{(\.exe)?"? }}
// ANDROID-armv7-DAG: -pie
// ANDROID-armv7-DAG: [[OBJECTFILE]]
// ANDROID-armv7-DAG: -lswiftCore
Expand All @@ -231,7 +231,7 @@
// CYGWIN-x86_64: swift
// CYGWIN-x86_64: -o [[OBJECTFILE:.*]]

// CYGWIN-x86_64: clang++{{(\.exe)?"? }}
// CYGWIN-x86_64: clang{{(\.exe)?"? }}
// CYGWIN-x86_64-DAG: [[OBJECTFILE]]
// CYGWIN-x86_64-DAG: -lswiftCore
// CYGWIN-x86_64-DAG: -L [[STDLIB_PATH:[^ ]+(/|\\\\)lib(/|\\\\)swift]]
Expand All @@ -246,7 +246,7 @@
// WINDOWS-x86_64: swift
// WINDOWS-x86_64: -o [[OBJECTFILE:.*]]

// WINDOWS-x86_64: clang++{{(\.exe)?"? }}
// WINDOWS-x86_64: clang{{(\.exe)?"? }}
// WINDOWS-x86_64-DAG: [[OBJECTFILE]]
// WINDOWS-x86_64-DAG: -L [[STDLIB_PATH:[^ ]+(/|\\\\)lib(/|\\\\)swift(/|\\\\)windows(/|\\\\)x86_64]]
// WINDOWS-x86_64-DAG: -F foo -iframework car -F cdr
Expand All @@ -272,7 +272,7 @@
// LINUX_DYNLIB-x86_64: -o [[OBJECTFILE:.*]]
// LINUX_DYNLIB-x86_64: -o {{"?}}[[AUTOLINKFILE:.*]]

// LINUX_DYNLIB-x86_64: clang++{{(\.exe)?"? }}
// LINUX_DYNLIB-x86_64: clang{{(\.exe)?"? }}
// LINUX_DYNLIB-x86_64-DAG: -shared
// LINUX_DYNLIB-x86_64-DAG: -fuse-ld=gold
// LINUX_DYNLIB-x86_64-NOT: -pie
Expand All @@ -297,7 +297,7 @@
// LINUX-linker-order: swift
// LINUX-linker-order: -o [[OBJECTFILE:.*]]

// LINUX-linker-order: clang++{{(\.exe)?"? }}
// LINUX-linker-order: clang{{(\.exe)?"? }}
// LINUX-linker-order: -Xlinker -rpath -Xlinker {{[^ ]+(/|\\\\)lib(/|\\\\)swift(/|\\\\)linux}}
// LINUX-linker-order: -L foo
// LINUX-linker-order: -Xlinker -rpath -Xlinker customrpath
Expand All @@ -306,14 +306,14 @@
// LINUX-clang-linker-order: swift
// LINUX-clang-linker-order: -o [[OBJECTFILE:.*]]

// LINUX-clang-linker-order: clang++{{"? }}
// LINUX-clang-linker-order: clang{{"? }}
// LINUX-clang-linker-order: -foo foopath
// LINUX-clang-linker-order: -o {{.*}}

// WINDOWS-clang-linker-order: swift
// WINDOWS-clang-linker-order: -o [[OBJECTFILE:.*]]

// WINDOWS-clang-linker-order: clang++{{"? }}
// WINDOWS-clang-linker-order: clang{{"? }}
// WINDOWS-clang-linker-order: -foo foopath
// WINDOWS-clang-linker-order: -o {{.*}}

Expand Down
2 changes: 1 addition & 1 deletion test/Driver/modulewrap.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
// CHECK: bin{{/|\\\\}}swift{{c?(\.EXE)?"?}} {{.*}}-emit-module [[MOD]]
// CHECK-SAME: -o [[MERGED:.*\.swiftmodule]]
// CHECK: bin{{/|\\\\}}swift{{c?(\.EXE)?"?}} -modulewrap [[MERGED]]{{"?}} -target x86_64-unknown-linux-gnu -o [[OBJ:.*\.o]]
// CHECK: bin{{/|\\\\}}clang++{{.*}} [[OBJ]]
// CHECK: bin{{/|\\\\}}clang{{.*}} [[OBJ]]
10 changes: 5 additions & 5 deletions test/Driver/multi-threaded.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,27 @@
// MODULE-DAG: -num-threads 4
// MODULE-DAG: {{[^ ]*[/\\]}}Inputs{{/|\\\\}}main.swift{{"?}} {{[^ ]*[/\\]}}multi-threaded.swift
// MODULE-DAG: -o test.swiftmodule
// MODULE-NOT: {{ld|clang\+\+}}
// MODULE-NOT: {{ld|clang}}

// ASSEMBLY: -frontend
// ASSEMBLY-DAG: -num-threads 4
// ASSEMBLY-DAG: {{[^ ]*[/\\]}}Inputs{{/|\\\\}}main.swift{{"?}} {{[^ ]*[/\\]}}multi-threaded.swift
// ASSEMBLY-DAG: -o /build/main.s -o /build/multi-threaded.s
// ASSEMBLY-NOT: {{ld|clang\+\+}}
// ASSEMBLY-NOT: {{ld|clang}}

// OBJECT: -frontend
// OBJECT-DAG: -num-threads 4
// OBJECT-DAG: {{[^ ]*[/\\]}}Inputs{{/|\\\\}}main.swift{{"?}} {{[^ ]*[/\\]}}multi-threaded.swift
// OBJECT-DAG: -o main.o -o multi-threaded.o
// OBJECT-NOT: {{ld|clang\+\+}}
// OBJECT-NOT: {{ld|clang}}

// BITCODE: -frontend
// BITCODE-DAG: -num-threads 4
// BITCODE-DAG: {{[^ ]*[/\\]}}Inputs{{/|\\\\}}main.swift{{"?}} {{[^ ]*[/\\]}}multi-threaded.swift
// BITCODE-DAG: -o {{.*[/\\]}}main.bc -o {{.*[/\\]}}multi-threaded.bc
// BITCODE-DAG: -frontend -c -primary-file {{.*[/\\]}}main.bc {{.*}} -o {{[^ ]*}}main.o
// BITCODE-DAG: -frontend -c -primary-file {{.*[/\\]}}multi-threaded.bc {{.*}} -o {{[^ ]*}}multi-threaded.o
// BITCODE-NOT: {{ld|clang\+\+}}
// BITCODE-NOT: {{ld|clang}}

// PARSEABLE: "outputs": [
// PARSEABLE: "path": "main.o"
Expand All @@ -55,7 +55,7 @@
// EXEC-DAG: -num-threads 4
// EXEC-DAG: {{[^ ]*[/\\]}}Inputs{{/|\\\\}}main.swift{{"?}} {{[^ ]*[/\\]}}multi-threaded.swift
// EXEC-DAG: -o {{.*te?mp.*[/\\]}}main{{[^ ]*}}.o{{"?}} -o {{.*te?mp.*[/\\]}}multi-threaded{{[^ ]*}}.o
// EXEC: {{ld|clang\+\+}}
// EXEC: {{ld|clang}}
// EXEC: {{.*te?mp.*[/\\]}}main{{[^ ]*}}.o{{"?}} {{.*te?mp.*[/\\]}}multi-threaded{{[^ ]*}}.o

// DEPENDENCIES-DAG: {{.*}}multi-threaded.o : {{.*[/\\]}}multi-threaded.swift {{.*[/\\]}}Inputs{{[/\\]}}main.swift
Expand Down
4 changes: 2 additions & 2 deletions test/Driver/parseable_output.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "began",
// CHECK-NEXT: "name": "link",
// CHECK-NEXT: "command": "{{.*[\\/](ld|clang\+\+)(\.exe)?(\\")?.*}}parseable_output-[[OUTPUT]].o{{(\\")?}} {{.*}}-o {{.*[\\/]}}parseable_output.swift.tmp.out{{(\\")?}}",
// CHECK-NEXT: "command_executable": "{{.*[\\/](ld|clang\+\+)(\.exe)?}}",
// CHECK-NEXT: "command": "{{.*[\\/](ld|clang)(\.exe)?(\\")?.*}}parseable_output-[[OUTPUT]].o{{(\\")?}} {{.*}}-o {{.*[\\/]}}parseable_output.swift.tmp.out{{(\\")?}}",
// CHECK-NEXT: "command_executable": "{{.*[\\/](ld|clang)(\.exe)?}}",
// CHECK-NEXT: "command_arguments": [
// CHECK: "{{.*[\\/]}}parseable_output-[[OUTPUT]].o",
// CHECK: "-o",
Expand Down
4 changes: 2 additions & 2 deletions test/Driver/parseable_output_unicode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "began",
// CHECK-NEXT: "name": "link",
// CHECK-NEXT: "command": "{{.*[\\/](ld|clang\+\+.exe)(\\")?}} {{.*[\\/]}}你好-[[OUTPUT]].o{{(\\")?}}{{.*}}-o {{.*[\\/]}}parseable_output_unicode.swift.tmp.out{{(\\")?}}",
// CHECK-NEXT: "command_executable": "{{.*[\\/](ld|clang\+\+.exe)(\\")?}}",
// CHECK-NEXT: "command": "{{.*[\\/](ld|clang.exe)(\\")?}} {{.*[\\/]}}你好-[[OUTPUT]].o{{(\\")?}}{{.*}}-o {{.*[\\/]}}parseable_output_unicode.swift.tmp.out{{(\\")?}}",
// CHECK-NEXT: "command_executable": "{{.*[\\/](ld|clang.exe)(\\")?}}",
// CHECK-NEXT: "command_arguments": [
// CHECK: "{{.*[\\/]}}你好-[[OUTPUT]].o",
// CHECK: "-o",
Expand Down
4 changes: 2 additions & 2 deletions test/Driver/profiling.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@
// watchOS_SIM: {{(bin/)?ld(.exe)?"? }}
// watchOS_SIM: lib{{(\\\\|/)}}swift{{(\\\\|/)}}clang{{(\\\\|/)}}lib{{(\\\\|/)}}darwin{{(\\\\|/)}}libclang_rt.profile_watchossim.a

// LINUX: clang++{{(\.exe)?"? }}
// LINUX: clang{{(\.exe)?"? }}
// LINUX: lib{{(\\\\|/)}}swift{{(\\\\|/)}}clang{{(\\\\|/)}}lib{{(\\\\|/)}}linux{{(\\\\|/)}}libclang_rt.profile-x86_64.a
// LINUX: -u__llvm_profile_runtime

// WINDOWS: clang++{{(\.exe)?"? }}
// WINDOWS: clang{{(\.exe)?"? }}
// WINDOWS: lib{{(\\\\|/)}}swift{{(\\\\|/)}}clang{{(\\\\|/)}}lib{{(\\\\|/)}}windows{{(\\\\|/)}}clang_rt.profile-x86_64.lib
// WINDOWS: -u__llvm_profile_runtime

Expand Down
6 changes: 3 additions & 3 deletions test/Driver/tools_directory.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//=================================================
// ** GENERIC UNIX TARGETS - linking via clang++ **
// ** GENERIC UNIX TARGETS - linking via clang **
//=================================================

// RUN: %swiftc_driver -### -target x86_64-linux-unknown -tools-directory %S/Inputs/fake-toolchain %s 2>&1 | %FileCheck -check-prefix CLANGSUB %s
Expand All @@ -9,7 +9,7 @@
// CLANGSUB-SAME: -o [[OBJECTFILE:.*]]
// CLANGSUB: swift-autolink-extract{{(\.exe)?"?}} [[OBJECTFILE]]
// CLANGSUB-SAME: -o {{"?}}[[AUTOLINKFILE:.*]]
// CLANGSUB: {{[^ ]+(\\\\|/)}}Inputs{{/|\\\\}}fake-toolchain{{/|\\\\}}clang++
// CLANGSUB: {{[^ ]+(\\\\|/)}}Inputs{{/|\\\\}}fake-toolchain{{/|\\\\}}clang
// CLANGSUB-DAG: [[OBJECTFILE]]
// CLANGSUB-DAG: @[[AUTOLINKFILE]]
// CLANGSUB: -o tools_directory
Expand All @@ -18,7 +18,7 @@
// BINUTILS-SAME: -o [[OBJECTFILE:.*]]
// BINUTILS: swift-autolink-extract{{(\.exe)?"?}} [[OBJECTFILE]]
// BINUTILS-SAME: -o {{"?}}[[AUTOLINKFILE:.*]]
// BINUTILS: clang++
// BINUTILS: clang
// BINUTILS-DAG: [[OBJECTFILE]]
// BINUTILS-DAG: @[[AUTOLINKFILE]]
// BINUTILS-DAG: -B /Something/obviously/fake
Expand Down
2 changes: 1 addition & 1 deletion test/Driver/verbose.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-unknown-linux-gnu -v %s 2>&1 | %FileCheck %s -check-prefix=VERBOSE_CLANG
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-unknown-windows-msvc -v %s 2>&1 | %FileCheck %s -check-prefix=VERBOSE_CLANG

// VERBOSE_CLANG: clang++{{.*}} -v -o
// VERBOSE_CLANG: clang{{.*}} -v -o
2 changes: 1 addition & 1 deletion test/Driver/windows-link-job.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %empty-directory(%t/DISTINCTIVE-WINDOWS-PATH/usr/bin)
// RUN: %hardlink-or-copy(from: %swift_driver_plain, to: %t/DISTINCTIVE-WINDOWS-PATH/usr/bin/swiftc)
// RUN: env PATH= %t/DISTINCTIVE-WINDOWS-PATH/usr/bin/swiftc -target x86_64-unknown-windows-msvc -### -module-name link -emit-library %s 2>&1 | %FileCheck %s
// CHECK: {{^}}clang++
// CHECK: {{^}}clang
2 changes: 2 additions & 0 deletions utils/gen-static-stdlib-link-args
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ function write_linkfile {
-latomic
-lswiftImageInspectionShared
$ICU_LIBS
-lstdc++
-lm
-Xlinker
-export-dynamic
-Xlinker
Expand Down
2 changes: 2 additions & 0 deletions utils/static-executable-args.lnk
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@
-licuuc
-licudata
-ldl
-lstdc++
-lm