Skip to main content
GameDev.net gamedev.net
🔒 Locked

First post and first C++ question

Started by snnooze Jun 1 at 6:25 AM 11 replies 750+ views
Original Post
snnooze
snnooze

Hello,

I'm new here so I will start by the begining.
My real name is Fabrice, I'm 45 and I live in France.

I have decided a few days ago to really invest more time in "hobbyist gamdev" because I always wanted but never really done. Of course I've done some little games but never really completed or shared them.

More recently, I have tested unity and godot engine and completed some mini games with that tools but I wanted something different so I returned to C++ and I've looked for a library.

I have played a little with SFML 3 and wanted to try SDL3.


That lead me to my first question 🙂

I try since about 4 or 5 nights to link SDL3 and SDL3_image to a project using a CMakeLists.txt file.

I succedded for SDL3 and that worked but as soon as I try to add SDL3_image that fail.

I'm not sure to be in the right place for ask that question but I hope someone can help me to solve / understand that problem.

The error I've got every time is SDL3_image can't find SDL3 (if needed I can send more informations)

There is the content of the file I have that works, I have tried so many things after that ... but never suceeded to add SDL3_image and don't even have tried other libs I planned to use.

# CMakeList.txt : fichier projet CMake de niveau supérieur, effectuez une configuration globale
# et incluez les sous-projets ici.
#
cmake_minimum_required (VERSION 3.16)

#! ! ! ! ! ! !
#set this to ON instead of OFF to ship the game!
#basically this will change the RESOURCES_PATH to be the local path
#! ! ! ! ! ! !
#delete the out folder after changing if visual studio doesn recognize the change
set(PRODUCTION_BUILD OFF CACHE BOOL "Make this a production build" FORCE)

if(MSVC)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Release>:Release>")
add_compile_options(/arch:AVX2) #make sure SIMD optimizations take place
else()

add_link_options(-static-libstdc++ -static-libgcc)
add_compile_options(-mavx2 -mfma) # make sure SIMD optimizations take place, but on linux and other platforms

endif()

# set the output directory for built objects.
# This makes sure that the dynamic library goes into the build directory automatically.

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIGURATION>")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIGURATION>")

# Activez Rechargement à chaud pour les compilateurs MSVC si cela est pris en charge.
if (POLICY CMP0141)
  cmake_policy(SET CMP0141 NEW)
  set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()

