Skip to content

Enable cross-compiling #1398

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

Closed
wants to merge 2 commits into from
Closed
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
4 changes: 4 additions & 0 deletions cmake/modules/AddSwift.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ function(_add_variant_swift_compile_flags
"-sdk" "${SWIFT_SDK_${sdk}_PATH}"
"-target" "${SWIFT_SDK_${sdk}_ARCH_${arch}_TRIPLE}")

if (CMAKE_CROSSCOMPILING)
list(APPEND result "-resource-dir" "${SWIFT_LIBRARY_OUTPUT_INTDIR}/swift")
endif ()

if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
list(APPEND result
"-F" "${SWIFT_SDK_${sdk}_PATH}/../../../Developer/Library/Frameworks")
Expand Down
9 changes: 5 additions & 4 deletions cmake/modules/SwiftSharedCMakeConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,12 @@ macro(swift_common_standalone_build_config product is_cross_compiling)

if(${is_cross_compiling})
# Can't run llvm-config from the cross-compiled LLVM.
set(LLVM_TOOLS_BINARY_DIR "" CACHE PATH "Path to llvm/bin")
set(LLVM_LIBRARY_DIR "" CACHE PATH "Path to llvm/lib")
set(LLVM_MAIN_INCLUDE_DIR "" CACHE PATH "Path to llvm/include")
set(LLVM_BINARY_DIR "" CACHE PATH "Path to LLVM build tree")
set(LLVM_TOOLS_BINARY_DIR "${SWIFT_NATIVE_LLVM_TOOLS_PATH}" CACHE PATH "Path to llvm/bin")
set(LLVM_LIBRARY_DIR "${SWIFT_NATIVE_LLVM_TOOLS_PATH}/../lib" CACHE PATH "Path to llvm/lib")
set(LLVM_MAIN_INCLUDE_DIR "${SWIFT_NATIVE_LLVM_TOOLS_PATH}/../include" CACHE PATH "Path to llvm/include")
set(LLVM_BINARY_DIR "${SWIFT_NATIVE_LLVM_TOOLS_PATH}/../" CACHE PATH "Path to LLVM build tree")
set(LLVM_MAIN_SRC_DIR "" CACHE PATH "Path to LLVM source tree")
set(SWIFT_PATH_TO_CLANG_BUILD "${LLVM_BINARY_DIR}")
else()
# Rely on llvm-config.
_swift_llvm_config_info(
Expand Down
48 changes: 48 additions & 0 deletions cmake/modules/Toolchain-linux-arm.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
message(STATUS "Using Linux-arm toolchain file")

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR "armv7l")
set(CMAKE_LIBRARY_ARCHITECTURE "arm-linux-gnueabihf") # for Glibc/CMakeLists.txt
set(CMAKE_EXECUTABLE_FORMAT "ELF")

include(CMakeForceCompiler)

# 1) Get a sysroot, e.g. by running debootstrap, or this script: https://gist.github.com/froody/de6846f3455451f81992
# 2) Download https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q3-update/+download/gcc-arm-none-eabi-4_9-2015q3-20150921-mac.tar.bz2
# 3) Untar gcc, and in gcc-arm-none-eabi-4_9-2015q3/bin/
# 4) Get the android NDK from http://developer.android.com/ndk/downloads/index.html
# and copy ld.gold to the gcc bin dir in (3) from:
# toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/arm-linux-androideabi/bin/ld.gold
# 5) Run
# ./utils/build-script -R --cross-compile-stdlib-targets linux-armv7 --
# --cross-compile-sysroot=<sysroot path from (1)>
# --cross-compile-toolchain-bin=<bin directory from (3)>

if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
set(CMAKE_AR ${CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN}/arm-none-eabi-ar CACHE FILEPATH "Archiver") # https://cmake.org/Bug/view.php?id=13038
endif ()

set(COMMON_C_FLAGS "-B ${CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN}")
set(COMMON_C_FLAGS "${COMMON_C_FLAGS} -B ${CMAKE_SYSROOT}/usr/lib/gcc/arm-linux-gnueabihf/4.8")
set(COMMON_C_FLAGS "${COMMON_C_FLAGS} -fuse-ld=gold")

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_C_FLAGS}" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_C_FLAGS}" CACHE STRING "" FORCE)

set(CMAKE_CXX_COMPILER_VERSION 3.6)

link_directories(${CMAKE_SYSROOT}/usr/lib/arm-linux-gnueabihf/
${CMAKE_SYSROOT}/usr/lib/gcc/arm-linux-gnueabihf/4.8/)
include_directories(SYSTEM
${CMAKE_SYSROOT}/usr/include/c++/4.8/
${CMAKE_SYSROOT}/usr/include/arm-linux-gnueabihf/c++/4.8/
${CMAKE_SYSROOT}/usr/lib/gcc/arm-linux-gnueabihf/4.8/include/)

# Used to find BSD and ICU among other things
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})

set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabihf)
set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabihf)
CMAKE_FORCE_C_COMPILER("${CMAKE_C_COMPILER}" Clang)
CMAKE_FORCE_CXX_COMPILER("${CMAKE_CXX_COMPILER}" Clang)

