# Swift package (PackageDescription)

**URL:** https://discourse.cmake.org/t/swift-package-packagedescription/15865
**Category:** Usage
**Tags:** os:windows, lang:swift
**Created:** [October 9, 2026, 9:08pm UTC](https://discourse.cmake.org/t/swift-package-packagedescription/15865 "2026-10-09T21:08:33Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Wallby](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/w/4491bb/32.png) [@Wallby](https://discourse.cmake.org/u/Wallby)
#### Post date: [October 9, 2026, 9:08pm UTC](https://discourse.cmake.org/t/swift-package-packagedescription/15865/1 "2026-10-09T21:08:33Z")

</div>

Is it possible to create a Swift package project (i.e. as can be created by `swift package init ...`) using CMake?

The example repository by swiftlang on GitHub doesn’t contain this as an example. And there is no issue that addresses this either (one issue that mentions packages, seems to be about using the binary in an external package project, not creating a package project from CMake).  
[https://github.com/swiftlang/swift-cmake-examples](https://github.com/swiftlang/swift-cmake-examples)

I tried compiling a .swift file that requires dependencies specified in a `Package.swift` file that is in the source folder next to the CMakeLists.txt. As I added the CMakeLists.txt to an existing Swift package project. This didn’t work. Errors about the import statements in the .swift source files are output, that those packages cannot be found.

I also tried adding the `Package.swift` to the `add_executable` command.

```cmake
add_executable(Example Package.swift ${sources})

```

… but that didn’t work either. The `PackageDescription` module can also not be found. I was also not sure what adding that file might even do, if it would try to build the project twice (once via CMake and once via the `Package.swift` file). But it didn’t work.

It of course works to use `add_custom_target`. And in my case the `.build` folder is also the `CMAKE_CURRENT_BINARY_DIR`. Which seems to not conflict with CMake. But not sure if it might. And it is also error-prone. As `${sources}` is merely for telling CMake when to run. So in this case a `file(GLOB ...)` would be required.

```cmake
add_custom_target(Example ALL
    COMMAND swift build
    DEPENDS ${sources}
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

```

The build folder for swift can be modified using `--scratch-path`. So it no longer conflicts.

Update:

I misunderstood that `add_custom_target` doesn’t require `DEPENDS` to trigger, it always triggers.

I cannot use `add_custom_command`, as it would require `file(REAL_PATH ...)` for a generator expression path I think?: `$<IF:$<CONFIG:Debug>,debug,release>` (release and debug are symlinks created by swift).

So instead, I now have

```cmake
add_custom_target(_Example ALL
    COMMAND swift build --scratch-path "${CMAKE_CURRENT_BINARY_DIR}/swift"
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    VERBATIM
)

add_executable(Example IMPORTED)
set_target_properties(Example
    PROPERTIES
    IMPORTED_LOCATION_Debug "${CMAKE_CURRENT_BINARY_DIR}/swift/debug"
    IMPORTED_LOCATION_Release "${CMAKE_CURRENT_BINARY_DIR}/swift/release"
)

```

Using generator Ninja Multi-Config

---

<div class="post-metadata">

### Author: ![Wallby](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/w/4491bb/32.png) [@Wallby](https://discourse.cmake.org/u/Wallby)
#### Post date: [October 10, 2026, 11:12am UTC](https://discourse.cmake.org/t/swift-package-packagedescription/15865/3 "2026-10-10T11:12:29Z")

</div>

I happened to notice inside of one of the repositories swift copies to .build/checkouts, that CMakeLists.txt files are present. Which seem to also use external packages?

This one from swift-subprocess:

```cmake
find_package(SwiftSystem QUIET)
if(NOT SwiftSystem_FOUND)
  message("-- Vendoring swift-system")
  FetchContent_Declare(SwiftSystem
    GIT_REPOSITORY https://github.com/apple/swift-system.git
    GIT_TAG a34201439c74b53f0fd71ef11741af7e7caf01e1 # 1.4.2
    GIT_SHALLOW YES)
  list(APPEND VendoredDependencies SwiftSystem)
endif()

```

Is that how to use Swift packages?

Update: Some dependencies don’t have CMakeLists.txt files. So this approach won’t suffice.

---

<div class="post-metadata">

### Author: ![Wallby](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/w/4491bb/32.png) [@Wallby](https://discourse.cmake.org/u/Wallby)
#### Post date: [October 11, 2026, 10:46am UTC](https://discourse.cmake.org/t/swift-package-packagedescription/15865/6 "2026-10-11T10:46:28Z")

</div>

Some more progress, discovered instead of using a generator expression that relies on swift’s generated symbolic links. You can also use `--show-bin-path` to get the absolute path:

```cmake
execute_process(
    COMMAND swift build --scratch-path "${CMAKE_CURRENT_BINARY_DIR}/swift" -c release --show-bin-path
    OUTPUT_VARIABLE swiftBinaryPath
)

```

I did not know that set\_target\_properties requires the specified config to be capitalized[1](https://gitlab.kitware.com/cmake/cmake/blob/v3.6.1/Source/cmTarget.cxx#L1522). So the above did not work. I now have the default `IMPORTED_LOCATION` set to the release folder, and otherwise `IMPORTED_LOCATION_DEBUG` set to the debug folder. And also added the file name at the end of the `IMPORTED_LOCATION[_...]` values, e.g. `example${CMAKE_EXECUTABLE_SUFFIX}`.

I have also added `USES_TERMINAL` to add\_custom\_target, to see the output of swift. As swift (with several dependencies specific in Package.swift) seems to always take a long time to compile, even if nothing has changed.

I’ve also added some install code:

```cmake
install(CODE "
file(COPY \"\$<TARGET_FILE:${executableTgt}>\" DESTINATION \"\${CMAKE_CURRENT_SOURCE_DIR}/.artifacts\")
# https://cmake.org/cmake/help/latest/variable/CMAKE_SYSTEM_NAME.html
# Swift also generates one folder ending with .resources
if(${CMAKE_SYSTEM_NAME} STREQUAL \"Windows\")
    file(
        GLOB sharedLibraries
        LIST_DIRECTORIES false
        \"\$<TARGET_FILE_DIR:${executableTgt}>/*.dll\"
    )
    file(
        GLOB sharedLibraryFolders
        LIST_DIRECTORIES true
        \"\$<TARGET_FILE_DIR:${executableTgt}>/*.resources/\"
    )
    #file(COPY \"\${sharedLibraries}\" DESTINATION \"\${CMAKE_CURRENT_SOURCE_DIR}/.artifacts\")
    foreach(sharedLibraryItem \${sharedLibraries} \${sharedLibraryFolders})
        file(COPY \"\${sharedLibraryItem}\" DESTINATION \"\${CMAKE_CURRENT_SOURCE_DIR}/.artifacts\")
    endforeach()
endif()
")

```

I tried `CMAKE_SYSTEM_NAME` without `${}` at first, but it seems that at install time this variable is empty.

There seem to be a few documentation issues. One of which being the capitalization rules of IMPORTED\_LOCAITON\_ not being documented on add\_target\_properties.

Another one is that `file(COPY ...)` according to the documentation takes a list of files.

> ```cmake
> file(<COPY|INSTALL> <files>...
> 
> ```

[Source](https://cmake.org/cmake/help/latest/command/file.html#copy)

But I got an error about a single file containing ; characters. So it seems this doesn’t work. Hence the `foreach`.
