Skip to content

Commit e673cd1

Browse files
authored
Merge pull request #9 from etcwilde/ewilde/fix-cxx-interop-deps-graph
CXX-Interop: Fix missing header deps edge
2 parents 7a86d39 + 51d1ba4 commit e673cd1

File tree

2 files changed

+55
-53
lines changed

2 files changed

+55
-53
lines changed

3_bidirectional_cxx_interop/cmake/modules/AddSwift.cmake

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,29 @@
55
#
66
# See https://swift.org/LICENSE.txt for license information
77

8-
include(CheckCompilerFlag)
9-
10-
# Generate bridging header from Swift to C++
11-
# NOTE: This logic will eventually be upstreamed into CMake
12-
function(_swift_generate_cxx_header_target target module header)
13-
cmake_parse_arguments(ARG "" "" "SOURCES;SEARCH_PATHS;DEPENDS" ${ARGN})
14-
if(NOT ARG_SOURCES)
15-
message(FATAL_ERROR "No sources provided to 'swift_generate_cxx_header_target'")
8+
9+
# Generate the bridging header from Swift to C++
10+
#
11+
# target: the name of the target to generate headers for.
12+
# This target must build swift source files.
13+
# header: the name of the header file to generate.
14+
#
15+
# NOTE: This logic will eventually be unstreamed into CMake.
16+
function(_swift_generate_cxx_header target header)
17+
if(NOT TARGET ${target})
18+
message(FATAL_ERROR "Target ${target} not defined.")
19+
endif()
20+
21+
if(NOT DEFINED CMAKE_Swift_COMPILER)
22+
message(WARNING "Swift not enabled in project. Cannot generate headers for Swift files.")
23+
return()
24+
endif()
25+
26+
cmake_parse_arguments(ARG "" "" "SEARCH_PATHS;MODULE_NAME" ${ARGN})
27+
28+
if(NOT ARG_MODULE_NAME)
29+
set(target_module_name $<TARGET_PROPERTY:${target},Swift_MODULE_NAME>)
30+
set(ARG_MODULE_NAME $<IF:$<BOOL:${target_module_name}>,${target_module_name},${target}>)
1631
endif()
1732

1833
if(ARG_SEARCH_PATHS)
@@ -23,27 +38,36 @@ function(_swift_generate_cxx_header_target target module header)
2338
set(SDK_FLAGS "-sdk" "${CMAKE_OSX_SYSROOT}")
2439
elseif(WIN32)
2540
set(SDK_FLAGS "-sdk" "$ENV{SDKROOT}")
41+
elseif(DEFINED ${CMAKE_SYSROOT})
42+
set(SDK_FLAGS "-sdk" "${CMAKE_SYSROOT}")
2643
endif()
2744

28-
add_custom_command(
29-
OUTPUT
30-
"${header}"
45+
cmake_path(APPEND CMAKE_CURRENT_BINARY_DIR include
46+
OUTPUT_VARIABLE base_path)
47+
48+
cmake_path(APPEND base_path ${header}
49+
OUTPUT_VARIABLE header_path)
50+
51+
set(_AllSources $<TARGET_PROPERTY:${target},SOURCES>)
52+
set(_SwiftSources $<FILTER:${_AllSources},INCLUDE,\\.swift$>)
53+
add_custom_command(OUTPUT ${header_path}
54+
DEPENDS ${_SwiftSources}
55+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
3156
COMMAND
3257
${CMAKE_Swift_COMPILER} -frontend -typecheck
3358
${ARG_SEARCH_PATHS}
34-
${ARG_SOURCES}
59+
${_SwiftSources}
3560
${SDK_FLAGS}
36-
-module-name "${module}"
61+
-module-name "${ARG_MODULE_NAME}"
3762
-cxx-interoperability-mode=default
38-
-emit-clang-header-path "${header}"
39-
DEPENDS
40-
${ARG_DEPENDS}
63+
-emit-clang-header-path ${header_path}
4164
COMMENT
42-
"Generating '${header}'"
43-
)
65+
"Generating '${header_path}'"
66+
COMMAND_EXPAND_LISTS)
4467

45-
add_custom_target("${target}"
46-
DEPENDS
47-
"${header}"
48-
)
68+
# Added to public interface for dependees to find.
69+
target_include_directories(${target} PUBLIC ${base_path})
70+
# Added to the target to ensure target rebuilds if header changes and is used
71+
# by sources in the target.
72+
target_sources(${target} PRIVATE ${header_path})
4973
endfunction()

3_bidirectional_cxx_interop/lib/fibonacci/CMakeLists.txt

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,16 @@
55
#
66
# See https://swift.org/LICENSE.txt for license information
77

8-
9-
# Generate a C++ header from Swift sources
10-
#
11-
# This function is implemented in cmake/modules/AddSwift.cmake.
12-
#
13-
# _swift_generate_cxx_header_target(target-name,
14-
# SwiftModule/C++ namespace,
15-
# generated header path)
16-
_swift_generate_cxx_header_target(
17-
fibonacci_swift_h
18-
SwiftFibonacci
19-
"${CMAKE_CURRENT_BINARY_DIR}/include/fibonacci/fibonacci-swift.h"
20-
SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/fibonacci.swift"
21-
SEARCH_PATHS "${PINGPONG_INCLUDE_DIR}")
22-
23-
# 1. Create a library from the Swift and C++ sources.
24-
# 2. The library requires the Swift header in order to compile, so we create a
25-
# dependency between the library and the header target created above.
26-
# 3. This libraries, and users of this library, will need to find the
27-
# generated header, so we direct CMake to emit `PUBLIC` a public header
28-
# search path, ensuring that dependees of this library also pick up this
29-
# search path.
30-
# 4. Manually override the Swift module name to "SwiftFibonacci" to match the
31-
# name in the generated header header above.
32-
# 5. Enable C++ interoperability mode on all Swift compilations. Again, this is
33-
# required for users of this library, so we make it 'PUBLIC' to ensure the
34-
# flag is propagated to users of the library. Emitting the flag is gated by
35-
# the COMPILE_LANGUAGE cmake generator expression to ensure that the flag is
36-
# only passed to the Swift compiler and not the C++ compiler.
378
add_library(fibonacci STATIC fibonacci.swift fibonacci.cpp)
38-
add_dependencies(fibonacci fibonacci_swift_h)
39-
target_include_directories(fibonacci PUBLIC "${CMAKE_CURRENT_BINARY_DIR}/include")
409
set_target_properties(fibonacci PROPERTIES Swift_MODULE_NAME "SwiftFibonacci")
4110
target_compile_options(fibonacci PUBLIC
4211
"$<$<COMPILE_LANGUAGE:Swift>:-cxx-interoperability-mode=default>")
12+
13+
# Generate a C++ header from Swift sources. This is automatically added to the
14+
# fibonacci target. The target will regenerate the header file when any of the
15+
# Swift sources change. Clang detects that the C++ file depends on the header,
16+
# and tells Ninja about this dependency in the depfile.
17+
# This function is implemented in cmake/modules/AddSwift.cmake.
18+
_swift_generate_cxx_header(fibonacci
19+
fibonacci/fibonacci-swift.h
20+
SEARCH_PATHS "${PINGPONG_INCLUDE_DIR}")

0 commit comments

Comments
 (0)