10 changes: 9 additions & 1 deletion stdlib/public/Glibc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ set(sources
set(output_dir "${SWIFTLIB_DIR}/glibc")

# Set correct paths to glibc headers
set(GLIBC_INCLUDE_PATH "/usr/include")
set(GLIBC_INCLUDE_PATH "${CMAKE_SYSROOT}/usr/include")

if(CMAKE_LIBRARY_ARCHITECTURE)
set(GLIBC_ARCH_INCLUDE_PATH "${GLIBC_INCLUDE_PATH}/${CMAKE_LIBRARY_ARCHITECTURE}")
else()
Expand Down Expand Up @@ -40,7 +41,14 @@ swift_install_in_component(stdlib
FILES "${output_dir}/module.map"
DESTINATION "lib/swift/glibc")

# Include directories passed to include_directories command
get_directory_property(include_dirs INCLUDE_DIRECTORIES)
foreach(dir ${include_dirs})
set(GLIBC_EXTRA_FLAGS ${GLIBC_EXTRA_FLAGS} "-I" ${dir})
endforeach()

add_swift_library(swiftGlibc IS_SDK_OVERLAY
${sources}
FILE_DEPENDS copy_glibc_module "${output_dir}"
SWIFT_COMPILE_FLAGS "-I" "${GLIBC_INCLUDE_PATH}" "-I" "${GLIBC_ARCH_INCLUDE_PATH}" ${GLIBC_EXTRA_FLAGS}
INSTALL_IN_COMPONENT stdlib-experimental)
80 changes: 78 additions & 2 deletions utils/build-script
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,12 @@ details of the setups of other systems or automated environments.""")
"target. The built LLVM and Clang will be used to compile Swift "
"for the cross-compilation targets.",
default=swift_build_support.targets.host_target())
targets_group.add_argument(
"--cross-compile-stdlib-targets",
help="The cross-compliation targets. The Swift stdlib will be built for"
"these targets using the host-target LLVM, Clang and Swift",
metavar="TARGET",
nargs='*')

projects_group = parser.add_argument_group(
title="Options to select projects")
Expand Down Expand Up @@ -882,11 +888,55 @@ the number of parallel build jobs to use""",
"--skip-build-benchmarks",
]

if platform.system() == 'Darwin':
system = platform.system()
machine = platform.machine()

if system == 'Darwin':
build_script_impl_inferred_args += [
"--toolchain-prefix",
swift_build_support.targets.darwin_toolchain_prefix(args.install_prefix),
]
stdlib_deployment_targets = [
"macosx-x86_64",
"iphonesimulator-i386",
"iphonesimulator-x86_64",
"appletvsimulator-x86_64",
"watchsimulator-i386",

# Put iOS native targets last so that we test them last (it takes a
# long time).
"iphoneos-arm64",
"iphoneos-armv7",
"appletvos-arm64",
"watchos-armv7k"
]
stdlib_cross_targets = [
"linux-armv7"
]
elif system == 'Linux':
arch_mapping = [
('x86_64' , 'x86_64'),
('armv6' , 'armv6'),
('armv7' , 'armv7'),
('aarch64' , 'aarch64'),
('ppc64' , 'powerpc64'),
('ppc64le' , 'powerpc64le')
]
arch_mapping = [(x, 'linux-'+y) for (x,y) in arch_mapping]

host_target = next(t for (s,t) in arch_mapping if machine.startswith(s))
stdlib_deployment_targets = [host_target]

# All other linux-* targets
stdlib_cross_targets = [t for (_,t) in arch_mapping]
stdlib_cross_targets.remove(host_target)
elif system == 'FreeBSD' and machine == 'amd64':
stdlib_deployment_targets = ["freebsd-x86_64"]
elif system == 'CYGWIN_NT-10' and machine == 'x86_64':
stdlib_deployment_targets = ["cygwin-x86_64"]
else:
print_with_argv0("Unknown operating system")
return 1

if args.build_subdir is None:
# Create a name for the build directory.
Expand Down Expand Up @@ -1037,7 +1087,33 @@ the number of parallel build jobs to use""",
'watchsimulator',
])

check_call(build_script_impl_args)
host_build_script_impl_args = [
"--stdlib-deployment-targets=" + " ".join(stdlib_deployment_targets)
]

check_call(build_script_impl_args + host_build_script_impl_args)

if args.cross_compile_stdlib_targets:
# Filter cross_compile_stdlib_targets by those supported for this host
stdlib_cross_targets = set(stdlib_cross_targets).intersection(args.cross_compile_stdlib_targets)
# Currently only cross-compiling the swift libraries is supported.
# Building the swift compiler would require building llvm too.
llvm_path = os.path.join(build_dir, "llvm-"+args.host_target, 'bin')
swift_path = os.path.join(build_dir, "swift-"+args.host_target, 'bin')
build_script_impl_args += [
"--native-llvm-tools-path=" + llvm_path,
"--native-clang-tools-path=" + llvm_path,
"--native-swift-tools-path=" + swift_path,
"--skip-build-cmark=1",
"--skip-build-llvm=1",
"--skip-build-osx=1", # FIXME only if host is osx
"--build-swift-tools=0"
]

for target in stdlib_cross_targets:
check_call(build_script_impl_args +
["--cross-compile-deployment-targets=" + target,
"--stdlib-deployment-targets=" + target])

if args.symbols_package:
print('--- Creating symbols package ---')
Expand Down
Loading