PrevUpHomeNext

swift pm cli uses cpp (cpp interop)


swift pm cli uses cpp (cpp interop) - Posted on Jun 4, 2024 - See https://www.swift.org/documentation/cxx-interop - Logs Home - d0018

swift pm cli uses cpp (cpp interop)

Swift package manager cli uses c++, (swift package manager).

Swift pm cli project

Init swift pm cli project

mkdir swiftcpp
cd swiftcpp
swift package init --type=executable

Take a look at the manifest file Package.swift,

The file can be modified, but the first line version can not be removed.

Change the coding style (but code is not changed):

(Package.swift)

// swift-tools-version: 5.10
import PackageDescription

let package = Package(
	name: "swiftcpp",
	targets: [
		.executableTarget(
			name: "swiftcpp"
		),
	]
)

Build and run the project for the first time.

swift build
swift run

Enable cpp support in the project

Modify Package.swift

Enable cpp interoperablity

.executableTarget(
	name: "swfitcpp",
	swiftSettings: [.interoperabilityMode(.Cxx)]	// Enable c++ interop
),

Set a cpp library as the dependency of the project

targets: [
	.target(
		name: "one_cpp_lib"	// The c++ library target name is one_cpp_lib
	),
	.executableTarget(
		name: "swfitcpp",
		dependencies: ["one_cpp_lib"],	// project swiftcpp depends one_cpp_lib
		swiftSettings: [.interoperabilityMode(.Cxx)]
	),
]

At last, the Package.swift will look like this:

The first line // swift-tools-version: 5.10 should not be removed.

// swift-tools-version: 5.10
import PackageDescription

let package = Package(
	name: "swiftcpp",
	targets: [
		.target(
			name: "one_cpp_lib"
		),
		.executableTarget(
			name: "swiftcpp",
			dependencies: ["one_cpp_lib"],
			swiftSettings: [.interoperabilityMode(.Cxx)]
		),
	]
)

Source code layout

Source folder tree

mkdir ./Sources/swiftcpp
mkdir ./Sources/one_cpp_lib
mkdir ./Sources/one_cpp_lib/include

In fact, ./Sources/main.swift can be moved to ./Sources/swiftcpp/,

or be removed and put your own swift code at ./Sources/swiftcpp/ .

rm ./Sources/main.swift

Now, the project folder tree is:

$ cd ..
$ tree ../swiftcpp

swiftcpp/
        |---- Package.swift
        |---- Sources/
                     |---- one_cpp_lib/
                     |                |---- include/
                     |
                     |---- swiftcpp/

Add cpp library source code: cpp header

File: ./Sources/one_cpp_lib/include/any_name_cpp_file.hpp

// Header projection macro must be added here,
// otherwise the swift package system might parse the same header twice
#ifndef __any_name_cpp_file_hpp__
#define __any_name_cpp_file_hpp__

#include <iostream>

class any_cpp_class_name
{
public:
	void print() const
	{
		std::cout << "Hello, I am c++!" << std::endl;
	}
};

#endif

Add swift main code

File: ./Sources/swiftcpp/start_point_any_name.swift

import one_cpp_lib

print("Hello I am swift!")
var cpp_object = any_cpp_class_name()
cpp_object.print()

Build project and run now!

$ swift build

Building for debugging...
[8/8] Linking swiftcpp
Build complete! (1.17s)

$ swift run

Building for debugging...
[1/1] Write swift-version-32A5E7755150B194.txt
Build complete! (0.44s)
Hello I am swift!
Hello, I am c++!

I want to add multiple cpp headers !

Upgrade File: ./Sources/one_cpp_lib/include/any_name_cpp_file.hpp

// Header projection macro must be added here,
// otherwise the swift package system might parse the same header twice
#ifndef __any_name_cpp_file_hpp__
#define __any_name_cpp_file_hpp__
#include "any_name_another.hpp"
#endif

New File: ./Sources/one_cpp_lib/include/any_name_another.hpp

#ifndef __any_name_another_hpp__
#define __any_name_another_hpp__

#include <iostream>

class any_name_class
{
public:
	void print() const
	{
		std::cout << "Hello, I am c++ !!!" << std::endl;
	}
	int get() const
	{
		return 987;
	}
};

#endif

Upgrade File: ./Sources/swiftcpp/start_point_any_name.swift

import one_cpp_lib

print("Hello, I am swift !!!")
var cpp_object = any_name_class()
cpp_object.print()
let result = cpp_object.get()
print("result:", result)

Build project and run again !

$ swift build

Building for debugging...
[8/8] Linking swiftcpp
Build complete! (1.28s)

$ swift run

Building for debugging...
[1/1] Write swift-version-32A5E7755150B194.txt
Build complete! (0.33s)
Hello, I am swift !!!
Hello, I am c++ !!!
result: 987

At last: Try to separate source files .cpp into ./swiftcpp/Sources/one_cpp_lib/

Try it youself !

I practiced it, simple source file tree structure is supported, but too complicated source tree will cause swift package manager reporting errors.

See Also

Logs Home

utx::print


PrevUpHomeNext

utx::print

esv::print