project ("Aijin")
set(CMAKE_CXX_STANDARD 17)
file(GLOB_RECURSE MY_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/Aijin/src/*.cpp")

add_executable(Aijin_Engine "${MY_SOURCES}")

#option(Aijin_SDL3 "Use vendored libraries" OFF)

set_property(TARGET Aijin_Engine PROPERTY CXX_STANDARD 17)

if(PRODUCTION_BUILD)
	# setup the ASSETS_PATH macro to be in the root folder of your exe
	target_compile_definitions(Aijin_Engine PUBLIC RESOURCES_PATH="./resources/") 

	# remove the option to debug asserts.
	target_compile_definitions(Aijin_Engine PUBLIC PRODUCTION_BUILD=1) 

else()
	# This is useful to get an ASSETS_PATH in your IDE during development
	target_compile_definitions(Aijin_Engine PUBLIC RESOURCES_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/")
	target_compile_definitions(Aijin_Engine PUBLIC PRODUCTION_BUILD=0) 

endif()


#Pour les fichiers headers
target_include_directories(Aijin_Engine PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/Aijin/headers/")
target_include_directories(Aijin_Engine PUBLIC SDL3)

#Liens vers SDL3
target_link_libraries(Aijin_Engine PRIVATE SDL3::SDL3)

#Linkage statique SDL3 : 
# Désactiver la bibliothèque partagée (dynamique)
set(SDL_SHARED OFF CACHE BOOL "" FORCE)
# Activer la bibliothèque statique
set(SDL_STATIC ON CACHE BOOL "" FORCE)

# Incluez les sous-projets.
#add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Aijin/libraries EXCLUDE_FROM_ALL)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/Aijin/libraries/SDL3 EXCLUDE_FROM_ALL)

#Affichage console ou pas en fonction du type de Build
if(MSVC) # If using the VS compiler...

	target_compile_definitions(Aijin_Engine PUBLIC _CRT_SECURE_NO_WARNINGS)

	if(PRODUCTION_BUILD)
		#YOU CAN REMOVE THE CONSOLE WITH THIS LINE!
		set_target_properties(Aijin_Engine PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup") #no console
	endif()

elseif(MINGW) # Windows / MinGW GCC/Clang
	if(PRODUCTION_BUILD)
		# Remove console on Windows under MinGW
		target_link_options(Aijin_Engine PRIVATE
			-mwindows
		)
	endif()

elseif(APPLE OR UNIX) # macOS / Linux
	if(PRODUCTION_BUILD)
		target_link_options(Aijin_Engine PRIVATE -s)
	endif()
endif()

I think that is the end of my first post, sorry it's a little long to read and if you need more info to help me just ask 🙂

Have a nice day.

RmbRT
RmbRT

Have you tried this?

cmake -DSDL3_DIR=/path/to/sdl3/build ..

This needs to be passed to the SDL3_image's CMake file. In case your error is SDL3_DIR-NOTFOUND. I have no clue how to make CMake pass values to other CMake files, though.

Walk with God.
JoeJ
JoeJ

snnooze wrote:

I try since about 4 or 5 nights to link SDL3 and SDL3_image to a project using a CMakeLists.txt file.

Impressive endurance. I would have given up after half an hour.

But on github i see sdl3_image comes with project files, e.g. for Visual Studio. So you could build it using that, not requiring CMake.

If that fails as well, my next step usually is to add all the source files of a library to my project, building it along with that and not requiring a dll at all. This works well for libraries which do not have lots of dependencies.

(I hate all this and will never learn any of it properly, and i do not expect my response to be very helpul : )


snnooze
snnooze

Hello,

RmbRT wrote:

Have you tried this?

cmake -DSDL3_DIR=/path/to/sdl3/build ..
Copy

This needs to be passed to the SDL3_image's CMake file. In case your error is SDL3_DIR-NOTFOUND. I have no clue how to make CMake pass values to other CMake files, though.


I've already tried to set a SDL3_DIR but I will retry just to be sure and let you know if that solve the problem.

Thanks for your help.

JoeJ wrote:

But on github i see sdl3_image comes with project files, e.g. for Visual Studio. So you could build it using that, not requiring CMake.

I have tried to use their CMake code but that have failed, I don't remember if I've tried with their visual studio solution. Tried so many things I think I lose my head 😀 .

Thanks for your answer,

Have a nice day 🙂

RmbRT
RmbRT

@snnooze you can also go the global install route and use cmake --install to compile SDL3, which should then allow SDL3_image to find it. It's a bit less clean but that should work if nothing else works. Or try downloading precompiled libraries or something, as a last measure.

Walk with God.
snnooze
snnooze

Hello,

RmbRT wrote:

@snnooze you can also go the global install route and use cmake --install to compile SDL3, which should then allow SDL3_image to find it. It's a bit less clean but that should work if nothing else works. Or try downloading precompiled libraries or something, as a last measure.

Thanks for your answer, I keep the visual studio and precompiled solution as a last measure.

I think after all that time on that file I'd like to see it work.

So I have tried to create a new hello world project and rewrited all the CMakeLists.txt and finally that worked.

One of the lines of the previous file seemed to create a bug and now the two libs are linked to the project.

But now I can't find a way to link statically the libraries.

I found that in the cmake doc but that not works :

set_property(TARGET foo PROPERTY
  MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

There is the actual state of the file if needed :

cmake_minimum_required(VERSION 3.16)
project(hello)

if(MSVC)
    set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
    set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Release>:Release>")
    add_compile_options(/arch:AVX2) #make sure SIMD optimizations take place
else()

    add_link_options(-static-libstdc++ -static-libgcc)

    add_compile_options(-mavx2 -mfma) # make sure SIMD optimizations take place, but on linux and other platforms

endif()

# set the output directory for built objects.
# This makes sure that the dynamic library goes into the build directory automatically.
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIGURATION>")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIGURATION>")

if (POLICY CMP0141)
    cmake_policy(SET CMP0141 NEW)
    set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()

set(CMAKE_CXX_STANDARD 17)

# This assumes the SDL source is available in vendored/SDL
add_subdirectory(vendored/SDL EXCLUDE_FROM_ALL)

# This assumes the SDL_image source is available in vendored/SDL_image
add_subdirectory(vendored/SDL_image EXCLUDE_FROM_ALL)

# Create your game executable target as usual
add_executable(hello WIN32 hello.c)

#set_property(TARGET hello PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

if(PRODUCTION_BUILD)
    # setup the ASSETS_PATH macro to be in the root folder of your exe
    target_compile_definitions(hello PUBLIC RESOURCES_PATH="./resources/")

    # remove the option to debug asserts.
    target_compile_definitions(helloPUBLIC PRODUCTION_BUILD=1)

else()
    # This is useful to get an ASSETS_PATH in your IDE during development
    target_compile_definitions(hello PUBLIC RESOURCES_PATH="${CMAKE_CURRENT_SOURCE_DIR}/resources/")
    target_compile_definitions(hello PUBLIC PRODUCTION_BUILD=0)

endif()

# Link to the actual SDL3 library.
target_link_libraries(hello PRIVATE SDL3_image::SDL3_image SDL3::SDL3)

#Affichage console ou pas en fonction du type de Build
if(MSVC) # If using the VS compiler...

    target_compile_definitions(hello PUBLIC _CRT_SECURE_NO_WARNINGS)

    if(PRODUCTION_BUILD)
        #YOU CAN REMOVE THE CONSOLE WITH THIS LINE!
        set_target_properties(hello PROPERTIES LINK_FLAGS "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup") #no console
    endif()

elseif(MINGW) # Windows / MinGW GCC/Clang
    if(PRODUCTION_BUILD)
        # Remove console on Windows under MinGW
        target_link_options(hello PRIVATE
                -mwindows
        )
    endif()

elseif(APPLE OR UNIX) # macOS / Linux
    if(PRODUCTION_BUILD)
        target_link_options(hello PRIVATE -s)
    endif()
endif()

Have a nice day 🙂

snnooze
snnooze

Hello

(sorry I don't find the edit button on my previous post)

I've just succeeded by finding that example on the SDL Github : https://github.com/Ravbug/sdl3-sample/blob/main/CMakeLists.txt

I still have to clean the file and "activate" the others libraries but that works now, the two libs are statically linked.

After about a week I can finally start to code a SDL Game 😀 .

Thanks again,

Have a nice day.

RmbRT
RmbRT

Good luck with your C++ gamedev journey. My first game ever was a tower defense back in 2012 or something, with SDL. Not sure whether that was SDL 1 or SDL 2. After that, I made a Minecraft clone with OpenGL 1.1. During that, I hit the limits of what OpenGL 1.1 can achieve, and started learning OpenGL 3.3, which was the most recent thing at the time, I think. I didn't really ever make a finished, polished game, though, and then got sidetracked for 12 years or so on a programming language project.

I'm always glad to see when someone writes games in a systems programming language and without a U-engine. These days I'm reinventing all the wheels I can as I slowly inch closer to a perfect future of well-designed, timeless software, laying a solid foundation. Currently, I'm working on a game & engine & tooling in C on top of WASM and my own flavour of WebGL, with the aim of also adding a native version of the runtime, and adding a native OpenGL backend as well.

Later on, I plan to port all this to my own language, when I'm finally done with my self-hosted compiler, and afterwards, I hope to one day write a modified OpenGL driver that directly supports my own GL variant, which should allow for higher performance, as the design is inherently more efficient. But for now, it just gets emulated on top of regular OpenGL.

Walk with God.
bvanevery
bvanevery

snnooze wrote:

The error I've got every time is SDL3_image can't find SDL3 (if needed I can send more informations)

Hello! Congrats on taking your plunge. Note that you are having a CMake problem, not a C++ problem. In the future you will get better responses if you realize that, title your posts accordingly, and seek out the standard resources for CMake. For instance their home site has a FAQ, and they also have a mailing list. Not saying you can't ask here, I'm saying your problem is likely very basic to the successful operation of CMake.

For instance, you probably haven't specified your SDL directory, and that can be done in the standard interactive way with the CMake build GUI. Passing command line strings is not usually the drill.

JoeJ wrote:

Impressive endurance. I would have given up after half an hour.

Not really how anyone should proceed or feel about CMake. Better to realize that CMake is its own thing with its own concerns and method of operation. A long time ago I was a CMake expert before it was as standard and common as it is now. We used to be saddled with GNU Autoconf and Automake, which are bleh. CMake may be bleh but those others were BLEH.

Using a Visual Studio file, if available, is a legit way to avoid learning how to use CMake and all its complications. But if a project is serious about cross-platform stuff, at some point they're not gonna provide standalone VS build files anymore. It's not the correct method of CMake operation. Projects often go through a transition where they start out with VS, add CMake to get cross-platform support, have 2 different build systems living side by side for awhile, eventually realize that results in all kinds of build irregularities and failures, finally learn enough CMake, and then finally give over to doing it the CMake generative way.

Unless CMake added a feature in the past decade that I haven't been paying attention to. I doubt it.

I've done enough CMake, to only want to touch it when I have to. Its main virtue is industrial thoroughness. Every single stupid cross-platform build permutation, they've dealt with it somehow. Of course it begs questions about why it happens to begin with. It's because the C++ build universe is pretty crazy. Rust in contrast seems to be much more sane, because they culturally engineered some build tools as standard.


gamedesign-l pre-moderated mailing list. Preventing flames since 2000! All opinions welcome.
RmbRT
RmbRT

bvanevery said:
Not really how anyone should proceed or feel about CMake. Better to realize that CMake is its own thing with its own concerns and method of operation. A long time ago I was a CMake expert before it was as standard and common as it is now. We used to be saddled with GNU Autoconf and Automake, which are bleh. CMake may be bleh but those others were BLEH.

I made my own build system. My current game builds like this:

$ rmbrt-build opengl wasm "src#RmbRT Sprite Editor" :rmbrt-image/read#rmbrt-image :rmbrt-font :rmbrt-ui
Project "RmbRT Sprite Editor" (src/)
	an OpenGL application as webassembly for the browser
[MOD ] common (wasm)
	[C   ] Compiled heap/temp_heap/temp.c
	[C   ] Compiled heap/heap.c
	[C   ] Compiled heap/large_heap.c
	[C   ] Compiled heap/obj_heap/alloc_sizes.c
	[C   ] Compiled heap/large_heap/regions.c
[MOD ] wasm (wasm)
	[C   ] Compiled fs.c
	[C   ] Compiled env.c
	[C   ] Compiled syscall.c
[MOD ] opengl (wasm)
	[C   ] Compiled matrix.c
	[C   ] Compiled rgl_impl/rgl.c
	[C   ] Compiled rgl_impl/rgl_texture.c
	[C   ] Compiled rgl_impl/rgl_vertex.c
	[C++ ] Compiled webgl.cpp
[PROJ] src/ (opengl wasm)
	[C   ] Compiled editor/toolbar-view.c
	[C   ] Compiled editor/edit-view.c
	[C   ] Compiled print.c
	[C   ] Compiled main.c
[DEP ] /home/rmbrt/Code/rmbrt-lib/rmbrt-image/read/ (opengl wasm)
	[C   ] Compiled decompress.c
[DEP ] /home/rmbrt/Code/rmbrt-lib/rmbrt-font/ (opengl wasm)
	[C   ] Compiled font.c
[DEP ] /home/rmbrt/Code/rmbrt-lib/rmbrt-ui/ (opengl wasm)
	[C   ] Compiled button.c
	[C   ] Compiled impl/gldesc.c
	[C   ] Compiled elem.c
	[C   ] Compiled view.c
	[C   ] Compiled mouse.c
[LINK] Linked RmbRT Sprite Editor
[PACK] Packaged web app
  at <file:///tmp/.rmbrt-runtime/wasm/proj//home/rmbrt/Games/tools/sprite-editor/src/RmbRT Sprite Editor.html>.

It takes all C and CPP files in src/, and compiles them, while also importing some common runtime files like the heap implementation, some WASM-target-specific code, and since it's a graphical application, the opengl subsystem. Names dependencies starting with : are paths relative to $RMBRT_LIBRARY, and path#Name imports a folder under that alias. Dependencies become available for inclusion via <rmbrt-image/…>, for example.

Finally, it produces a single monolithic HTML file with the WASM embedded as base64, as well as the opengl-specific bindings, and the page itself is just a fullscreen canvas. When I get around to making a native build backend, it will produce a native opengl app that boots straight into a window with GL context.

Walk with God.
bvanevery
bvanevery

RmbRT wrote:

I made my own build system. My current game builds like this:

Yeah I've done enough real world build systems to contemplate making my own as well. As well as apprising any new programming language in those terms. Did they manage to come up with a build system that's native to the new language? The problem with CMake is it's not C/C++. So C/C++ programmers usually don't want to get their hands dirty with the sordid build system details.

They throw it over the fence to a "CMake person" and treat that person as a second class citizen in their development team. They're not doing "the real" project that adds all the features and whatnot, they're doing "the build". The endgame is they kick the buildmaster off their team, when they complain about all the ways the other people are ruining the build and avoiding serious cross-platform attention to detail. Been there done that. Seen it happen to others too, like with the Urho3D engine where the last guy standing was strong at CMake, weak at anything actually 3D engine related.

Every programmer should be a buildmaster, in the same way that every US Marine is a rifleman. I think Rust may have culturally achieved this more or less, but I don't actually have Rust programming experience. I just monitor what they have and haven't accomplished in gamedom from time to time.

Jonathan Blow had the right idea with his Jai language, that compiling stuff on the fly was integral to development. But he never shipped in a way that the vast majority of us can use, and it's been a long time now, so who cares. Just sayin' he gets conceptual points for recognizing the build problem.


gamedesign-l pre-moderated mailing list. Preventing flames since 2000! All opinions welcome.
RmbRT
RmbRT

bvanevery said:
I just monitor what they have and haven't accomplished in gamedom from time to time.

I don't like rust, especially how it forces severe constraints on architecture, and also doesn't even let you compile code mid-refactor, so even minor changes have huge turnaround time until you can actually test them, and sometimes, a minor change forces a major codebase refactor just because Rust wants to prove that your code is “safe” according to some definition of safe. This article explains it well: Leaving Rust gamedev after 3 years.

bvanevery said:
Jonathan Blow had the right idea with his Jai language, that compiling stuff on the fly was integral to development. But he never shipped in a way that the vast majority of us can use, and it's been a long time now, so who cares. Just sayin' he gets conceptual points for recognizing the build problem.

I think he has the right intention, and for his use case it's fine, but I wouldn't want to have a meta program that interfaces with compiler internals. But that's what he needs for his language, so it's fine. For my own language, so far it's just about passing source files to the compiler. The compilation speed goal is 1M LOC/s, so you can just recompile from scratch every time without even needing libraries. Of course assuming the entire codebase is written in that language. Everything else still needs to be linked as library, but I aim to provide a sufficiently feature-rich runtime that lets you do whatever you want out of the box. Mainly, talking to disk, network, graphics, and sound and other periphery like that. The final goal is to lift the runtime library into the OS itself, and then have the entire userspace be written entirely in my language and relying only on the runtime as basically the hardware access layer. And then as long as you can provide a runtime port on a given target (such as in the browser, or on windows, etc.), you can run all my software. And executables would actually just be .tar source archives or something like that, containing all the source code of the application, and when you first launch an application, it would just compile it right there and store the executable in /tmp. Again, with 1M LOC/s as the compilation speed goal, you wouldn't even notice.

Walk with God.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.