What are the steps needed to create a working Swift file with C++ interoperability and vis versa?

I am trying to figure out the steps necessary to create a Swift program that successfully calls a C++ function or class. I found the page at: https://github.com/apple/swift/blob/main/docs/CppInteroperability/GettingStartedWithC%2B%2BInterop.md is no longer accurate (as the heading link states). The page at: Swift.org - Mixing Swift and C++ discusses the topic with many insights, but nothing that gets me from creating a Swift project to a functional hello world program. Below are the steps that I have figured out so far. Some might suggest I have too much detail in the steps, but I find that when coding, even the slightest most minor oversight may be the one big thing that makes the difference between a working program and endless hours of frustration. Clearly the steps that I listed below are not correct because they don’t get me to a working program. Those who are more familiar with interoperability will likely immediately see where I need to make changes. At this time, this list of steps is all I have. The list has gone through several iterations to get to this point. I offer the list as a question of how should I proceed to get a working program, and as a suggestion that somewhere in a prominent place in the documentation, there needs to be a set of steps, in this form, that is always current, and takes a reader from zero to a working Swift program, and conversely from zero to a working C++ program.

Here are the steps that I have.

  1. Be sure you are using XCode 15, and Swift 5
  2. Plan ahead by to put all files into the Swift project folder so everything is in one place and easily found and referenced. This can be changed, later, to have the C++ files in another location.
  3. Create a Swift project
  4. Check again to make sure this is Swift 5 or greater.
  5. One way to check the version is to use the following code in a Swift program. The text editor, for this post may change the word “print” to “Print”. It happens.
    In my editing of this post, I found the editor wants to remove the pound sign from the statements in the following code example. When implementing those statements add a pound sign before, if, else if, and endif.

if swift(>=5.9) // see the comments in the text above.
print(“You are running Swift 5.9 or greater. You’re good to go ahead.”)
elseif swift(>=5.0)
print(“You are running Swift 5.0 or greater. You’re good to go ahead.”)
endif

  1. After creating the Swift project, all subsequent files are to be created in the project by beginning with the following steps: XCode -> new -> file -> (followed by selecting the appropriate icon for whichever file type is to be created as part of the project)
  2. Change the project settings for C++ interoperability by taking the following steps: Project -> Build Settings -> All -> C++ and Objective C Interoperability -> Set to C++/Objective C
  3. Create a C++ .cpp file but no .hpp file (no code added yet) (the name is CPPTest.CPP)
  4. Create a .h file having the same name as the C++ file, and having the extension .h (wonder if I could have created a .hpp and just changed the extension, or just leave it as hpp and reference it as such where needed). The file name is CPPTest.h.
  5. Create a module map file having same name as the CPP file, with extension .modulemap the modulemap file name is CPPTest.modulemap.
  6. Change the module map contents to read as follows:

module CPPTest{
header “CPPTest.h”
requires cplusplus // this is not mentioned in all documents.
export *
}

  1. Go back to main.swift and add the following:

  2. Import “CPPTest.h”

  3. Here I get the error message: “Expected identifier in import declaration”

  4. The error appears to be occurring on the quote character ‘ ” ’ ahead of the file name. So I tried various possibilities including leaving off the quote sign, inserting a complete path to the .h file, leaving off the .h, pointing to the module map, and others, with no success.

  5. My project includes one .h file, If there eventually is a project with several .h files and several .cpp files and only the .h files are listed in the modulemap and main.swift,, how does each referenced .h file know which .cpp file it is to be associated with? That may be revealed when I have a complete set of working how-to steps. Perhaps that is also at the heart of my current problem.

This works for me:

  • create a new Xcode project (e.g. a Swift command line tool)
  • go to project -> Build Settings and add $(PROJECT_DIR) and recursive to Header search paths
  • in project -> Build Settings set C++ and Objective-C Interoperability to C++/Objective-C++
  • create new cpp/hpp files (hpp is fine)
  • confirm to create a bridging header as well
  • in the bridging header, add import <YOUR_C++_FILE_NAME.hpp> (with angle brackets)
  • go to main.swift and instantiate a c++ wrapper object
4 Likes

Thank you!!!
That is even more simple than I expected.
I've been working with those steps and they have worked every time.

I'm trying to get up and running with some existing C++ code into a new iOS project and am super confused at many levels. Aren't we supposed to not need a bridging header now?