Skip to content

Commit ef2b9d8

Browse files
committed
[cmake] On Darwin, teach add_swift_host_tool how to find swift's SDK/compat libs, fix the rpath of tools, and add tests.
There are three things going on here (note all on Darwin): 1. If one compiles a swift static library and links the static library into a cxx executable, the cxx executable will need the -L flags to find the appropriate libraries in the SDK/toolchain. 2. I fixed an rpath issue where due to old code I didn't understand/propagated forward, we were setting the rpath to be the -L directory in the appropriate SDK. After reasoning about this a little bit I realized that this was code that was actually intended to be used for target libraries (for which the given rpath would be correct). On the host side though on Darwin, we want to use the rpath for the standard stabilized stdlib on the system. 3. I added Build System Unittests to ensure that this keeps on working. I also added test cases that I should have added before. I just had never thought about how to test this and I realized this method would work and would prevent regressions while I am waiting for a new swiftc with driver fixes to land.
1 parent 799b615 commit ef2b9d8

File tree

10 files changed

+150
-3
lines changed

10 files changed

+150
-3
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,7 @@ endif()
10611061

10621062
if(SWIFT_INCLUDE_TESTS)
10631063
add_subdirectory(test)
1064+
add_subdirectory(validation-test)
10641065
add_subdirectory(unittests)
10651066
endif()
10661067
if(SWIFT_INCLUDE_DOCS)

cmake/modules/AddSwift.cmake

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ function(_add_host_variant_c_compile_flags target)
180180
target_compile_options(${target} PRIVATE -g)
181181
endif()
182182
else()
183-
target_compile_options(${target} PRIVATE -g0)
183+
target_compile_options(${target} PRIVATE $<$<COMPILE_LANGUAGE:C,CXX,OBJC,OBJCXX>:-g0>)
184+
target_compile_options(${target} PRIVATE $<$<COMPILE_LANGUAGE:Swift>:-gnone>)
184185
endif()
185186
endif()
186187

