pusewicz
(Piotr Usewicz)
1
I'm having trouble trying to integrate Gosu in my Swift project. Adding SDL2 (with module.modulemap) was easy and works no problem. Bear in mind that I'm a complete noob to Swift.
I wanted to jump some hoops and add Gosu directly as it implements some of the functionality to create games easier compared to plain SDL2.
I have Gosu installed through Homebrew.
My Sources/CGosu/module.modulemap:
module CGosu [system] {
umbrella header "/opt/homebrew/include/Gosu/Gosu.hpp"
export *
}
My Package.swift:
// swift-tools-version: 5.10
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "SwiftGosu",
platforms: [
.macOS(.v14)
],
targets: [
.executableTarget(
name: "SwiftGosu",
dependencies: ["CGosu"],
path: "Sources"
),
.systemLibrary(
name: "CGosu",
providers: [.brew(["libgosu"])]
),
]
)
Output for swift run:
error: emit-module command failed with exit code 1 (use -v to see invocation)
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "/opt/homebrew/include/Gosu/Gosu.hpp"
^
/opt/homebrew/include/Gosu/Gosu.hpp:9:10: note: in file included from /opt/homebrew/include/Gosu/Gosu.hpp:9:
#include <Gosu/Audio.hpp>
^
/opt/homebrew/include/Gosu/Audio.hpp:3:10: note: in file included from /opt/homebrew/include/Gosu/Audio.hpp:3:
#include <Gosu/Fwd.hpp>
^
/opt/homebrew/include/Gosu/Fwd.hpp:3:1: error: unknown type name 'namespace'
namespace Gosu
^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "/opt/homebrew/include/Gosu/Gosu.hpp"
^
/opt/homebrew/include/Gosu/Gosu.hpp:9:10: note: in file included from /opt/homebrew/include/Gosu/Gosu.hpp:9:
#include <Gosu/Audio.hpp>
^
/opt/homebrew/include/Gosu/Audio.hpp:3:10: note: in file included from /opt/homebrew/include/Gosu/Audio.hpp:3:
#include <Gosu/Fwd.hpp>
^
/opt/homebrew/include/Gosu/Fwd.hpp:3:15: error: expected ';' after top level declarator
namespace Gosu
^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "/opt/homebrew/include/Gosu/Gosu.hpp"
^
/opt/homebrew/include/Gosu/Gosu.hpp:9:10: note: in file included from /opt/homebrew/include/Gosu/Gosu.hpp:9:
#include <Gosu/Audio.hpp>
^
/opt/homebrew/include/Gosu/Audio.hpp:4:10: note: in file included from /opt/homebrew/include/Gosu/Audio.hpp:4:
#include <Gosu/IO.hpp>
^
/opt/homebrew/include/Gosu/IO.hpp:4:10: error: 'algorithm' file not found
#include <algorithm>
^
/Users/piotr/Work/GitHub/SwiftGosu/Sources/main.swift:4:8: error: could not build Objective-C module 'CGosu'
import CGosu
^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "/opt/homebrew/include/Gosu/Gosu.hpp"
^
/opt/homebrew/include/Gosu/Gosu.hpp:9:10: note: in file included from /opt/homebrew/include/Gosu/Gosu.hpp:9:
#include <Gosu/Audio.hpp>
^
/opt/homebrew/include/Gosu/Audio.hpp:3:10: note: in file included from /opt/homebrew/include/Gosu/Audio.hpp:3:
#include <Gosu/Fwd.hpp>
^
/opt/homebrew/include/Gosu/Fwd.hpp:3:1: error: unknown type name 'namespace'
namespace Gosu
^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "/opt/homebrew/include/Gosu/Gosu.hpp"
^
/opt/homebrew/include/Gosu/Gosu.hpp:9:10: note: in file included from /opt/homebrew/include/Gosu/Gosu.hpp:9:
#include <Gosu/Audio.hpp>
^
/opt/homebrew/include/Gosu/Audio.hpp:3:10: note: in file included from /opt/homebrew/include/Gosu/Audio.hpp:3:
#include <Gosu/Fwd.hpp>
^
/opt/homebrew/include/Gosu/Fwd.hpp:3:15: error: expected ';' after top level declarator
namespace Gosu
^
<module-includes>:1:9: note: in file included from <module-includes>:1:
#import "/opt/homebrew/include/Gosu/Gosu.hpp"
^
/opt/homebrew/include/Gosu/Gosu.hpp:9:10: note: in file included from /opt/homebrew/include/Gosu/Gosu.hpp:9:
#include <Gosu/Audio.hpp>
^
/opt/homebrew/include/Gosu/Audio.hpp:4:10: note: in file included from /opt/homebrew/include/Gosu/Audio.hpp:4:
#include <Gosu/IO.hpp>
^
/opt/homebrew/include/Gosu/IO.hpp:4:10: error: 'algorithm' file not found
#include <algorithm>
^
/Users/piotr/Work/GitHub/SwiftGosu/Sources/main.swift:4:8: error: could not build Objective-C module 'CGosu'
import CGosu
^
error: fatalError
How should I go ahead and add it? Should I clone the Gosu repository directly to Sources/CGosu and use that instead? With the systemLibrary definition it seems I can't make it treat it as a C++ library.
Hey, it looks like you need to enable CXX Interoperability mode in the project. See here: Swift.org - Setting Up Mixed-Language Swift and C++ Projects
By the looks of your Packge.swift, you’re importing Gosu as a C module which is why it’s whining about it. Have a look at the guide and see if you can enable CXX interop for the project.
1 Like
jrose
(Jordan Rose)
3
…and per Modules — Clang 19.0.0git documentation, you can put requires cplusplus in your module definition to make sure this doesn't happen by accident.
1 Like
pusewicz
(Piotr Usewicz)
4
Ok, this is now better. I also had to figure out that the main executable target had to link to the library, too so that it could find the symbols.
2 Likes
pusewicz
(Piotr Usewicz)
5
Thank you for the help @xtremekforever and @jrose!
1 Like
Glad you could get it working!!
pusewicz
(Piotr Usewicz)
7
@xtremekforever BTW. Do you know if it's possible to directly use namespaced C++ classes? Or do I need a C wrapper for those?
I think it should be. In my case I was using namespaced classes from our proprietary library where all classes were under a “lib” namespace, and I did stuff like:
let myInstance = lib.MyClass()
I did have issues creating instances of classes that used fancy types like std::atomic and std::mutex- it seemed that having members using those type classes caused Swift to not even show the class, so they had to be wrapped in C functions to get instances instead.
Are you having issues seeing your namespaced classes?
1 Like
pusewicz
(Piotr Usewicz)
9
Cool, I think I finally got it to work! Next step, inheritance (or wrapping?).
I've got this C++ class thing. In order to use it, I need to inherit from it, and override the update method.
Here's an example in C++.
@xtremekforever Would you know how could this be achieved in Swift? Directly trying to inherit does not work.
/Users/piotr/Work/GitHub/SwiftGosu/Sources/main.swift:6:24: error: 'Window' is not a member type of enum '__ObjC.Gosu'
class GameWindow: Gosu.Window {
~~~~ ^
/opt/homebrew/include/Gosu/Window.hpp:23:11: note: record 'Window' is not automatically available: does not have a copy constructor or destructor; does this type have reference semantics?
class Window : private Noncopyable
^
SWIFT_SHARED_REFERENCE(<#retain#>, <#release#>)
Obviously, as you can tell, I'm new to C++/Swift, so I have no idea what I'm doing :P.
When it comes to this I'm not sure if it's really possible in Swift right now. You may just need to make a class in C++ that inherits from it and provides an update method, and that maybe calls a Swift class method instead.
1 Like