Skip to content

Commit 5e170eb

Browse files
committed
build: support cross-compiling to windows
1 parent 63c117a commit 5e170eb

File tree

8 files changed

+163
-16
lines changed

8 files changed

+163
-16
lines changed

CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ set(SWIFT_ANDROID_DEPLOY_DEVICE_PATH "" CACHE STRING
193193
# User-configurable ICU specific options for Android, FreeBSD, Linux.
194194
#
195195

196-
foreach(sdk ANDROID;FREEBSD;LINUX)
196+
foreach(sdk ANDROID;FREEBSD;LINUX;WINDOWS)
197197
set(SWIFT_${sdk}_ICU_UC "" CACHE STRING
198198
"Path to a directory containing the icuuc library for ${sdk}")
199199
set(SWIFT_${sdk}_ICU_UC_INCLUDE "" CACHE STRING
@@ -736,6 +736,12 @@ if("${SWIFT_PRIMARY_VARIANT_ARCH}" STREQUAL "")
736736
set(SWIFT_PRIMARY_VARIANT_ARCH "${SWIFT_PRIMARY_VARIANT_ARCH_default}")
737737
endif()
738738

739+
# Should we cross-compile the standard library for Windows?
740+
is_sdk_requested(WINDOWS swift_build_windows)
741+
if(swift_build_windows)
742+
configure_sdk_windows(WINDOWS "Windows" "msvc" i686)
743+
endif()
744+
739745
if("${SWIFT_SDKS}" STREQUAL "")
740746
set(SWIFT_SDKS "${SWIFT_CONFIGURED_SDKS}")
741747
endif()

cmake/modules/AddSwift.cmake

Lines changed: 103 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,13 @@ function(_add_variant_c_compile_link_flags)
101101
"-B" "${SWIFT_ANDROID_NDK_PATH}/toolchains/arm-linux-androideabi-${SWIFT_ANDROID_NDK_GCC_VERSION}/prebuilt/linux-x86_64/arm-linux-androideabi/bin/")
102102
endif()
103103

104+
if("${CFLAGS_SDK}" STREQUAL "WINDOWS")
105+
list(APPEND result "-DLLVM_ON_WIN32")
106+
list(APPEND result "-D_CRT_SECURE_NO_WARNINGS")
107+
# TODO(compnerd) handle /MT
108+
list(APPEND result "-D_DLL")
109+
list(APPEND result "-fms-compatibility-version=1900")
110+
endif()
104111

105112
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
106113

@@ -176,6 +183,18 @@ function(_add_variant_c_compile_flags)
176183
list(APPEND result "-g0")
177184
endif()
178185

186+
if("${CFLAGS_SDK}" STREQUAL "WINDOWS")
187+
list(APPEND result -Xclang;--dependent-lib=oldnames)
188+
# TODO(compnerd) handle /MT, /MTd, /MD, /MDd
189+
if("${CMAKE_BUILD_TYPE}" STREQUAL "RELEASE")
190+
list(APPEND result "-D_MD")
191+
list(APPEND result -Xclang;--dependent-lib=msvcrt)
192+
else()
193+
list(APPEND result "-D_MDd")
194+
list(APPEND result -Xclang;--dependent-lib=msvcrtd)
195+
endif()
196+
endif()
197+
179198
if(CFLAGS_ENABLE_ASSERTIONS)
180199
list(APPEND result "-UNDEBUG")
181200
else()
@@ -264,6 +283,10 @@ function(_add_variant_link_flags)
264283
list(APPEND result "-lpthread")
265284
elseif("${LFLAGS_SDK}" STREQUAL "CYGWIN")
266285
# No extra libraries required.
286+
elseif("${LFLAGS_SDK}" STREQUAL "WINDOWS")
287+
# NOTE: we do not use "/MD" or "/MDd" and select the runtime via linker
288+
# options. This causes conflicts.
289+
list(APPEND result "-nostdlib")
267290
elseif("${LFLAGS_SDK}" STREQUAL "ANDROID")
268291
list(APPEND result
269292
"-ldl"
@@ -594,6 +617,16 @@ function(_add_swift_library_single target name)
594617
endif()
595618
endif()
596619

620+
if("${SWIFTLIB_SINGLE_SDK}" STREQUAL "WINDOWS")
621+
list(APPEND SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS -Xfrontend;-autolink-library;-Xfrontend;oldnames)
622+
# TODO(compnerd) handle /MT and /MTd
623+
if("${CMAKE_BUILD_TYPE}" STREQUAL "RELEASE")
624+
list(APPEND SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS -Xfrontend;-autolink-library;-Xfrontend;msvcrt)
625+
else()
626+
list(APPEND SWIFTLIB_SINGLE_SWIFT_COMPILE_FLAGS -Xfrontend;-autolink-library;-Xfrontend;msvcrtd)
627+
endif()
628+
endif()
629+
597630
# FIXME: don't actually depend on the libraries in SWIFTLIB_SINGLE_LINK_LIBRARIES,
598631
# just any swiftmodule files that are associated with them.
599632
handle_swift_sources(
@@ -649,6 +682,28 @@ function(_add_swift_library_single target name)
649682
endif()
650683
endif()
651684

685+
if("${SWIFTLIB_SINGLE_SDK}" STREQUAL "WINDOWS")
686+
if("${libkind}" STREQUAL "STATIC")
687+
set_property(TARGET "${target}" PROPERTY PREFIX "lib")
688+
set_property(TARGET "${target}" PROPERTY SUFFIX ".lib")
689+
elseif("${libkind}" STREQUAL "SHARED")
690+
set_property(TARGET "${target}" PROPERTY PREFIX "")
691+
set_property(TARGET "${target}" PROPERTY SUFFIX ".dll")
692+
693+
# Each dll has an associated .lib (import library); since we may be
694+
# building on a non-DLL platform (not windows), create an imported target
695+
# for the library which created implicitly by the dll.
696+
add_custom_command_target(${target}_IMPORT_LIBRARY
697+
OUTPUT "${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}/${name}.lib"
698+
DEPENDS "${target}")
699+
add_library(${target}_IMPLIB SHARED IMPORTED GLOBAL)
700+
set_property(TARGET "${target}_IMPLIB" PROPERTY
701+
IMPORTED_LOCATION "${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}/${name}.lib")
702+
add_dependencies(${target}_IMPLIB ${${target}_IMPORT_LIBRARY})
703+
endif()
704+
set_property(TARGET "${target}" PROPERTY NO_SONAME ON)
705+
endif()
706+
652707
# The section metadata objects are generated sources, and we need to tell CMake
653708
# not to expect to find them prior to their generation.
654709
if("${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_OBJECT_FORMAT}" STREQUAL "ELF")
@@ -880,7 +935,9 @@ function(_add_swift_library_single target name)
880935
"${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_OBJECT_FORMAT}" STREQUAL "ELF")
881936
list(APPEND link_flags "-fuse-ld=gold")
882937
endif()
883-
if (SWIFT_ENABLE_LLD_LINKER)
938+
if(SWIFT_ENABLE_LLD_LINKER OR
939+
("${SWIFTLIB_SINGLE_SDK}" STREQUAL "WINDOWS" AND
940+
NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WINDOWS"))
884941
list(APPEND link_flags "-fuse-ld=lld")
885942
endif()
886943

@@ -925,6 +982,34 @@ function(_add_swift_library_single target name)
925982
COMPILE_FLAGS " ${c_compile_flags}")
926983
set_property(TARGET "${target}" APPEND_STRING PROPERTY
927984
LINK_FLAGS " ${link_flags} -L${SWIFTLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR} -L${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/../lib/swift/${SWIFTLIB_SINGLE_SUBDIR} -L${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/../lib/swift/${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_LIB_SUBDIR}")
985+
986+
# Adjust the linked libraries for windows targets. On Windows, the link is
987+
# performed against the import library, and the runtime uses the dll. Not
988+
# doing so will result in incorrect symbol resolution and linkage. We created
989+
# import library targets when the library was added. Use that to adjust the
990+
# link libraries.
991+
if("${SWIFTLIB_SINGLE_SDK}" STREQUAL "WINDOWS")
992+
foreach(library_list LINK_LIBRARIES INTERFACE_LINK_LIBRARIES PRIVATE_LINK_LIBRARIES)
993+
set(import_libraries)
994+
foreach(library ${SWIFTLIB_SINGLE_${library_list}})
995+
# Ensure that the library is a target. If an absolute path was given,
996+
# then we do not have an import library associated with it. This occurs
997+
# primarily with ICU (which will be an import library). Import
998+
# libraries are only associated with shared libraries, so add an
999+
# additional check for that as well.
1000+
set(import_library ${library})
1001+
if(TARGET ${library})
1002+
get_target_property(type ${library} TYPE)
1003+
if(${type} STREQUAL "SHARED_LIBRARY")
1004+
set(import_library ${library}_IMPLIB)
1005+
endif()
1006+
endif()
1007+
list(APPEND import_libraries ${import_library})
1008+
endforeach()
1009+
set(SWIFTLIB_SINGLE_${library_list} ${import_libraries})
1010+
endforeach()
1011+
endif()
1012+
9281013
if("${libkind}" STREQUAL "OBJECT")
9291014
_require_empty_list(
9301015
"${SWIFTLIB_SINGLE_PRIVATE_LINK_LIBRARIES}"
@@ -1329,14 +1414,23 @@ function(add_swift_library name)
13291414
if(NOT SWIFTLIB_OBJECT_LIBRARY)
13301415
# Determine the name of the universal library.
13311416
if(SWIFTLIB_SHARED)
1332-
set(UNIVERSAL_LIBRARY_NAME
1333-
"${SWIFTLIB_DIR}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX}")
1417+
if("${sdk}" STREQUAL "WINDOWS")
1418+
set(UNIVERSAL_LIBRARY_NAME
1419+
"${SWIFTLIB_DIR}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${name}.dll")
1420+
else()
1421+
set(UNIVERSAL_LIBRARY_NAME
1422+
"${SWIFTLIB_DIR}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${CMAKE_SHARED_LIBRARY_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX}")
1423+
endif()
13341424
else()
1335-
set(UNIVERSAL_LIBRARY_NAME
1336-
"${SWIFTLIB_DIR}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
1425+
if("${sdk}" STREQUAL "WINDOWS")
1426+
set(UNIVERSAL_LIBRARY_NAME
1427+
"${SWIFTLIB_DIR}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/lib${name}.lib")
1428+
else()
1429+
set(UNIVERSAL_LIBRARY_NAME
1430+
"${SWIFTLIB_DIR}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
1431+
endif()
13371432
endif()
13381433

1339-
13401434
set(lipo_target "${name}-${SWIFT_SDK_${sdk}_LIB_SUBDIR}")
13411435
_add_swift_lipo_target(
13421436
${lipo_target}
@@ -1552,7 +1646,9 @@ function(_add_swift_executable_single name)
15521646
"${SWIFT_SDK_${SWIFTEXE_SINGLE_SDK}_OBJECT_FORMAT}" STREQUAL "ELF")
15531647
list(APPEND link_flags "-fuse-ld=gold")
15541648
endif()
1555-
if(SWIFT_ENABLE_LLD_LINKER)
1649+
if(SWIFT_ENABLE_LLD_LINKER OR
1650+
("${SWIFTLIB_SINGLE_SDK}" STREQUAL "WINDOWS" AND
1651+
NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WINDOWS"))
15561652
list(APPEND link_flags "-fuse-ld=lld")
15571653
endif()
15581654

cmake/modules/FindICU.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ foreach(MODULE ${ICU_FIND_COMPONENTS})
2525
endif()
2626
endforeach()
2727

28-
foreach(sdk ANDROID;FREEBSD;LINUX)
28+
foreach(sdk ANDROID;FREEBSD;LINUX;WINDOWS)
2929
foreach(MODULE ${ICU_FIND_COMPONENTS})
3030
if("${SWIFT_${sdk}_ICU_${MODULE}_INCLUDE}" STREQUAL "")
3131
set(SWIFT_${sdk}_ICU_${MODULE}_INCLUDE ${ICU_${MODULE}_INCLUDE_DIRS})

cmake/modules/SwiftConfigureSDK.cmake

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ set(SWIFT_CONFIGURED_SDKS)
88
# Report the given SDK to the user.
99
function(_report_sdk prefix)
1010
message(STATUS "${SWIFT_SDK_${prefix}_NAME} SDK:")
11-
message(STATUS " Path: ${SWIFT_SDK_${prefix}_PATH}")
11+
if("${prefix}" STREQUAL "WINDOWS")
12+
message(STATUS " INCLUDE: $ENV{INCLUDE}")
13+
message(STATUS " LIB: $ENV{LIB}")
14+
else()
15+
message(STATUS " Path: ${SWIFT_SDK_${prefix}_PATH}")
16+
endif()
1217
message(STATUS " Version: ${SWIFT_SDK_${prefix}_VERSION}")
1318
message(STATUS " Build number: ${SWIFT_SDK_${prefix}_BUILD_NUMBER}")
1419
message(STATUS " Deployment version: ${SWIFT_SDK_${prefix}_DEPLOYMENT_VERSION}")
@@ -138,6 +143,35 @@ macro(configure_sdk_unix
138143
_report_sdk("${prefix}")
139144
endmacro()
140145

146+
macro(configure_sdk_windows prefix sdk_name environment architectures)
147+
# Note: this has to be implemented as a macro because it sets global
148+
# variables.
149+
150+
set(SWIFT_SDK_${prefix}_NAME "${sdk_name}")
151+
# NOTE: set the path to / to avoid a spurious `--sysroot` from being passed
152+
# to the driver -- rely on the `INCLUDE` AND `LIB` environment variables
153+
# instead.
154+
set(SWIFT_SDK_${prefix}_PATH "/")
155+
set(SWIFT_SDK_${prefix}_VERSION "NOTFOUND")
156+
set(SWIFT_SDK_${prefix}_BUILD_NUMBER "NOTFOUND")
157+
set(SWIFT_SDK_${prefix}_DEPLOYMENT_VERSION "NOTFOUND")
158+
set(SWIFT_SDK_${prefix}_LIB_SUBDIR "windows")
159+
set(SWIFT_SDK_${prefix}_VERSION_MIN_NAME "NOTFOUND")
160+
set(SWIFT_SDK_${prefix}_TRIPLE_NAME "NOTFOUND")
161+
set(SWIFT_SDK_${prefix}_ARCHITECTURES "${architectures}")
162+
set(SWIFT_SDK_${prefix}_OBJECT_FORMAT "COFF")
163+
164+
foreach(arch ${architectures})
165+
set(SWIFT_SDK_${prefix}_ARCH_${arch}_TRIPLE
166+
"${arch}-unknown-windows-${environment}")
167+
endforeach()
168+
169+
# Add this to the list of known SDKs.
170+
list(APPEND SWIFT_CONFIGURED_SDKS "${prefix}")
171+
172+
_report_sdk("${prefix}")
173+
endmacro()
174+
141175
# Configure a variant of a certain SDK
142176
#
143177
# In addition to the SDK and architecture, a variant determines build settings.

cmake/modules/SwiftSetIfArchBitness.cmake

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ function(set_if_arch_bitness var_name)
77
${ARGN})
88

99
if("${SIA_ARCH}" STREQUAL "i386" OR
10-
"${SIA_ARCH}" STREQUAL "armv6" OR
11-
"${SIA_ARCH}" STREQUAL "armv7" OR
12-
"${SIA_ARCH}" STREQUAL "armv7k" OR
13-
"${SIA_ARCH}" STREQUAL "armv7s")
10+
"${SIA_ARCH}" STREQUAL "i686" OR
11+
"${SIA_ARCH}" STREQUAL "armv6" OR
12+
"${SIA_ARCH}" STREQUAL "armv7" OR
13+
"${SIA_ARCH}" STREQUAL "armv7k" OR
14+
"${SIA_ARCH}" STREQUAL "armv7s")
1415
set("${var_name}" "${SIA_CASE_32_BIT}" PARENT_SCOPE)
1516
elseif("${SIA_ARCH}" STREQUAL "x86_64" OR
1617
"${SIA_ARCH}" STREQUAL "arm64" OR

cmake/modules/SwiftSharedCMakeConfig.cmake

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,11 @@ macro(swift_common_standalone_build_config_llvm product is_cross_compiling)
9191
include(AddSwiftTableGen) # This imports TableGen from LLVM.
9292
include(HandleLLVMOptions)
9393

94+
# HACK: this ugly tweaking is to prevent the propogation of the flag from LLVM
95+
# into swift. The use of this flag pollutes all targets, and we are not able
96+
# to remove it on a per-target basis which breaks cross-compilation.
97+
string(REGEX REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
98+
9499
set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
95100
string(REGEX REPLACE "([0-9]+)\\.[0-9]+(\\.[0-9]+)?" "\\1" PACKAGE_VERSION_MAJOR
96101
${PACKAGE_VERSION})

stdlib/public/stubs/Stubs.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,11 @@ __muloti4(ti_int a, ti_int b, int* overflow)
384384

385385
#endif
386386

387-
#if defined(__linux__) && defined(__arm__)
387+
// FIXME: ideally we would have a slow path here for Windows which would be
388+
// lowered to instructions as though MSVC had generated. There does not seem to
389+
// be a MSVC provided multiply with overflow detection that I can see, but this
390+
// avoids an unncessary dependency on compiler-rt for a single function.
391+
#if (defined(__linux__) && defined(__arm__)) || defined(_MSC_VER)
388392
// Similar to above, but with mulodi4. Perhaps this is
389393
// something that shouldn't be done, and is a bandaid over
390394
// some other lower-level architecture issue that I'm

test/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ function(get_test_dependencies SDK result_var_name)
5959
("${SDK}" STREQUAL "LINUX") OR
6060
("${SDK}" STREQUAL "CYGWIN") OR
6161
("${SDK}" STREQUAL "FREEBSD") OR
62-
("${SDK}" STREQUAL "ANDROID"))
62+
("${SDK}" STREQUAL "ANDROID") OR
63+
("${SDK}" STREQUAL "WINDOWS"))
6364
# No extra dependencies.
6465
else()
6566
message(FATAL_ERROR "Unknown SDK: ${SDK}")

0 commit comments

Comments
 (0)