From f665628c2e37ad34d1438ac2b602f7600e4c986b Mon Sep 17 00:00:00 2001 From: Carlos Zoido Date: Tue, 11 Aug 2026 17:33:00 +0200 Subject: [PATCH 1/9] wip --- README.md | 2 ++ examples/languages/README.md | 5 +++ .../swift/cxx_interop/CMakeLists.txt | 21 ++++++++++++ .../languages/swift/cxx_interop/README.md | 34 +++++++++++++++++++ .../swift/cxx_interop/ci_test_example.py | 27 +++++++++++++++ .../languages/swift/cxx_interop/conanfile.py | 26 ++++++++++++++ .../languages/swift/cxx_interop/main.swift | 32 +++++++++++++++++ 7 files changed, 147 insertions(+) create mode 100644 examples/languages/README.md create mode 100644 examples/languages/swift/cxx_interop/CMakeLists.txt create mode 100644 examples/languages/swift/cxx_interop/README.md create mode 100644 examples/languages/swift/cxx_interop/ci_test_example.py create mode 100644 examples/languages/swift/cxx_interop/conanfile.py create mode 100644 examples/languages/swift/cxx_interop/main.swift diff --git a/README.md b/README.md index 4dd8739e..bd0c99f8 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ Sources for the [examples section](https://docs.conan.io/2/examples.html) of the ### [Libraries examples](examples/libraries) +### [Language interoperability examples](examples/languages) + ### [Graph examples](examples/graph) ### [Security examples](examples/security) \ No newline at end of file diff --git a/examples/languages/README.md b/examples/languages/README.md new file mode 100644 index 00000000..dc8f3713 --- /dev/null +++ b/examples/languages/README.md @@ -0,0 +1,5 @@ +## Language interoperability examples + +### [Swift / C++ interop](swift/cxx_interop) + +- Consume plain, Swift-unaware ConanCenter C++ packages directly from a Swift app, using Swift's C++ interoperability mode. diff --git a/examples/languages/swift/cxx_interop/CMakeLists.txt b/examples/languages/swift/cxx_interop/CMakeLists.txt new file mode 100644 index 00000000..b2fa63a5 --- /dev/null +++ b/examples/languages/swift/cxx_interop/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.28) +project(swift_cpp_demo LANGUAGES CXX Swift) + +find_package(lunasvg REQUIRED) + +add_executable(demo main.swift) + +target_link_libraries(demo PRIVATE + lunasvg::lunasvg +) + +# Module map generated by conanfile.py's generate() for the Swift-unaware lunasvg headers. +get_filename_component(_conan_generators_dir "${CMAKE_TOOLCHAIN_FILE}" DIRECTORY) + +# CMAKE_CXX_STANDARD comes from Conan's CMakeToolchain, derived from the profile's +# compiler.cppstd, so this doesn't drift from what lunasvg itself was built with. +target_compile_options(demo PRIVATE + "$<$:-cxx-interoperability-mode=default>" + "$<$:SHELL:-Xcc -std=c++${CMAKE_CXX_STANDARD}>" + "$<$:SHELL:-Xcc -fmodule-map-file=${_conan_generators_dir}/shim/lunasvg.modulemap>" +) diff --git a/examples/languages/swift/cxx_interop/README.md b/examples/languages/swift/cxx_interop/README.md new file mode 100644 index 00000000..6113f5c5 --- /dev/null +++ b/examples/languages/swift/cxx_interop/README.md @@ -0,0 +1,34 @@ +# Swift / C++ interop with Conan-managed dependencies + +A Swift app that consumes a plain, Swift-unaware ConanCenter package -- +[lunasvg](https://conan.io/center/recipes/lunasvg) -- directly, via +[Swift's C++ interoperability mode](https://www.swift.org/documentation/cxx-interop/). +Swift builds an SVG scene as a string, hands it to lunasvg's C++ `Document` +and `Bitmap` classes to parse and rasterize, and writes the result to a PNG +file -- no C wrapper library needed. + +Since lunasvg ships no Swift module map, `conanfile.py`'s `generate()` writes +a small [Clang module map](https://clang.llvm.org/docs/Modules.html) pointing +at its real installed header (read from `cpp_info`), and `CMakeLists.txt` +passes that to `swiftc` via `-Xcc -fmodule-map-file=...` together with +`-cxx-interoperability-mode=default`. + +## Requirements + +- macOS with Xcode command line tools (`swiftc`), Swift 5.9+. +- CMake >= 3.28, with the Ninja generator: CMake's Swift support doesn't work + with the "Unix Makefiles" default some CMake versions pick on macOS. + +## Build and run + +```bash +git clone https://github.com/conan-io/examples2.git +cd examples2/examples/languages/swift/cxx_interop + +conan install . --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja +cmake --preset conan-release +cmake --build --preset conan-release +./build/Release/demo +``` + +The program renders the SVG and writes `summer.png` to the working directory. diff --git a/examples/languages/swift/cxx_interop/ci_test_example.py b/examples/languages/swift/cxx_interop/ci_test_example.py new file mode 100644 index 00000000..50c74398 --- /dev/null +++ b/examples/languages/swift/cxx_interop/ci_test_example.py @@ -0,0 +1,27 @@ +import platform +import re +import subprocess + +from test.examples_tools import run + +# ############# Example ################ +print("Swift <-> C++ interop: consuming a plain ConanCenter package from Swift") + + +def _cmake_supports_swift(minimum=(3, 28)): + try: + output = subprocess.run(["cmake", "--version"], capture_output=True, text=True, check=True).stdout + except FileNotFoundError: + return False + match = re.search(r"(\d+)\.(\d+)\.(\d+)", output) + return bool(match) and tuple(int(x) for x in match.groups()[:2]) >= minimum + + +if platform.system() != "Darwin" or not _cmake_supports_swift(): + print("WARNING: Skipping Swift interop example, requires macOS with swiftc and CMake >= 3.28") +else: + run("conan install . --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja") + run("cmake --preset conan-release") + run("cmake --build --preset conan-release") + # No window/event loop involved, so the binary can run headlessly in CI. + run("./build/Release/demo") diff --git a/examples/languages/swift/cxx_interop/conanfile.py b/examples/languages/swift/cxx_interop/conanfile.py new file mode 100644 index 00000000..9675b14b --- /dev/null +++ b/examples/languages/swift/cxx_interop/conanfile.py @@ -0,0 +1,26 @@ +import os +from conan import ConanFile +from conan.tools.cmake import CMakeToolchain, CMakeDeps, cmake_layout +from conan.tools.files import save + + +class SwiftCppDemo(ConanFile): + settings = "os", "arch", "compiler", "build_type" + + def layout(self): + cmake_layout(self) + + def requirements(self): + self.requires("lunasvg/3.5.0") + + def _write_modulemap(self, filename, module_name, header_path): + content = f'module {module_name} {{\n header "{header_path}"\n export *\n}}\n' + save(self, os.path.join(self.generators_folder, "shim", filename), content) + + def generate(self): + CMakeDeps(self).generate() + CMakeToolchain(self).generate() + + # lunasvg has no Swift module map; write a shim one from its cpp_info. + lunasvg_include = self.dependencies["lunasvg"].cpp_info.includedirs[0] + self._write_modulemap("lunasvg.modulemap", "LunaSVGMod", f"{lunasvg_include}/lunasvg/lunasvg.h") diff --git a/examples/languages/swift/cxx_interop/main.swift b/examples/languages/swift/cxx_interop/main.swift new file mode 100644 index 00000000..3fc28558 --- /dev/null +++ b/examples/languages/swift/cxx_interop/main.swift @@ -0,0 +1,32 @@ +import CxxStdlib +import LunaSVGMod + +// lunasvg has no styling of its own; this stylesheet colors the markup below. +let svg = """ + + + + + + + + + + Swift + C++ + Conan + + + + + + +""" + +let css = ".sky{fill:#8ECBEB} .hills{fill:#8FA89B} .ground{fill:#8FC77E} .cloud{fill:#FFFFFF} .title{fill:#3B4A40}" + +let document = lunasvg.Document.loadFromData(std.string(svg)) +document.pointee.applyStyleSheet(std.string(css)) + +let bitmap = document.pointee.renderToBitmap() +_ = bitmap.writeToPng(std.string("summer.png")) + +print("Generated summer.png") From 9bead9f7c3c5e82591d94ec5e0c264ff615912d4 Mon Sep 17 00:00:00 2001 From: Carlos Zoido Date: Tue, 11 Aug 2026 19:39:32 +0200 Subject: [PATCH 2/9] wip --- .../swift/cxx_interop/CMakeLists.txt | 7 +----- .../languages/swift/cxx_interop/conanfile.py | 23 +++++++++++++------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/examples/languages/swift/cxx_interop/CMakeLists.txt b/examples/languages/swift/cxx_interop/CMakeLists.txt index b2fa63a5..69a9400e 100644 --- a/examples/languages/swift/cxx_interop/CMakeLists.txt +++ b/examples/languages/swift/cxx_interop/CMakeLists.txt @@ -9,13 +9,8 @@ target_link_libraries(demo PRIVATE lunasvg::lunasvg ) -# Module map generated by conanfile.py's generate() for the Swift-unaware lunasvg headers. -get_filename_component(_conan_generators_dir "${CMAKE_TOOLCHAIN_FILE}" DIRECTORY) - -# CMAKE_CXX_STANDARD comes from Conan's CMakeToolchain, derived from the profile's -# compiler.cppstd, so this doesn't drift from what lunasvg itself was built with. target_compile_options(demo PRIVATE "$<$:-cxx-interoperability-mode=default>" "$<$:SHELL:-Xcc -std=c++${CMAKE_CXX_STANDARD}>" - "$<$:SHELL:-Xcc -fmodule-map-file=${_conan_generators_dir}/shim/lunasvg.modulemap>" + "$<$:SHELL:-Xcc -fmodule-map-file=${LUNASVG_MODULEMAP}>" ) diff --git a/examples/languages/swift/cxx_interop/conanfile.py b/examples/languages/swift/cxx_interop/conanfile.py index 9675b14b..e978781b 100644 --- a/examples/languages/swift/cxx_interop/conanfile.py +++ b/examples/languages/swift/cxx_interop/conanfile.py @@ -1,4 +1,5 @@ import os +import textwrap from conan import ConanFile from conan.tools.cmake import CMakeToolchain, CMakeDeps, cmake_layout from conan.tools.files import save @@ -13,14 +14,22 @@ def layout(self): def requirements(self): self.requires("lunasvg/3.5.0") - def _write_modulemap(self, filename, module_name, header_path): - content = f'module {module_name} {{\n header "{header_path}"\n export *\n}}\n' - save(self, os.path.join(self.generators_folder, "shim", filename), content) - def generate(self): CMakeDeps(self).generate() - CMakeToolchain(self).generate() # lunasvg has no Swift module map; write a shim one from its cpp_info. - lunasvg_include = self.dependencies["lunasvg"].cpp_info.includedirs[0] - self._write_modulemap("lunasvg.modulemap", "LunaSVGMod", f"{lunasvg_include}/lunasvg/lunasvg.h") + include_dir = self.dependencies["lunasvg"].cpp_info.includedir + header = f"{include_dir}/lunasvg/lunasvg.h" + + modulemap_path = os.path.join(self.generators_folder, "lunasvg.modulemap") + modulemap = textwrap.dedent(f'''\ + module LunaSVGMod {{ + header "{header}" + export * + }} + ''') + save(self, modulemap_path, modulemap) + + tc = CMakeToolchain(self) + tc.variables["LUNASVG_MODULEMAP"] = modulemap_path + tc.generate() From 9acdff71418560231add0f0cdc8e8c710cf0c63c Mon Sep 17 00:00:00 2001 From: Carlos Zoido Date: Wed, 12 Aug 2026 08:01:07 +0200 Subject: [PATCH 3/9] wip --- .../languages/swift/cxx_interop/CMakeLists.txt | 2 +- examples/languages/swift/cxx_interop/README.md | 6 ++++-- .../swift/cxx_interop/ci_test_example.py | 15 ++------------- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/examples/languages/swift/cxx_interop/CMakeLists.txt b/examples/languages/swift/cxx_interop/CMakeLists.txt index 69a9400e..fcc97a1b 100644 --- a/examples/languages/swift/cxx_interop/CMakeLists.txt +++ b/examples/languages/swift/cxx_interop/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.28) +cmake_minimum_required(VERSION 3.23) project(swift_cpp_demo LANGUAGES CXX Swift) find_package(lunasvg REQUIRED) diff --git a/examples/languages/swift/cxx_interop/README.md b/examples/languages/swift/cxx_interop/README.md index 6113f5c5..b6656399 100644 --- a/examples/languages/swift/cxx_interop/README.md +++ b/examples/languages/swift/cxx_interop/README.md @@ -16,8 +16,10 @@ passes that to `swiftc` via `-Xcc -fmodule-map-file=...` together with ## Requirements - macOS with Xcode command line tools (`swiftc`), Swift 5.9+. -- CMake >= 3.28, with the Ninja generator: CMake's Swift support doesn't work - with the "Unix Makefiles" default some CMake versions pick on macOS. +- CMake >= 3.23, with the Ninja generator: CMake's Swift support doesn't work + with the "Unix Makefiles" default some CMake versions pick on macOS, and + `--preset` needs CMake >= 3.23 to read the `CMakePresets.json` schema + version `CMakeToolchain` generates. ## Build and run diff --git a/examples/languages/swift/cxx_interop/ci_test_example.py b/examples/languages/swift/cxx_interop/ci_test_example.py index 50c74398..d235f6b7 100644 --- a/examples/languages/swift/cxx_interop/ci_test_example.py +++ b/examples/languages/swift/cxx_interop/ci_test_example.py @@ -1,6 +1,4 @@ import platform -import re -import subprocess from test.examples_tools import run @@ -8,17 +6,8 @@ print("Swift <-> C++ interop: consuming a plain ConanCenter package from Swift") -def _cmake_supports_swift(minimum=(3, 28)): - try: - output = subprocess.run(["cmake", "--version"], capture_output=True, text=True, check=True).stdout - except FileNotFoundError: - return False - match = re.search(r"(\d+)\.(\d+)\.(\d+)", output) - return bool(match) and tuple(int(x) for x in match.groups()[:2]) >= minimum - - -if platform.system() != "Darwin" or not _cmake_supports_swift(): - print("WARNING: Skipping Swift interop example, requires macOS with swiftc and CMake >= 3.28") +if platform.system() != "Darwin": + print("WARNING: Skipping Swift interop example, requires macOS with swiftc") else: run("conan install . --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja") run("cmake --preset conan-release") From 69f5b563d5c46c8e7b1e228037f572a48f31805c Mon Sep 17 00:00:00 2001 From: Carlos Zoido Date: Wed, 12 Aug 2026 10:07:20 +0200 Subject: [PATCH 4/9] minor changes --- examples/languages/swift/cxx_interop/README.md | 5 +---- examples/languages/swift/cxx_interop/ci_test_example.py | 4 +--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/examples/languages/swift/cxx_interop/README.md b/examples/languages/swift/cxx_interop/README.md index b6656399..71c55562 100644 --- a/examples/languages/swift/cxx_interop/README.md +++ b/examples/languages/swift/cxx_interop/README.md @@ -16,10 +16,7 @@ passes that to `swiftc` via `-Xcc -fmodule-map-file=...` together with ## Requirements - macOS with Xcode command line tools (`swiftc`), Swift 5.9+. -- CMake >= 3.23, with the Ninja generator: CMake's Swift support doesn't work - with the "Unix Makefiles" default some CMake versions pick on macOS, and - `--preset` needs CMake >= 3.23 to read the `CMakePresets.json` schema - version `CMakeToolchain` generates. +- CMake >= 3.23, with the Ninja generator. ## Build and run diff --git a/examples/languages/swift/cxx_interop/ci_test_example.py b/examples/languages/swift/cxx_interop/ci_test_example.py index d235f6b7..e9fd02f2 100644 --- a/examples/languages/swift/cxx_interop/ci_test_example.py +++ b/examples/languages/swift/cxx_interop/ci_test_example.py @@ -2,8 +2,7 @@ from test.examples_tools import run -# ############# Example ################ -print("Swift <-> C++ interop: consuming a plain ConanCenter package from Swift") +print("Swift C++ interop: consuming a plain ConanCenter package from Swift") if platform.system() != "Darwin": @@ -12,5 +11,4 @@ run("conan install . --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja") run("cmake --preset conan-release") run("cmake --build --preset conan-release") - # No window/event loop involved, so the binary can run headlessly in CI. run("./build/Release/demo") From c0e58314f3500fb5d1afb2f611033cbf186b5882 Mon Sep 17 00:00:00 2001 From: Carlos Zoido Date: Thu, 13 Aug 2026 16:36:10 +0200 Subject: [PATCH 5/9] use xcode --- .gitignore | 2 + .../swift/cxx_interop/CMakeLists.txt | 16 -- .../languages/swift/cxx_interop/README.md | 28 ++- .../swift/cxx_interop/ci_test_example.py | 8 +- .../languages/swift/cxx_interop/conanfile.py | 17 +- .../demo.xcodeproj/project.pbxproj | 198 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + 7 files changed, 241 insertions(+), 35 deletions(-) delete mode 100644 examples/languages/swift/cxx_interop/CMakeLists.txt create mode 100644 examples/languages/swift/cxx_interop/demo.xcodeproj/project.pbxproj create mode 100644 examples/languages/swift/cxx_interop/demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/.gitignore b/.gitignore index e1b6d3fc..e84fda54 100644 --- a/.gitignore +++ b/.gitignore @@ -56,6 +56,7 @@ venv/ .pydevproject .settings/* .ropeproject/* +**/xcuserdata/ .tox CMakeUserPresets.json @@ -69,6 +70,7 @@ tutorial/versioning/revisions/intro/chat/* tutorial/versioning/revisions/intro/hello/* examples/libraries/tensorflow-lite/pose-estimation/pose-estimation examples/libraries/imgui/introduction/bindings +examples/languages/swift/cxx_interop/summer.png # Bazel files bazel-* diff --git a/examples/languages/swift/cxx_interop/CMakeLists.txt b/examples/languages/swift/cxx_interop/CMakeLists.txt deleted file mode 100644 index fcc97a1b..00000000 --- a/examples/languages/swift/cxx_interop/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -cmake_minimum_required(VERSION 3.23) -project(swift_cpp_demo LANGUAGES CXX Swift) - -find_package(lunasvg REQUIRED) - -add_executable(demo main.swift) - -target_link_libraries(demo PRIVATE - lunasvg::lunasvg -) - -target_compile_options(demo PRIVATE - "$<$:-cxx-interoperability-mode=default>" - "$<$:SHELL:-Xcc -std=c++${CMAKE_CXX_STANDARD}>" - "$<$:SHELL:-Xcc -fmodule-map-file=${LUNASVG_MODULEMAP}>" -) diff --git a/examples/languages/swift/cxx_interop/README.md b/examples/languages/swift/cxx_interop/README.md index 71c55562..6f5cd530 100644 --- a/examples/languages/swift/cxx_interop/README.md +++ b/examples/languages/swift/cxx_interop/README.md @@ -9,14 +9,17 @@ file -- no C wrapper library needed. Since lunasvg ships no Swift module map, `conanfile.py`'s `generate()` writes a small [Clang module map](https://clang.llvm.org/docs/Modules.html) pointing -at its real installed header (read from `cpp_info`), and `CMakeLists.txt` -passes that to `swiftc` via `-Xcc -fmodule-map-file=...` together with -`-cxx-interoperability-mode=default`. +at its real installed header (read from `cpp_info`), and sets `OTHER_SWIFT_FLAGS` +through `XcodeToolchain.extra_xcconfig` to pass that to `swiftc` via +`-Xcc -fmodule-map-file=...` together with `-cxx-interoperability-mode=default`. +`demo.xcodeproj` is a plain Xcode project whose Release configuration is based +on the `.xcconfig` files that Conan's `XcodeDeps`/`XcodeToolchain` generators +write. ## Requirements -- macOS with Xcode command line tools (`swiftc`), Swift 5.9+. -- CMake >= 3.23, with the Ninja generator. +- macOS with Xcode (`swiftc`, `xcodebuild`), Swift 5.9+. +- Conan 2.32 or newer (`XcodeToolchain.extra_xcconfig`). ## Build and run @@ -24,10 +27,17 @@ passes that to `swiftc` via `-Xcc -fmodule-map-file=...` together with git clone https://github.com/conan-io/examples2.git cd examples2/examples/languages/swift/cxx_interop -conan install . --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja -cmake --preset conan-release -cmake --build --preset conan-release -./build/Release/demo +conan install . --build=missing +open demo.xcodeproj +``` + +From there it is a normal Xcode project: press Run, and Swift calls into +lunasvg. The same build also works from the command line: + +```bash +xcodebuild -project demo.xcodeproj -scheme demo -configuration Release \ + -derivedDataPath build build +./build/Build/Products/Release/demo ``` The program renders the SVG and writes `summer.png` to the working directory. diff --git a/examples/languages/swift/cxx_interop/ci_test_example.py b/examples/languages/swift/cxx_interop/ci_test_example.py index e9fd02f2..7de8d3cf 100644 --- a/examples/languages/swift/cxx_interop/ci_test_example.py +++ b/examples/languages/swift/cxx_interop/ci_test_example.py @@ -8,7 +8,7 @@ if platform.system() != "Darwin": print("WARNING: Skipping Swift interop example, requires macOS with swiftc") else: - run("conan install . --build=missing -c tools.cmake.cmaketoolchain:generator=Ninja") - run("cmake --preset conan-release") - run("cmake --build --preset conan-release") - run("./build/Release/demo") + run("conan install . --build=missing") + run("xcodebuild -project demo.xcodeproj -scheme demo -configuration Release " + "-derivedDataPath build build") + run("./build/Build/Products/Release/demo") diff --git a/examples/languages/swift/cxx_interop/conanfile.py b/examples/languages/swift/cxx_interop/conanfile.py index e978781b..67db30b1 100644 --- a/examples/languages/swift/cxx_interop/conanfile.py +++ b/examples/languages/swift/cxx_interop/conanfile.py @@ -1,7 +1,8 @@ import os import textwrap from conan import ConanFile -from conan.tools.cmake import CMakeToolchain, CMakeDeps, cmake_layout +from conan.tools.apple import XcodeDeps, XcodeToolchain +from conan.tools.build import cppstd_flag from conan.tools.files import save @@ -9,15 +10,14 @@ class SwiftCppDemo(ConanFile): settings = "os", "arch", "compiler", "build_type" def layout(self): - cmake_layout(self) + self.folders.generators = "generators" def requirements(self): self.requires("lunasvg/3.5.0") def generate(self): - CMakeDeps(self).generate() + XcodeDeps(self).generate() - # lunasvg has no Swift module map; write a shim one from its cpp_info. include_dir = self.dependencies["lunasvg"].cpp_info.includedir header = f"{include_dir}/lunasvg/lunasvg.h" @@ -30,6 +30,11 @@ def generate(self): ''') save(self, modulemap_path, modulemap) - tc = CMakeToolchain(self) - tc.variables["LUNASVG_MODULEMAP"] = modulemap_path + cppstd = cppstd_flag(self) + + tc = XcodeToolchain(self) + tc.extra_xcconfig["OTHER_SWIFT_FLAGS"] = ( + f'$(inherited) -cxx-interoperability-mode=default ' + f'-Xcc {cppstd} -Xcc -fmodule-map-file="{modulemap_path}"' + ) tc.generate() diff --git a/examples/languages/swift/cxx_interop/demo.xcodeproj/project.pbxproj b/examples/languages/swift/cxx_interop/demo.xcodeproj/project.pbxproj new file mode 100644 index 00000000..a9884292 --- /dev/null +++ b/examples/languages/swift/cxx_interop/demo.xcodeproj/project.pbxproj @@ -0,0 +1,198 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + 134B726B92DC37149DD8FB1A /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08895F9843B6FA00C49130BF /* main.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0507141398EC23BB262BA813 /* demo */ = {isa = PBXFileReference; includeInIndex = 0; path = demo; sourceTree = BUILT_PRODUCTS_DIR; }; + 08895F9843B6FA00C49130BF /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + A080ABC67B6FC4B3732B7606 /* conan_config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = conan_config.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 253DD428CCB2178AB212D9C6 = { + isa = PBXGroup; + children = ( + 08895F9843B6FA00C49130BF /* main.swift */, + 5D676B908F57C1AF87D8AC72 /* generators */, + CBA6EB5BDDD3CD851F85C932 /* Products */, + ); + sourceTree = ""; + }; + 5D676B908F57C1AF87D8AC72 /* generators */ = { + isa = PBXGroup; + children = ( + A080ABC67B6FC4B3732B7606 /* conan_config.xcconfig */, + ); + path = generators; + sourceTree = ""; + }; + CBA6EB5BDDD3CD851F85C932 /* Products */ = { + isa = PBXGroup; + children = ( + 0507141398EC23BB262BA813 /* demo */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 25BF8E1F96134B86B979D8A6 /* demo */ = { + isa = PBXNativeTarget; + buildConfigurationList = EED75AB90447BE0300554485 /* Build configuration list for PBXNativeTarget "demo" */; + buildPhases = ( + 5227B068F7CA093BC3C8FF22 /* Sources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = demo; + packageProductDependencies = ( + ); + productName = demo; + productReference = 0507141398EC23BB262BA813 /* demo */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + EE8D0A5E600AE5890BCA0377 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1430; + TargetAttributes = { + }; + }; + buildConfigurationList = 069786E56D7D9BA850EF6E04 /* Build configuration list for PBXProject "demo" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + Base, + en, + ); + mainGroup = 253DD428CCB2178AB212D9C6; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = CBA6EB5BDDD3CD851F85C932 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 25BF8E1F96134B86B979D8A6 /* demo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 5227B068F7CA093BC3C8FF22 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 134B726B92DC37149DD8FB1A /* main.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 13750F1439DABFE631C7C9E4 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A080ABC67B6FC4B3732B7606 /* conan_config.xcconfig */; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = io.conan.examples.demo; + SDKROOT = macosx; + }; + name = Release; + }; + CE5C8F26EC586CE7B2176121 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 069786E56D7D9BA850EF6E04 /* Build configuration list for PBXProject "demo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CE5C8F26EC586CE7B2176121 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EED75AB90447BE0300554485 /* Build configuration list for PBXNativeTarget "demo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13750F1439DABFE631C7C9E4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = EE8D0A5E600AE5890BCA0377 /* Project object */; +} diff --git a/examples/languages/swift/cxx_interop/demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/examples/languages/swift/cxx_interop/demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/examples/languages/swift/cxx_interop/demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + From 075977c7b608715b47ca1f2324f64c19e9489924 Mon Sep 17 00:00:00 2001 From: Carlos Zoido Date: Thu, 13 Aug 2026 16:41:17 +0200 Subject: [PATCH 6/9] wip --- examples/languages/swift/cxx_interop/README.md | 2 +- examples/languages/swift/cxx_interop/ci_test_example.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/languages/swift/cxx_interop/README.md b/examples/languages/swift/cxx_interop/README.md index 6f5cd530..b2ecf275 100644 --- a/examples/languages/swift/cxx_interop/README.md +++ b/examples/languages/swift/cxx_interop/README.md @@ -27,7 +27,7 @@ write. git clone https://github.com/conan-io/examples2.git cd examples2/examples/languages/swift/cxx_interop -conan install . --build=missing +conan install . -s build_type=Release --build=missing open demo.xcodeproj ``` diff --git a/examples/languages/swift/cxx_interop/ci_test_example.py b/examples/languages/swift/cxx_interop/ci_test_example.py index 7de8d3cf..555b13d1 100644 --- a/examples/languages/swift/cxx_interop/ci_test_example.py +++ b/examples/languages/swift/cxx_interop/ci_test_example.py @@ -8,7 +8,7 @@ if platform.system() != "Darwin": print("WARNING: Skipping Swift interop example, requires macOS with swiftc") else: - run("conan install . --build=missing") + run("conan install . -s build_type=Release --build=missing") run("xcodebuild -project demo.xcodeproj -scheme demo -configuration Release " "-derivedDataPath build build") run("./build/Build/Products/Release/demo") From 460b593f66f855a372187102b1d5c79e7b56f6e5 Mon Sep 17 00:00:00 2001 From: Carlos Zoido Date: Fri, 14 Aug 2026 11:06:04 +0200 Subject: [PATCH 7/9] wip --- examples/languages/swift/cxx_interop/ci_test_example.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/languages/swift/cxx_interop/ci_test_example.py b/examples/languages/swift/cxx_interop/ci_test_example.py index 555b13d1..a2610824 100644 --- a/examples/languages/swift/cxx_interop/ci_test_example.py +++ b/examples/languages/swift/cxx_interop/ci_test_example.py @@ -1,12 +1,15 @@ import platform +from conan.tools.scm import Version + from test.examples_tools import run print("Swift C++ interop: consuming a plain ConanCenter package from Swift") +conan_version = run("conan --version").split()[-1] -if platform.system() != "Darwin": - print("WARNING: Skipping Swift interop example, requires macOS with swiftc") +if platform.system() != "Darwin" or Version(conan_version) < Version("2.32"): + print("WARNING: Skipping Swift interop example, requires macOS with swiftc and Conan >= 2.32") else: run("conan install . -s build_type=Release --build=missing") run("xcodebuild -project demo.xcodeproj -scheme demo -configuration Release " From 49237d881b1d5be1089c0cacac5ec4e986604b73 Mon Sep 17 00:00:00 2001 From: Carlos Zoido Date: Mon, 17 Aug 2026 10:29:45 +0200 Subject: [PATCH 8/9] update name --- examples/languages/swift/cxx_interop/README.md | 4 ++-- examples/languages/swift/cxx_interop/conanfile.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/languages/swift/cxx_interop/README.md b/examples/languages/swift/cxx_interop/README.md index b2ecf275..a80c1a57 100644 --- a/examples/languages/swift/cxx_interop/README.md +++ b/examples/languages/swift/cxx_interop/README.md @@ -10,7 +10,7 @@ file -- no C wrapper library needed. Since lunasvg ships no Swift module map, `conanfile.py`'s `generate()` writes a small [Clang module map](https://clang.llvm.org/docs/Modules.html) pointing at its real installed header (read from `cpp_info`), and sets `OTHER_SWIFT_FLAGS` -through `XcodeToolchain.extra_xcconfig` to pass that to `swiftc` via +through `XcodeToolchain.build_settings` to pass that to `swiftc` via `-Xcc -fmodule-map-file=...` together with `-cxx-interoperability-mode=default`. `demo.xcodeproj` is a plain Xcode project whose Release configuration is based on the `.xcconfig` files that Conan's `XcodeDeps`/`XcodeToolchain` generators @@ -19,7 +19,7 @@ write. ## Requirements - macOS with Xcode (`swiftc`, `xcodebuild`), Swift 5.9+. -- Conan 2.32 or newer (`XcodeToolchain.extra_xcconfig`). +- Conan 2.32 or newer (`XcodeToolchain.build_settings`). ## Build and run diff --git a/examples/languages/swift/cxx_interop/conanfile.py b/examples/languages/swift/cxx_interop/conanfile.py index 67db30b1..4b3ba70f 100644 --- a/examples/languages/swift/cxx_interop/conanfile.py +++ b/examples/languages/swift/cxx_interop/conanfile.py @@ -33,7 +33,7 @@ def generate(self): cppstd = cppstd_flag(self) tc = XcodeToolchain(self) - tc.extra_xcconfig["OTHER_SWIFT_FLAGS"] = ( + tc.build_settings["OTHER_SWIFT_FLAGS"] = ( f'$(inherited) -cxx-interoperability-mode=default ' f'-Xcc {cppstd} -Xcc -fmodule-map-file="{modulemap_path}"' ) From a2f37812300399cee054cb7a038e41578ef9cd2f Mon Sep 17 00:00:00 2001 From: Carlos Zoido Date: Mon, 17 Aug 2026 11:07:53 +0200 Subject: [PATCH 9/9] run with -dev version --- examples/languages/swift/cxx_interop/ci_test_example.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/languages/swift/cxx_interop/ci_test_example.py b/examples/languages/swift/cxx_interop/ci_test_example.py index a2610824..cdf3b02a 100644 --- a/examples/languages/swift/cxx_interop/ci_test_example.py +++ b/examples/languages/swift/cxx_interop/ci_test_example.py @@ -8,7 +8,7 @@ conan_version = run("conan --version").split()[-1] -if platform.system() != "Darwin" or Version(conan_version) < Version("2.32"): +if platform.system() != "Darwin" or Version(conan_version).main < Version("2.32").main: print("WARNING: Skipping Swift interop example, requires macOS with swiftc and Conan >= 2.32") else: run("conan install . -s build_type=Release --build=missing")