@@ -633,6 +634,19 @@ function(add_swift_host_tool executable)
633634
JOB_POOL_LINK swift_link_job_pool)
634635
endif()
635636
if(${SWIFT_HOST_VARIANT_SDK} IN_LIST SWIFT_APPLE_PLATFORMS)
637+
# If we found a swift compiler and are going to use swift code in swift
638+
# host side tools but link with clang, add the appropriate -L paths so we
639+
# find all of the necessary swift libraries on Darwin.
640+
if (CMAKE_Swift_COMPILER)
641+
# Add in the SDK directory for the host platform and add an rpath.
642+
target_link_directories(${executable} PRIVATE
643+
${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_ARCH_${SWIFT_HOST_VARIANT_ARCH}_PATH}/usr/lib/swift)
644+
# Add in the toolchain directory so we can grab compatibility libraries
645+
get_filename_component(TOOLCHAIN_BIN_DIR ${CMAKE_Swift_COMPILER} DIRECTORY)
646+
get_filename_component(TOOLCHAIN_LIB_DIR "${TOOLCHAIN_BIN_DIR}/../lib/swift/macosx" ABSOLUTE)
647+
target_link_directories(${executable} PUBLIC ${TOOLCHAIN_LIB_DIR})
648+
endif()
649+
636650
# Lists of rpaths that we are going to add to our executables.
637651
#
638652
# Please add each rpath separately below to the list, explaining why you are
@@ -644,8 +658,8 @@ function(add_swift_host_tool executable)
644658
# contain swift content.
645659
list(APPEND RPATH_LIST "@executable_path/../lib")
646660
647-
# Also include the swift specific resource dir in our rpath.
648-
list(APPEND RPATH_LIST "@executable_path/../lib/swift/${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_LIB_SUBDIR}")
661+
# Also include the abi stable system stdlib in our rpath.
662+
list(APPEND RPATH_LIST "/usr/lib/swift")
649663
650664
set_target_properties(${executable} PROPERTIES
651665
BUILD_WITH_INSTALL_RPATH YES
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
# Only test this if we found a Swift compiler.
3+
if (CMAKE_Swift_COMPILER)
4+
add_subdirectory(swift-cmake)
5+
endif()
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# In the absence of fine grained tablegen dependencies we need to ensure that
2+
# Swift's libraries all build after the LLVM & Clang tablegen-generated headers
3+
# are generated. When building out-of-tree (as with build-script) LLVM & Clang's
4+
# CMake configuration files create these targets as dummies so we can safely
5+
# depend on them directly here (See: SR-6026)
6+
# LLVM_COMMON_DEPENDS is a construct from the LLVM build system. It is a special
7+
# purpose variable that provides common dependencies for all libraries, and
8+
# executables generated when it is set. CMake's scoping rules enforce that these
9+
# new dependencies will only be added to targets created under Swift's lib
10+
# directory.
11+
list(APPEND LLVM_COMMON_DEPENDS intrinsics_gen clang-tablegen-targets)
12+
13+
# Add generated libSyntax headers to global dependencies.
14+
list(APPEND LLVM_COMMON_DEPENDS swift-syntax-generated-headers)
15+
list(APPEND LLVM_COMMON_DEPENDS swift-parse-syntax-generated-headers)
16+
17+
add_swift_host_library(TestCPPLib
18+
STATIC
19+
CPPLib.cpp)
20+
21+
add_swift_host_library(TestPureSwiftSharedLib
22+
SHARED
23+
PURE_SWIFT
24+
Klass.swift)
25+
target_link_libraries(TestPureSwiftSharedLib PRIVATE TestCPPLib)
26+
target_link_options(TestPureSwiftSharedLib PRIVATE "SHELL:-import-objc-header ${CMAKE_CURRENT_SOURCE_DIR}/CPPLib.h")
27+
28+
add_swift_host_library(TestPureSwiftStaticLib
29+
STATIC
30+
PURE_SWIFT
31+
Klass.swift)
32+
target_link_libraries(TestPureSwiftStaticLib PRIVATE TestCPPLib)
33+
target_compile_options(TestPureSwiftStaticLib PRIVATE "SHELL:-import-objc-header ${CMAKE_CURRENT_SOURCE_DIR}/CPPLib.h")
34+
35+
add_swift_host_tool(TestCPPToolLinkSwiftSharedLib
36+
CPPTool.cpp
37+
SWIFT_COMPONENT testsuite-tools
38+
)
39+
target_link_libraries(TestCPPToolLinkSwiftSharedLib PRIVATE TestPureSwiftSharedLib)
40+
41+
add_swift_host_tool(TestCPPToolLinkSwiftStaticLib
42+
CPPTool.cpp
43+
SWIFT_COMPONENT testsuite-tools
44+
)
45+
target_link_libraries(TestCPPToolLinkSwiftStaticLib
46+
PRIVATE
47+
TestPureSwiftStaticLib)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
#include <cstdio>
3+
#include "CPPLib.h"
4+
5+
extern "C" {
6+
void CPPLib_log() {
7+
printf("I am in cpplib log!\n");
8+
}
9+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
2+
#ifndef SWIFT_TEST_CPPLIB
3+
#define SWIFT_TEST_CPPLIB
4+
5+
#ifdef __cplusplus
6+
extern "C" {
7+
#endif
8+
void CPPLib_log();
9+
#ifdef __cplusplus
10+
}
11+
#endif
12+
13+
#endif
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===--- CPPTool.cpp ------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
///
13+
/// Calls a method from one of the swift libraries.
14+
///
15+
//===----------------------------------------------------------------------===//
16+
17+
#include <cstdio>
18+
19+
extern "C" {
20+
int doSomething();
21+
}
22+
23+
int main(int argc, char *argv[]) {
24+
printf("doSomething: %d\n", doSomething());
25+
return 0;
26+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// This isn't a test but lit wants to treat it as a test! Make it exit -1 to
2+
// make sure lit doesn't run this file and add a REQUIRES line so we actually
3+
// never do that.
4+
//
5+
// RUN: exit -1
6+
// REQUIRES: not_a_test
7+
8+
public class Klass {}
9+
10+
public func useKlass(_ k: Klass) {}
11+
12+
@_cdecl("doSomething")
13+
public func doSomething() -> Int {
14+
CPPLib_log()
15+
let x: Int = 34
16+
// Make sure we link against SwiftCore.
17+
print("Swift is going to return \(34)")
18+
return x
19+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# REQUIRES: standalone_build,OS=macosx
2+
3+
# Test that makes sure when we link in a pure swift shared lib into a cxx tool
4+
# that we set rpaths right and thus can run the test.
5+
6+
# RUN: %swift_obj_root/bin/TestCPPToolLinkSwiftSharedLib | %FileCheck %s
7+
# RUN: %swift_obj_root/bin/TestCPPToolLinkSwiftStaticLib | %FileCheck %s
8+
9+
# CHECK: I am in cpplib log!
10+
# CHECK: Swift is going to return 34
11+
# CHECK: doSomething: 34

validation-test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
add_subdirectory(BuildSystem)

0 commit comments

Comments
 (0)