Skip to content

Commit c0b1fd2

Browse files
authored
Support building macro plugin as a library instead of executable via CMake (#517)
This adds support in the CMake rules for building the `TestingMacros` macro plugin target as a library instead of an executable. ### Motivation: In preparation for adding Swift Testing to Swift.org toolchains (as [mentioned](https://github.com/swiftlang/swift-evolution/blob/main/visions/swift-testing.md#distribution) in the vision document), this modifies the project's CMake rules to allow building its macro plugin in a way that is consistent with others in the toolchain — as a shared library rather than an executable. Macros in the toolchain can be libraries which are directly loaded by the compiler and avoid the IPC overhead of being a separate executable. ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent de7171a commit c0b1fd2

File tree

6 files changed

+66
-23
lines changed

6 files changed

+66
-23
lines changed

Package.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ let package = Package(
6868
],
6969
exclude: ["CMakeLists.txt"],
7070
swiftSettings: .packageSettings + [
71+
// When building as a package, the macro plugin always builds as an
72+
// executable rather than a library.
73+
.define("SWT_NO_LIBRARY_MACRO_PLUGINS"),
74+
7175
// The only target which needs the ability to import this macro
7276
// implementation target's module is its unit test target. Users of the
7377
// macros this target implements use them via their declarations in the

Sources/CMakeLists.txt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@ if(NOT SwiftTesting_MACRO_MAKE_PROGRAM)
1212
set(SwiftTesting_MACRO_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM})
1313
endif()
1414

15+
find_package(SwiftSyntax CONFIG GLOBAL)
16+
if(SwiftSyntax_FOUND)
17+
set(SwiftTesting_BuildMacrosAsExecutables NO)
18+
else()
19+
set(SwiftTesting_BuildMacrosAsExecutables YES)
20+
endif()
21+
1522
ExternalProject_Add(TestingMacros
1623
PREFIX "tm"
1724
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/TestingMacros"
1825
CMAKE_ARGS
1926
-DCMAKE_MAKE_PROGRAM=${SwiftTesting_MACRO_MAKE_PROGRAM}
27+
-DSwiftTesting_BuildMacrosAsExecutables=${SwiftTesting_BuildMacrosAsExecutables}
28+
-DSwiftSyntax_DIR=${SwiftSyntax_DIR}
2029
INSTALL_COMMAND "")
2130
ExternalProject_Get_Property(TestingMacros BINARY_DIR)
22-
if(CMAKE_HOST_WIN32)
23-
set(TestingMacrosPath "${BINARY_DIR}/TestingMacros.exe#TestingMacros")
24-
else()
25-
set(TestingMacrosPath "${BINARY_DIR}/TestingMacros#TestingMacros")
26-
endif()
2731

2832
include(AvailabilityDefinitions)
2933
include(CompilerSettings)

Sources/Testing/CMakeLists.txt

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,17 @@ target_link_libraries(Testing PRIVATE
9696
_TestingInternals)
9797
add_dependencies(Testing
9898
TestingMacros)
99-
target_compile_definitions(Testing PRIVATE
100-
SWT_BUILDING_WITH_CMAKE)
101-
target_compile_options(Testing PUBLIC
102-
-load-plugin-executable "${TestingMacrosPath}")
10399
target_compile_options(Testing PRIVATE
104100
-enable-library-evolution)
101+
102+
if(SwiftTesting_BuildMacrosAsExecutables)
103+
if(CMAKE_HOST_WIN32)
104+
set(_TestingMacros_ExecutableSuffix ".exe")
105+
endif()
106+
107+
target_compile_options(Testing PUBLIC
108+
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-load-plugin-executable ${BINARY_DIR}/TestingMacros${_TestingMacros_ExecutableSuffix}#TestingMacros>")
109+
else()
110+
target_compile_options(Testing PUBLIC
111+
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-plugin-path ${BINARY_DIR}>")
112+
endif()

Sources/TestingMacros/CMakeLists.txt

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ if(WIN32)
2222
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
2323
endif()
2424

25-
include(FetchContent)
2625
find_package(SwiftSyntax CONFIG GLOBAL)
27-
if(NOT SwiftSyntax_FOUND)
26+
27+
if(SwiftTesting_BuildMacrosAsExecutables)
28+
# When building the macro plugin as an executable, clone and build
29+
# swift-syntax.
30+
include(FetchContent)
2831
set(FETCHCONTENT_BASE_DIR ${CMAKE_BINARY_DIR}/_d)
2932
# TODO: Update GIT_TAG to the 6.0 release tag once it is available.
3033
FetchContent_Declare(SwiftSyntax
@@ -33,9 +36,31 @@ if(NOT SwiftSyntax_FOUND)
3336
FetchContent_MakeAvailable(SwiftSyntax)
3437
endif()
3538

39+
# Include these modules _after_ swift-syntax is declared above, but _before_ the
40+
# macro plugin target is declared below, so that its settings are not applied to
41+
# the former but are applied to the latter.
3642
include(AvailabilityDefinitions)
3743
include(CompilerSettings)
38-
add_executable(TestingMacros
44+
45+
if(SwiftTesting_BuildMacrosAsExecutables)
46+
# When swift-syntax is built locally, the macro plugin must be built as an
47+
# executable.
48+
add_executable(TestingMacros)
49+
50+
set_target_properties(TestingMacros PROPERTIES
51+
ENABLE_EXPORTS TRUE)
52+
53+
# Parse the module as a library, even though it's an executable, because it
54+
# uses an `@main` type to define its entry point.
55+
target_compile_options(TestingMacros PRIVATE -parse-as-library)
56+
57+
# Include the .swift file which contains its `@main` entry point type.
58+
target_compile_definitions(TestingMacros PRIVATE SWT_NO_LIBRARY_MACRO_PLUGINS)
59+
else()
60+
add_library(TestingMacros SHARED)
61+
endif()
62+
63+
target_sources(TestingMacros PRIVATE
3964
ConditionMacro.swift
4065
SourceLocationMacro.swift
4166
SuiteDeclarationMacro.swift
@@ -61,14 +86,13 @@ add_executable(TestingMacros
6186
TagMacro.swift
6287
TestDeclarationMacro.swift
6388
TestingMacrosMain.swift)
64-
set_target_properties(TestingMacros PROPERTIES
65-
ENABLE_EXPORTS TRUE)
66-
target_compile_options(TestingMacros PRIVATE -parse-as-library)
89+
6790
target_link_libraries(TestingMacros PRIVATE
68-
SwiftSyntax::SwiftCompilerPlugin
6991
SwiftSyntax::SwiftSyntax
7092
SwiftSyntax::SwiftSyntaxMacroExpansion
71-
SwiftSyntax::SwiftSyntaxMacros
72-
SwiftSyntax509
73-
SwiftSyntax510
74-
SwiftSyntax600)
93+
SwiftSyntax::SwiftSyntaxMacros)
94+
if(SwiftTesting_BuildMacrosAsExecutables)
95+
# Link the 'SwiftCompilerPlugin' target, but only when built as an executable.
96+
target_link_libraries(TestingMacros PRIVATE
97+
SwiftSyntax::SwiftCompilerPlugin)
98+
endif()

Sources/TestingMacros/TestingMacrosMain.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
99
//
1010

11-
#if canImport(SwiftCompilerPlugin)
11+
#if SWT_NO_LIBRARY_MACRO_PLUGINS
1212
import SwiftCompilerPlugin
1313
import SwiftSyntaxMacros
1414

cmake/modules/shared/CompilerSettings.cmake

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# See http://swift.org/LICENSE.txt for license information
77
# See http://swift.org/CONTRIBUTORS.txt for Swift project authors
88

9-
# Settings intended to be applied to every Swift target in this package.
9+
# Settings intended to be applied to every Swift target in this project.
1010
# Analogous to project-level build settings in an Xcode project.
1111
add_compile_options(
1212
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -require-explicit-sendable>")
@@ -16,7 +16,10 @@ add_compile_options(
1616
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -enable-upcoming-feature -Xfrontend ExistentialAny>"
1717
"SHELL:$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend -enable-upcoming-feature -Xfrontend InternalImportsByDefault>")
1818

19-
# Platform specific defines.
19+
# Definitions applied unconditionally to files of all languages, in all targets.
20+
add_compile_definitions("SWT_BUILDING_WITH_CMAKE")
21+
22+
# Platform-specific definitions.
2023
if(APPLE)
2124
add_compile_definitions("SWT_TARGET_OS_APPLE")
2225
endif()

0 commit comments

Comments
 (0)