Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic support for generating C++ header from Swift code #14241

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

2xsaiko
Copy link
Contributor

@2xsaiko 2xsaiko commented Feb 11, 2025

(Requires/follow-up to #13317.)

Adds a new function to generate Swift to C++ bridging header in order to allow calling Swift code from C++.

Also adds a function to get the Swift library search paths, since linking a static Swift library into a C++ program does not automatically link against the Swift standard library. CMake doesn't seem to have this problem but I don't know why. Maybe they use swiftc to link the final binary in this case instead of the C++ linker? I don't like this at all, would love suggestions for how to make this better.

Caveat: using this requires manually setting CXX to the Swift-bundled clang++ (on non-macOS), since it requires special support in the compiler which the normal clang doesn't come with. What would need to happen for this not to be necessary is Meson would have to detect that when a Swift-generated header is used in a C++ target it should automatically use the Swift-bundled clang++. Not sure if this is possible/desirable.

To do:

  • Version checks (C++ bridging is available in 5.9 and above)
  • Test cases
  • Documentation

Ref:

cxx = meson.get_compiler('cpp')

swift = import('swift')

swiftcore_dep = [
    cxx.find_library('swiftCore', dirs: swift.get_library_path()),
    cxx.find_library('swiftSwiftOnoneSupport', dirs: swift.get_library_path()),
]

swiftlib = static_library('swiftlib', 'swiftlib.swift', swift_args: ['-parse-as-library'])
swiftlib_h = swift.generate_cpp_header(swiftlib)
cpp_exe = executable('cpp_exe', 'main.cpp', swiftlib_h, link_with: [swiftlib], dependencies: [swiftcore_dep])
// main.cpp

#include "swiftlib-Swift.h"

int main()
{
    swiftlib::callMe();
}
// swiftlib.swift

public func callMe() {
  print("Hello from Swift!")
}

@dcbaker
Copy link
Member

dcbaker commented Feb 11, 2025

If you add link_language : 'swift' to the mixed target does that make the linking magically work?

@2xsaiko
Copy link
Contributor Author

2xsaiko commented Feb 11, 2025

If you add link_language : 'swift' to the mixed target does that make the linking magically work?

Was hopeful, but unfortunately not. :(

cpp_exe = executable('cpp_exe', 'main.cpp', swiftlib_h, link_with: [swiftlib], link_language: 'swift')

ERROR: Swift target cpp_exe contains a non-swift source file.

Swift has a completely different code path for target generation because it compiles the whole module at once instead of per-file, that's probably the reason. It's probably worth fixing that instead, then we would also get per-file incremental compilation.

EDIT: It's definitely worth fixing since right now LSP is also broken except for the first file in each target

@dcbaker
Copy link
Member

dcbaker commented Feb 11, 2025

Swift has a completely different code path for target generation because it compiles the whole module at once instead of per-file, that's probably the reason. It's probably worth fixing that instead, then we would also get per-file incremental compilation.

I wonder if that's from being copied from Rust, which does have that model. I'd be curious if swift can just use the main file -> object; objects -> archive | dylib | exe path that C, C++, ObjC, ObjC++, and Fortran use.

@2xsaiko
Copy link
Contributor Author

2xsaiko commented Feb 11, 2025

It should be able to use that, yeah. That's what it seems to be doing internally already: https://theswiftdev.com/the-swift-compiler-for-beginners/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants