@@ -12,11 +12,21 @@ B ?= "${S}/.build"
1212EXTERNALSRC_BUILD ?= "${EXTERNALSRC} /.build"
1313
1414BUILD_MODE = "${@ ['release' , 'debug' ][d . getVar ('DEBUG_BUILD' ) == '1' ]}"
15+ BUILD_DIR = "${B} /${BUILD_MODE} "
1516
1617# Additional parameters to pass to SPM
1718EXTRA_OESWIFT ?= ""
1819
1920SWIFT_TARGET_NAME = "${@ oe . utils . conditional ('TARGET_ARCH' , 'arm' , 'armv7-unknown-linux-gnueabihf' , 'aarch64-unknown-linux-gnu' , d )}"
21+ SWIFT_TARGET_ARCH = "${@ oe . utils . conditional ('TARGET_ARCH' , 'arm' , 'armv7' , 'aarch64' , d )}"
22+
23+ do_fix_gcc_install_dir () {
24+ # symbolic links do not work, will not be found by Swift clang driver
25+ # this is necessary to make the libstdc++ location heuristic work, necessary for C++ interop
26+ (cd ${STAGING_DIR_TARGET} /usr /lib && rm -rf gcc && mkdir -p gcc && cp -rp ${SWIFT_TARGET_ARCH} -oe -linux gcc )
27+ }
28+
29+ addtask fix_gcc_install_dir before do_configure after do_prepare_recipe_sysroot
2030
2131# Workaround complex macros that cannot be automatically imported by Swift.
2232# https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/using_imported_c_macros_in_swift
@@ -41,6 +51,37 @@ def fix_socket_header(filename):
4151 else :
4252 f . write (line )
4353
54+ # Support for SwiftPM fetching packages and their GitHub submodules
55+ do_swift_package_resolve [depends ] += "unzip-native:do_populate_sysroot swift-native:do_populate_sysroot"
56+ do_swift_package_resolve [network ] = "1"
57+ do_swift_package_resolve [vardepsexclude ] = "BB_ORIGENV"
58+
59+ python do_swift_package_resolve () {
60+ import subprocess
61+ import os
62+
63+ s = d . getVar ('S' )
64+ b = d . getVar ('B' )
65+
66+ env = os . environ . copy ()
67+
68+ ssh_auth_sock = d . getVar ('BB_ORIGENV' ). get ('SSH_AUTH_SOCK' )
69+ if ssh_auth_sock :
70+ env ['SSH_AUTH_SOCK' ] = ssh_auth_sock
71+
72+ ret = subprocess . call (['swift' , 'package' , 'resolve' , '--package-path' , s , '--build-path' , b ], env = env )
73+ if ret != 0 :
74+ bb . fatal ('swift package resolve failed' )
75+
76+ # note: --depth 1 requires git version 2.43.0 or later
77+ for package in os . listdir (path = f '{b}/checkouts' ):
78+ package_dir = f '{b}/checkouts/{package}'
79+ ret = subprocess . call (['git' , 'submodule' , 'update' , '--init' , '--recursive' , '--depth' , '1' ], cwd = package_dir , env = env )
80+ if ret != 0 :
81+ bb . fatal ('git submodule update failed' )
82+ }
83+
84+ addtask swift_package_resolve after do_unpack before do_compile
4485
4586python swift_do_configure () {
4687 import os
@@ -62,6 +103,8 @@ python swift_do_configure() {
62103 # This is used to determine necessary include paths
63104 cxx_include_base = recipe_sysroot + "/usr/include/c++"
64105 cxx_include_list = os . listdir (cxx_include_base )
106+ if 'current' in cxx_include_list :
107+ cxx_include_list . remove ('current' )
65108 if len (cxx_include_list ) != 1 :
66109 bb . fatal ("swift bbclass detected more than one c++ runtime, unable to determine which one to use" )
67110 cxx_version = cxx_include_list [0 ]
@@ -71,22 +114,26 @@ python swift_do_configure() {
71114 swift_destination_template = """{
72115 "version":1,
73116 "sdk":"${STAGING_DIR_TARGET} /",
74- "toolchain-bin-dir":"${STAGING_DIR_NATIVE} /opt/ usr/bin",
117+ "toolchain-bin-dir":"${STAGING_DIR_NATIVE} /usr/bin",
75118 "target":"${SWIFT_TARGET_NAME} ",
76119 "dynamic-library-extension":"so",
77120 "extra-cc-flags":[
78121 "-fPIC",
122+ "-I${STAGING_INCDIR} ",
79123 "-I${STAGING_DIR_TARGET} /usr/include/c++/${SWIFT_CXX_VERSION} ",
80124 "-I${STAGING_DIR_TARGET} /usr/include/c++/${SWIFT_CXX_VERSION} /${TARGET_SYS} ",
81- "-I${STAGING_DIR_NATIVE} /opt/ usr/lib/clang/13.0.0 /include",
82- "-I${STAGING_DIR_NATIVE} /opt/ usr/lib/clang/13.0.0 /include-fixed"
125+ "-I${STAGING_DIR_NATIVE} /usr/lib/clang/17 /include",
126+ "-I${STAGING_DIR_NATIVE} /usr/lib/clang/17 /include-fixed"
83127 ],
84128 "extra-swiftc-flags":[
85129 "-target",
86130 "${SWIFT_TARGET_NAME} ",
87131 "-use-ld=lld",
88132 "-tools-directory",
89- "${STAGING_DIR_NATIVE} /opt/usr/bin",
133+ "${STAGING_DIR_NATIVE} /usr/bin",
134+
135+ "-enforce-exclusivity=unchecked",
136+ "-enforce-exclusivity=none",
90137
91138 "-Xlinker", "-rpath", "-Xlinker", "/usr/lib/swift/linux",
92139
@@ -111,14 +158,16 @@ python swift_do_configure() {
111158 "-I${STAGING_INCDIR} ",
112159 "-I${STAGING_DIR_TARGET} /usr/include/c++/${SWIFT_CXX_VERSION} ",
113160 "-I${STAGING_DIR_TARGET} /usr/include/c++/${SWIFT_CXX_VERSION} /${TARGET_SYS} ",
114- "-I${STAGING_DIR_NATIVE} /opt/ usr/lib/clang/13.0.0 /include",
115- "-I${STAGING_DIR_NATIVE} /opt/ usr/lib/clang/13.0.0 /include-fixed",
161+ "-I${STAGING_DIR_NATIVE} /usr/lib/clang/17 /include",
162+ "-I${STAGING_DIR_NATIVE} /usr/lib/clang/17 /include-fixed",
116163
117164 "-resource-dir", "${STAGING_DIR_TARGET} /usr/lib/swift",
118165 "-module-cache-path", "${B} /${BUILD_MODE} /ModuleCache",
119166 "-Xclang-linker", "-B${STAGING_DIR_TARGET} /usr/lib/${TARGET_SYS} /${SWIFT_CXX_VERSION} ",
120167 "-Xclang-linker", "-B${STAGING_DIR_TARGET} /usr/lib",
121168
169+ "-Xcc", "--gcc-install-dir=${STAGING_DIR_TARGET} /usr/lib/gcc/${TARGET_SYS} /${SWIFT_CXX_VERSION} ",
170+
122171 "-sdk", "${STAGING_DIR_TARGET} "
123172 ],
124173 "extra-cpp-flags":[
@@ -135,10 +184,66 @@ python swift_do_configure() {
135184 configJSON . close ()
136185}
137186
138- swift_do_compile () {
139- swift build --package -path ${S} --build -path ${B} --skip -update -c ${BUILD_MODE} --destination ${WORKDIR} /destination . json ${EXTRA_OESWIFT}
187+ # ideally this should be handled by do_swift_package_resolve but doesn't always appear to be the case
188+ do_compile [network ] = "1"
189+ swift_do_compile [vardepsexclude ] = "BB_ORIGENV"
190+
191+ python swift_do_compile () {
192+ import subprocess
193+ import os
194+ import shlex
195+
196+ s = d . getVar ('S' )
197+ b = d . getVar ('B' )
198+ build_mode = d . getVar ('BUILD_MODE' )
199+ workdir = d . getVar ("WORKDIR" , True )
200+ destination_json = workdir + '/destination.json'
201+ extra_oeswift = shlex . split (d . getVar ('EXTRA_OESWIFT' ))
202+ ssh_auth_sock = d . getVar ('BB_ORIGENV' )['SSH_AUTH_SOCK' ]
203+ recipe_sysroot = d . getVar ("STAGING_DIR_TARGET" , True )
204+
205+ env = os . environ . copy ()
206+ env ['SSH_AUTH_SOCK' ] = ssh_auth_sock
207+ env ['SYSROOT' ] = recipe_sysroot
208+
209+ args = ['swift' , 'build' , '--package-path' , s , '--build-path' , b , '-c' , build_mode , '--destination' , destination_json ] + extra_oeswift
210+
211+ ret = subprocess . call (args , env = env , cwd = s )
212+ if ret != 0 :
213+ bb . fatal ('swift build failed' )
214+
215+ if d . getVar ('SWIFT_BUILD_TESTS' ) == '1' :
216+ if d . getVar ('DEBUG_BUILD' ) != '1' :
217+ bb . warn ('building Swift tests with release build, @testable imports may fail' )
218+
219+ # FIXME: why do we need to specify -lXCTest and -lTesting explicitly
220+ test_args = ['--build-tests' , '-Xlinker' , '-lXCTest' , '-Xlinker' , '-lTesting' ]
221+ ret = subprocess . call (args + test_args + extra_oeswift , env = env , cwd = s )
222+ if ret != 0 :
223+ bb . fatal ('swift build --build-tests failed' )
224+ }
225+
226+ do_package_update () {
227+ cd ${S}
228+ swift package update
229+
230+ # Iterate over the search dirs for this recipes' files
231+ # The first one that has a Package.resolved is the one bitbake got the file
232+ # from in the first places
233+ RESOLVED_PATH = ""
234+ for i in $(echo "${FILESPATH} " | tr ':' '\n' ); do
235+ if [ -r "${i} " /Package . resolved ]; then
236+ RESOLVED_PATH = "${i} /Package.resolved"
237+ cp Package . resolved "${RESOLVED_PATH} "
238+ bbwarn "Replaced ${RESOLVED_PATH} with updated Package.resolved."
239+ break
240+ fi
241+ done
242+ [ -z "${RESOLVED_PATH} " ] && bbwarn "Updated Package.resolved located at ${S} /Package.resolved" || :
140243}
244+ do_package_update [network ] = "1"
245+ addtask do_package_update after do_configure
141246
142- EXPORT_FUNCTIONS do_configure do_compile
247+ EXPORT_FUNCTIONS do_configure do_compile do_package_update
143248
144249EXTRANATIVEPATH += "swift-tools"
0 commit comments