pusewicz
(Piotr Usewicz)
July 10, 2024, 10:48am
1
I'm trying to setup CMake with Swift and running into issues when compiling cute .
Here's the repo: GitHub - pusewicz/dungeon_loop_cute
And the command I use: cmake -Bbuild -G Ninja . && cmake --build build
.
Unfortunately I'm getting:
$ cmake --build build
[1/1] Linking Swift executable dungeonloop
FAILED: dungeonloop CMakeFiles/dungeonloop.dir/src/main.swift.o
: && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -j 16 -num-threads 16 -emit-executable -o dungeonloop -emit-dependencies -DCF_STATIC -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk -output-file-map CMakeFiles/dungeonloop.dir//output-file-map.json -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk -I /Users/piotr/Work/Github/dungeon_loop_cute/src -I /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-src/include -I /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-src/libraries -I /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-src/libraries/cimgui -I /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-src/libraries/cimgui/imgui -I /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/sdl2-build/include -I /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/sdl2-build/include-config- -F /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-build /Users/piotr/Work/Github/dungeon_loop_cute/src/main.swift -F /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-build -L /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-build -L /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-build -L /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/sdl2-build -L /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/sdl2-build -L /opt/homebrew/lib -L /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk/usr/lib/swift _deps/cute-build/cute.framework/Versions/1.0.0/cute -Xlinker -framework -Xlinker IOKit -Xlinker -framework -Xlinker Foundation -Xlinker -framework -Xlinker Security -Xlinker -framework -Xlinker QuartzCore -Xlinker -framework -Xlinker Metal -Xlinker -framework -Xlinker MetalKit -Xlinker -framework -Xlinker Network _deps/cute-build/libphysfs.a _deps/sdl2-build/libSDL2main.a _deps/sdl2-build/libSDL2.a -lm -liconv -Wl,-framework,CoreVideo -Wl,-framework,Cocoa -Wl,-framework,IOKit -Wl,-framework,ForceFeedback -Wl,-framework,Carbon -Wl,-framework,CoreAudio -Wl,-framework,AudioToolbox -Wl,-framework,AVFoundation -Wl,-framework,Foundation -Wl,-weak_framework,GameController -Wl,-weak_framework,Metal -Wl,-weak_framework,QuartzCore -Wl,-weak_framework,CoreHaptics -lc++ && :
error: unknown argument: '-Wl,-framework,CoreVideo'
ninja: build stopped: subcommand failed.
How would I go about resolving this issue?
etcwilde
(Evan Wilde)
July 10, 2024, 1:37pm
2
This is coming from SDL assuming that everyone is using a C/C++ compiler:
list(APPEND SOURCE_FILES ${RENDER_METAL_SOURCES})
set(SDL_VIDEO_RENDER_METAL 1)
set(HAVE_RENDER_METAL TRUE)
endif()
endif()
endif()
endif()
# Actually load the frameworks at the end so we don't duplicate include.
if(SDL_FRAMEWORK_COREVIDEO)
list(APPEND EXTRA_LDFLAGS "-Wl,-framework,CoreVideo")
endif()
if(SDL_FRAMEWORK_COCOA)
list(APPEND EXTRA_LDFLAGS "-Wl,-framework,Cocoa")
endif()
if(SDL_FRAMEWORK_IOKIT)
list(APPEND EXTRA_LDFLAGS "-Wl,-framework,IOKit")
endif()
if(SDL_FRAMEWORK_FF)
list(APPEND EXTRA_LDFLAGS "-Wl,-framework,ForceFeedback")
endif()
For Swift, the flag is -Xlinker
, not -Wl
, which is why Swift is complaining there. CoreVideo
just happens to be the first framework getting linked, so it fails.
SDL is getting built as a static library, which means that linking its dependencies is the job of the dynamically linked DSO (dylib or executable) that links SDL. Your executable depends on cute, which by default builds as a static archive, so your executable is the first DSO in the chain, so that's what gets all of the link flags. If you build cute as a dynamic library/framework, it will still fail though because cute marks the library link PUBLIC
, so everything that it depends on also gets forwarded to everything that links cute.
)
else()
set_target_properties(cute PROPERTIES
FRAMEWORK_VERSION "1.0.0"
MACOSX_FRAMEWORK_IDENTIFIER "com.cuteframework.shared"
)
endif()
endif()
# Link up all dependencies to Cute.
target_link_libraries(cute PUBLIC ${CF_LINK_LIBS})
# Cute unit tests executable (optional, defaulted to also build).
if (CF_FRAMEWORK_BUILD_TESTS)
set(CF_TEST_SRCS test/main.cpp
test/test_array.cpp
test/test_aseprite.cpp
test/test_audio.cpp
test/test_base64.cpp
test/test_coroutine.cpp
test/test_doubly_list.cpp
If you change that line to target_link_libraries(cute PRIVATE ${CF_LINK_LIBS})
and build cute as a dynamic library by setting CF_FRAMEWORK_STATIC
to FALSE
, your program should build.
pusewicz
(Piotr Usewicz)
July 10, 2024, 1:55pm
3
@etcwilde Thanks so much for your reply. I'm very new to Swift, CMake so might be asking silly questions here.
target_link_libraries(cute PRIVATE ${CF_LINK_LIBS})
This, I imagine, means that I cannot override it in my CMakeList.txt and has to be changed in the upstream (cute)? Or is there a way to patch it without commiting Cute to my local repo?
etcwilde
(Evan Wilde)
July 10, 2024, 2:03pm
4
You can apply patches in FetchContent_Declare
with the PATCH_COMMAND
.
It'll probably look something like
FetchContent_Declare(
cute
GIT_REPOSITORY https://github.com/RandyGaul/cute_framework
PATCH_COMMAND git apply "<wherever you're putting the patch>/000-cute.patch"
)
I also recommend pinning the checkout to a commit with GIT_TAG
so that you're not working against a moving target (Also helps with rebuild times since CMake doesn't need to check against the repo to see if anything has changed.) And it probably wouldn't hurt to open an issue/PR on cute to fix that as well.
1 Like
pusewicz
(Piotr Usewicz)
July 10, 2024, 5:16pm
5
@etcwilde Fantastic, it looks like it managed to build.
I've pushed the changes and added build.sh
script to run the build.
Now, the remaining task is to try to load that in my main.swift
.
FAILED: dungeonloop CMakeFiles/dungeonloop.dir/src/main.swift.o
: && /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -j 16 -num-threads 16 -emit-executable -o dungeonloop -emit-dependencies -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk -output-file-map CMakeFiles/dungeonloop.dir//output-file-map.json -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX14.5.sdk -I /Users/piotr/Work/Github/dungeon_loop_cute/src -I /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-src/include -I /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-src/libraries -I /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-src/libraries/cimgui -I /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-src/libraries/cimgui/imgui -F /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-build /Users/piotr/Work/Github/dungeon_loop_cute/src/main.swift -F /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-build -L /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-build -Xlinker -rpath -Xlinker /Users/piotr/Work/Github/dungeon_loop_cute/build/_deps/cute-build _deps/cute-build/cute.framework/Versions/1.0.0/cute && :
/Users/piotr/Work/Github/dungeon_loop_cute/src/module.modulemap:2:19: error: umbrella header 'cute.h' not found
umbrella header "cute.h"
^
/Users/piotr/Work/Github/dungeon_loop_cute/src/main.swift:1:8: error: could not build Objective-C module 'cute'
import cute
^
error: fatalError
ninja: build stopped: subcommand failed.
I've added a modulemap file, but I don't really know how to expose the built framework. Would love some help with that!
pusewicz
(Piotr Usewicz)
July 10, 2024, 9:49pm
6
I tried following Swift.org - Wrapping C/C++ Library in Swift , but to no avail. There should be a demo repo that does what this article tries to accomplish.