Skip to content

Commit 41e58b1

Browse files
committed
Fix multi-arch cross-compiling
On platforms without fat binaries (anything but Darwin), we now build and install stdlibs for each arch in it's own folder. Namely lib/swift/<platform>/<arch> instead of lib/swift/<platform>.
1 parent 7d7e88f commit 41e58b1

File tree

10 files changed

+249
-93
lines changed

10 files changed

+249
-93
lines changed

cmake/modules/AddSwift.cmake

Lines changed: 153 additions & 53 deletions
Large diffs are not rendered by default.

cmake/modules/SwiftConfigureSDK.cmake

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ function(_report_sdk prefix)
2222
message(STATUS " ${arch} LIB: ${${arch}_LIB}")
2323
endforeach()
2424
else()
25-
message(STATUS " Path: ${SWIFT_SDK_${prefix}_PATH}")
25+
foreach(arch ${SWIFT_SDK_${prefix}_ARCHITECTURES})
26+
message(STATUS " ${arch} Path: ${SWIFT_SDK_${prefix}_ARCH_${ARCH}_PATH}")
27+
endforeach()
2628
endif()
2729
message(STATUS " Version: ${SWIFT_SDK_${prefix}_VERSION}")
2830
message(STATUS " Build number: ${SWIFT_SDK_${prefix}_BUILD_NUMBER}")
@@ -122,6 +124,9 @@ macro(configure_sdk_darwin
122124
set(SWIFT_SDK_${prefix}_OBJECT_FORMAT "MACHO")
123125

124126
foreach(arch ${architectures})
127+
# On Darwin, all archs share the same SDK path.
128+
set(SWIFT_SDK_${prefix}_ARCH_${arch}_PATH "${SWIFT_SDK_${prefix}_PATH}")
129+
125130
set(SWIFT_SDK_${prefix}_ARCH_${arch}_TRIPLE
126131
"${arch}-apple-${SWIFT_SDK_${prefix}_TRIPLE_NAME}${SWIFT_SDK_${prefix}_DEPLOYMENT_VERSION}")
127132
endforeach()
@@ -137,8 +142,10 @@ macro(configure_sdk_unix
137142
# Note: this has to be implemented as a macro because it sets global
138143
# variables.
139144

145+
# Todo: this only supports building an SDK for one target arch only.
146+
140147
set(SWIFT_SDK_${prefix}_NAME "${name}")
141-
set(SWIFT_SDK_${prefix}_PATH "${sdkpath}")
148+
set(SWIFT_SDK_${prefix}_ARCH_${arch}_PATH "${sdkpath}")
142149
set(SWIFT_SDK_${prefix}_VERSION "don't use")
143150
set(SWIFT_SDK_${prefix}_BUILD_NUMBER "don't use")
144151
set(SWIFT_SDK_${prefix}_DEPLOYMENT_VERSION "don't use")
@@ -186,6 +193,7 @@ macro(configure_sdk_windows prefix sdk_name environment architectures)
186193
set(SWIFT_SDK_${prefix}_ARCH_${arch}_TRIPLE
187194
"${arch}-unknown-windows-${environment}")
188195
endif()
196+
set(SWIFT_SDK_${prefix}_ARCH_${arch}_PATH "/")
189197
endforeach()
190198

191199
# Add this to the list of known SDKs.

lib/Driver/ToolChains.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,6 +1016,17 @@ static void getRuntimeLibraryPath(SmallVectorImpl<char> &runtimeLibPath,
10161016
getPlatformNameForTriple(TC.getTriple()));
10171017
}
10181018

1019+
/// Get the runtime library link path with the target triple's specific arch
1020+
/// library folder.
1021+
static void getRuntimeLibraryPathWithArch(SmallVectorImpl<char> &runtimeLibPath,
1022+
const llvm::opt::ArgList &args,
1023+
const ToolChain &TC) {
1024+
getRuntimeLibraryPath(runtimeLibPath, args, TC);
1025+
llvm::sys::path::append(runtimeLibPath,
1026+
swift::getMajorArchitectureName(TC.getTriple()));
1027+
1028+
}
1029+
10191030
static void getClangLibraryPathOnDarwin(SmallVectorImpl<char> &libPath,
10201031
const ArgList &args,
10211032
const ToolChain &TC) {
@@ -1037,8 +1048,8 @@ static void getClangLibraryPathOnLinux(SmallVectorImpl<char> &libPath,
10371048
/// Get the runtime library link path for static linking,
10381049
/// which is platform-specific and found relative to the compiler.
10391050
static void getRuntimeStaticLibraryPath(SmallVectorImpl<char> &runtimeLibPath,
1040-
const llvm::opt::ArgList &args,
1041-
const ToolChain &TC) {
1051+
const llvm::opt::ArgList &args,
1052+
const ToolChain &TC) {
10421053
// FIXME: Duplicated from CompilerInvocation, but in theory the runtime
10431054
// library link path and the standard library module import path don't
10441055
// need to be the same.
@@ -1056,6 +1067,18 @@ static void getRuntimeStaticLibraryPath(SmallVectorImpl<char> &runtimeLibPath,
10561067
getPlatformNameForTriple(TC.getTriple()));
10571068
}
10581069

1070+
/// Get the runtime library path with the target triple's arch specific
1071+
/// directory.
1072+
static void getRuntimeStaticLibraryPathWithArch(
1073+
SmallVectorImpl<char> &runtimeLibPath,
1074+
const llvm::opt::ArgList &args,
1075+
const ToolChain &TC) {
1076+
getRuntimeStaticLibraryPath(runtimeLibPath, args, TC);
1077+
llvm::sys::path::append(runtimeLibPath,
1078+
swift::getMajorArchitectureName(TC.getTriple()));
1079+
1080+
}
1081+
10591082
ToolChain::InvocationInfo
10601083
toolchains::Darwin::constructInvocation(const InterpretJobAction &job,
10611084
const JobContext &context) const {
@@ -1477,7 +1500,7 @@ toolchains::GenericUnix::constructInvocation(const InterpretJobAction &job,
14771500
InvocationInfo II = ToolChain::constructInvocation(job, context);
14781501

14791502
SmallString<128> runtimeLibraryPath;
1480-
getRuntimeLibraryPath(runtimeLibraryPath, context.Args, *this);
1503+
getRuntimeLibraryPathWithArch(runtimeLibraryPath, context.Args, *this);
14811504

14821505
addPathEnvironmentVariableIfNeeded(II.ExtraEnvironment, "LD_LIBRARY_PATH",
14831506
":", options::OPT_L, context.Args,
@@ -1610,10 +1633,10 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
16101633
}
16111634

16121635
SmallString<128> SharedRuntimeLibPath;
1613-
getRuntimeLibraryPath(SharedRuntimeLibPath, context.Args, *this);
1636+
getRuntimeLibraryPathWithArch(SharedRuntimeLibPath, context.Args, *this);
16141637

16151638
SmallString<128> StaticRuntimeLibPath;
1616-
getRuntimeStaticLibraryPath(StaticRuntimeLibPath, context.Args, *this);
1639+
getRuntimeStaticLibraryPathWithArch(StaticRuntimeLibPath, context.Args, *this);
16171640

16181641
// Add the runtime library link path, which is platform-specific and found
16191642
// relative to the compiler.
@@ -1627,8 +1650,6 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
16271650
}
16281651

16291652
SmallString<128> swiftrtPath = SharedRuntimeLibPath;
1630-
llvm::sys::path::append(swiftrtPath,
1631-
swift::getMajorArchitectureName(getTriple()));
16321653
llvm::sys::path::append(swiftrtPath, "swiftrt.o");
16331654
Arguments.push_back(context.Args.MakeArgString(swiftrtPath));
16341655

@@ -1664,6 +1685,7 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
16641685
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath));
16651686

16661687
SmallString<128> linkFilePath = StaticRuntimeLibPath;
1688+
llvm::sys::path::remove_filename(linkFilePath); // remove arch name
16671689
llvm::sys::path::append(linkFilePath, "static-executable-args.lnk");
16681690
auto linkFile = linkFilePath.str();
16691691

@@ -1677,6 +1699,7 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
16771699
Arguments.push_back(context.Args.MakeArgString(StaticRuntimeLibPath));
16781700

16791701
SmallString<128> linkFilePath = StaticRuntimeLibPath;
1702+
llvm::sys::path::remove_filename(linkFilePath); // remove arch name
16801703
llvm::sys::path::append(linkFilePath, "static-stdlib-args.lnk");
16811704
auto linkFile = linkFilePath.str();
16821705
if (llvm::sys::fs::is_regular_file(linkFile)) {
@@ -1711,6 +1734,7 @@ toolchains::GenericUnix::constructInvocation(const LinkJobAction &job,
17111734

17121735
if (context.Args.hasArg(options::OPT_profile_generate)) {
17131736
SmallString<128> LibProfile(SharedRuntimeLibPath);
1737+
llvm::sys::path::remove_filename(LibProfile); // remove arch name
17141738
llvm::sys::path::remove_filename(LibProfile); // remove platform name
17151739
llvm::sys::path::append(LibProfile, "clang", "lib");
17161740

lib/Frontend/CompilerInvocation.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,19 @@ static void updateRuntimeLibraryPath(SearchPathOptions &SearchPathOpts,
4545
llvm::SmallString<128> LibPath(SearchPathOpts.RuntimeResourcePath);
4646

4747
llvm::sys::path::append(LibPath, getPlatformNameForTriple(Triple));
48-
SearchPathOpts.RuntimeLibraryPath = LibPath.str();
48+
if (Triple.isOSDarwin()) {
49+
// On Darwin the library search path is where we store fat binaries.
50+
SearchPathOpts.RuntimeLibraryPath = LibPath.str();
51+
}
4952

5053
llvm::sys::path::append(LibPath, swift::getMajorArchitectureName(Triple));
5154
SearchPathOpts.RuntimeLibraryImportPath = LibPath.str();
55+
if (!Triple.isOSDarwin()) {
56+
// On platforms without fat binaries, we use the arch specific
57+
// directory for searching for binaries. This is the same as the import
58+
// path for modules.
59+
SearchPathOpts.RuntimeLibraryPath = LibPath.str();
60+
}
5261
}
5362

5463
void CompilerInvocation::setRuntimeResourcePath(StringRef Path) {

stdlib/public/Platform/CMakeLists.txt

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,24 @@ foreach(sdk ${SWIFT_SDKS})
5353
set(GLIBC_INCLUDE_PATH "/system/develop/headers/posix")
5454
set(GLIBC_ARCH_INCLUDE_PATH "/system/develop/headers/posix")
5555
set(GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH "/system/develop/headers/")
56+
set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH "/system/develop/headers/")
5657
else()
5758
# Determine the location of glibc headers based on the target.
5859
set(GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH "/usr/include")
59-
set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH ${GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH})
60-
endif()
60+
set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH "${GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH}")
6161

62-
# Some SDKs place their headers in architecture-specific subfolders.
63-
if((${sdk} STREQUAL "LINUX" OR ${sdk} STREQUAL "FREEBSD") AND CMAKE_LIBRARY_ARCHITECTURE)
64-
set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH "${GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH}/${CMAKE_LIBRARY_ARCHITECTURE}")
65-
endif()
62+
# Some SDKs place their headers in architecture-specific subfolders.
63+
if(("${sdk}" STREQUAL "LINUX" OR "${sdk}" STREQUAL "FREEBSD") AND CMAKE_LIBRARY_ARCHITECTURE)
64+
set(GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH "${GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH}/${CMAKE_LIBRARY_ARCHITECTURE}")
65+
endif()
66+
67+
set(GLIBC_INCLUDE_PATH "${GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH}")
68+
set(GLIBC_ARCH_INCLUDE_PATH "${GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH}")
6669

67-
if(NOT "${sdk}" STREQUAL "HAIKU")
68-
set(GLIBC_INCLUDE_PATH "${SWIFT_SDK_${sdk}_PATH}/${GLIBC_SYSROOT_RELATIVE_INCLUDE_PATH}")
69-
set(GLIBC_ARCH_INCLUDE_PATH "${SWIFT_SDK_${sdk}_PATH}/${GLIBC_SYSROOT_RELATIVE_ARCH_INCLUDE_PATH}")
70+
if(NOT "${SWIFT_SDK_${sdk}_ARCH_${arch}_PATH}" STREQUAL "/")
71+
set(GLIBC_INCLUDE_PATH "${SWIFT_SDK_${sdk}_ARCH_${arch}_PATH}${GLIBC_INCLUDE_PATH}")
72+
set(GLIBC_ARCH_INCLUDE_PATH "${SWIFT_SDK_${sdk}_ARCH_${arch}_PATH}${GLIBC_ARCH_INCLUDE_PATH}")
73+
endif()
7074
endif()
7175

7276
set(glibc_modulemap_source "glibc.modulemap.gyb")
@@ -88,7 +92,7 @@ foreach(sdk ${SWIFT_SDKS})
8892

8993
# If this SDK is a target for a non-native host, create a native modulemap
9094
# without a sysroot prefix. This is the one we'll install instead.
91-
if(NOT "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_PATH}" STREQUAL "/")
95+
if(NOT "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${arch}_PATH}" STREQUAL "/")
9296

9397
set(glibc_sysroot_relative_modulemap_out "${module_dir}/sysroot-relative-modulemaps/glibc.modulemap")
9498
handle_gyb_source_single(glibc_modulemap_native_target
@@ -106,7 +110,7 @@ foreach(sdk ${SWIFT_SDKS})
106110
# FIXME: When SDK is a cross-compile target (SDK != Host), the generated
107111
# modulemap will be relative to the Host, with hardcoded paths.
108112
# It is not relocatable to the target platform itself.
109-
# This only affects ANDROID right now, but could affect cross-compiled LINUX targets
113+
# This affects any cross-compiled targets that use glibc.modulemap
110114

111115
swift_install_in_component(sdk-overlay
112116
FILES "${glibc_modulemap_out}"

stdlib/public/Platform/glibc.modulemap.gyb

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ module SwiftGlibc [system] {
3838

3939
// C standard library
4040
module C {
41+
% if CMAKE_SDK in ["LINUX", "ANDROID", "CYGWIN"]:
42+
module features {
43+
% if CMAKE_SDK == "LINUX":
44+
header "${GLIBC_INCLUDE_PATH}/stdc-predef.h"
45+
% end
46+
header "${GLIBC_INCLUDE_PATH}/features.h"
47+
export *
48+
}
49+
% end
4150
% if CMAKE_SDK in ["LINUX", "FREEBSD", "CYGWIN", "HAIKU"]:
4251
module complex {
4352
header "${GLIBC_INCLUDE_PATH}/complex.h"
@@ -71,13 +80,6 @@ module SwiftGlibc [system] {
7180
}
7281
% end
7382

74-
% if CMAKE_SDK in ["LINUX", "ANDROID", "CYGWIN"]:
75-
module features {
76-
header "${GLIBC_INCLUDE_PATH}/features.h"
77-
export *
78-
}
79-
% end
80-
8183
module ctype {
8284
header "${GLIBC_INCLUDE_PATH}/ctype.h"
8385
export *

test/CMakeLists.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,18 @@ foreach(SDK ${SWIFT_SDKS})
201201
list(APPEND test_dependencies "touch-covering-tests")
202202
endif()
203203

204-
set(validation_test_dependencies
204+
is_darwin_based_sdk("${SDK}" IS_DARWIN)
205+
if (IS_DARWIN)
206+
# use lipo targets as dependencies
207+
set(validation_test_dependencies
205208
"swiftStdlibCollectionUnittest-${SWIFT_SDK_${SDK}_LIB_SUBDIR}"
206209
"swiftStdlibUnicodeUnittest-${SWIFT_SDK_${SDK}_LIB_SUBDIR}")
210+
else()
211+
# use arch specific targets as dependencies on platforms without fat binaries
212+
set(validation_test_dependencies
213+
"swiftStdlibCollectionUnittest${VARIANT_SUFFIX}"
214+
"swiftStdlibUnicodeUnittest${VARIANT_SUFFIX}")
215+
endif()
207216

208217
set(command_upload_stdlib)
209218
set(command_upload_swift_reflection_test)

test/Driver/environment.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33

44
// RUN: %swift_driver -target x86_64-unknown-gnu-linux -L/foo/ -driver-use-frontend-path %S/Inputs/print-var.sh %s LD_LIBRARY_PATH | %FileCheck -check-prefix=CHECK${LD_LIBRARY_PATH+_LAX} %s
55

6-
// CHECK: {{^/foo/:[^:]+/lib/swift/linux$}}
7-
// CHECK_LAX: {{^/foo/:[^:]+/lib/swift/linux}}
6+
// CHECK: {{^/foo/:[^:]+/lib/swift/linux/x86_64$}}
7+
// CHECK_LAX: {{^/foo/:[^:]+/lib/swift/linux/x86_64}}

test/Driver/options-interpreter.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
// CHECK-RESOURCE-DIR-ONLY: # DYLD_LIBRARY_PATH=/RSRC/macosx{{$}}
1919

2020
// RUN: %swift_driver -### -target x86_64-unknown-linux-gnu -resource-dir /RSRC/ %s | %FileCheck -check-prefix=CHECK-RESOURCE-DIR-ONLY-LINUX${LD_LIBRARY_PATH+_LAX} %s
21-
// CHECK-RESOURCE-DIR-ONLY-LINUX: # LD_LIBRARY_PATH=/RSRC/linux{{$}}
22-
// CHECK-RESOURCE-DIR-ONLY-LINUX_LAX: # LD_LIBRARY_PATH=/RSRC/linux{{$|:}}
21+
// CHECK-RESOURCE-DIR-ONLY-LINUX: # LD_LIBRARY_PATH=/RSRC/linux/x86_64{{$}}
22+
// CHECK-RESOURCE-DIR-ONLY-LINUX_LAX: # LD_LIBRARY_PATH=/RSRC/linux/x86_64{{$|:}}
2323

2424
// RUN: %swift_driver -### -target x86_64-apple-macosx10.9 -L/foo/ %s | %FileCheck -check-prefix=CHECK-L %s
2525
// CHECK-L: # DYLD_LIBRARY_PATH={{/foo/:[^:]+/lib/swift/macosx$}}
@@ -59,9 +59,9 @@
5959
// CHECK-COMPLEX-DAG: DYLD_LIBRARY_PATH={{/foo2/:/bar2/:[^:]+/lib/swift/macosx($| )}}
6060

6161
// RUN: %swift_driver -### -target x86_64-unknown-linux-gnu -L/foo/ %s | %FileCheck -check-prefix=CHECK-L-LINUX${LD_LIBRARY_PATH+_LAX} %s
62-
// CHECK-L-LINUX: # LD_LIBRARY_PATH={{/foo/:[^:]+/lib/swift/linux$}}
63-
// CHECK-L-LINUX_LAX: # LD_LIBRARY_PATH={{/foo/:[^:]+/lib/swift/linux($|:)}}
62+
// CHECK-L-LINUX: # LD_LIBRARY_PATH={{/foo/:[^:]+/lib/swift/linux/x86_64$}}
63+
// CHECK-L-LINUX_LAX: # LD_LIBRARY_PATH={{/foo/:[^:]+/lib/swift/linux/x86_64($|:)}}
6464

6565
// RUN: env LD_LIBRARY_PATH=/abc/ %swift_driver_plain -### -target x86_64-unknown-linux-gnu -L/foo/ -L/bar/ %s | %FileCheck -check-prefix=CHECK-LINUX-COMPLEX${LD_LIBRARY_PATH+_LAX} %s
66-
// CHECK-LINUX-COMPLEX: # LD_LIBRARY_PATH={{/foo/:/bar/:[^:]+/lib/swift/linux:/abc/$}}
67-
// CHECK-LINUX-COMPLEX_LAX: # LD_LIBRARY_PATH={{/foo/:/bar/:[^:]+/lib/swift/linux:/abc/($|:)}}
66+
// CHECK-LINUX-COMPLEX: # LD_LIBRARY_PATH={{/foo/:/bar/:[^:]+/lib/swift/linux/x86_64:/abc/$}}
67+
// CHECK-LINUX-COMPLEX_LAX: # LD_LIBRARY_PATH={{/foo/:/bar/:[^:]+/lib/swift/linux/x86_64:/abc/($|:)}}

validation-test/execution/interpret-with-dependencies-linux.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
// CHECK: {{okay}}
99

1010
// Now test a dependency on a library in the compiler's resource directory.
11-
// RUN: %empty-directory(%t/rsrc/%target-sdk-name)
12-
// RUN: ln -s %t/libabc.so %t/rsrc/%target-sdk-name/
13-
// RUN: ln -s %platform-module-dir/../* %t/rsrc/%target-sdk-name/
11+
// RUN: %empty-directory(%t/rsrc/%target-sdk-name/%target-cpu)
12+
// RUN: ln -s %t/libabc.so %t/rsrc/%target-sdk-name/%target-cpu
13+
// RUN: ln -s %platform-module-dir/../%target-cpu/* %t/rsrc/%target-sdk-name/%target-cpu
1414
// RUN: ln -s %platform-module-dir/../../shims %t/rsrc/
1515
// RUN: %empty-directory(%t/other)
1616
// RUN: ln -s %t/libfoo.so %t/other

0 commit comments

Comments
 (0)