zienag
(Alfred Zien)
1
Hello swift users!
We have custom build system to build our swift project, and I tried to use new cxx interop feature.
I have simple c++ code
class Foo {
public:
Foo() = default;
std::string getStr() const;
};
And I'm calling it from swift like this:
public func getStr() -> String {
Foo().getStr()
}
Error I'm getting:
SwiftFile.swift:25:9: error: value of type 'Foo' has no member 'getStr'
Foo().getStr()
~~~~~ ^~~~~~
Header.h:25:3: note: function 'getStr' unavailable (cannot import)
std::string getStr() const;
^
Header.h:25:3: note: return type unavailable (cannot import)
std::string getStr() const;
^
Header.h:25:15: note: function uses foreign reference type 'basic_string' as a value in the return types which breaks 'swift_shared_reference' contract
std::string getStr() const;
^
I'm passing -cxx-interoperability-mode=default -Xcc -std=gnu++20 flags to swift compiler.
Setting up the same code in xcode works fine.
Can anyone tell me what I'm doing wrong or perhaps suggest a direction in which to look?
1 Like
zienag
(Alfred Zien)
2
After looking into it, I've found the problem.
It's about using export * in the module map files that Xcode creates. Our project uses stricter rules, meaning module maps don't share their dependencies automatically.
Instead of using export *, we found that making the module map only exporting the std module works just fine.
I'm not totally sure how it works, but it looks like when Swift imports a C++ module, it switches out the regular standard library module map for its own version. We couldn't find a better way to deal with this besides changing the module map of the module we're bringing in.