Skip to content
Jan Niklas Hasse edited this page Nov 8, 2024 · 19 revisions

Quickstart as Video Quickstart as Video

  1. (Optional but recommended) Install VS Code and the C++ and CMake extension (CodeLLDB might be needed for debugging)
  2. Install dependencies:
  1. Create a project folder with three sub folders (src, data, subprojects) and also a game.cpp in src and a CMakeLists.txt in the top folder. Then open the project folder with VS Code
mygame/
├── src/
│   └── game.cpp
├── data/
├── subprojects/
└── CMakeLists.txt
  1. Clone JNGL into subprojects
cd subprojects
git clone https://github.com/jhasse/jngl.git
cd ..

Alternatively, if you are using git as your revision system, you can also use git submodule add https://github.com/jhasse/jngl.git which adds JNGL as a submodule (see https://git-scm.com/book/en/v2/Git-Tools-Submodules)

  1. Create a game.cpp file in src and add the Hello World code
  2. Add this project setup in your CMakeLists.txt
cmake_minimum_required(VERSION 3.6)

project(mygame LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 14)
if(NOT MSVC)
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color")
endif()

add_subdirectory(subprojects/jngl)


set(MYGAME_SANITIZE_ADDRESS_DEFAULT ON)
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows" OR ANDROID OR CMAKE_BUILD_TYPE MATCHES "Release")
	set(MYGAME_SANITIZE_ADDRESS_DEFAULT OFF)
endif()
option(MYGAME_SANITIZE_ADDRESS "Enable AddressSanitizer" ${MYGAME_SANITIZE_ADDRESS_DEFAULT})
if(MYGAME_SANITIZE_ADDRESS)
	set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
	set (CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address")
endif()

file(GLOB SOURCES CONFIGURE_DEPENDS
	src/*.cpp
)
if(ANDROID)
	# build native_app_glue as a static lib
	set(${CMAKE_C_FLAGS}, "${CMAKE_C_FLAGS}")
	add_library(native_app_glue STATIC
		${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)

	# now build app's shared lib
	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall")

	# Export ANativeActivity_onCreate(),
	# Refer to: https://github.com/android-ndk/ndk/issues/381.
	set(CMAKE_SHARED_LINKER_FLAGS
		"${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")

	add_library(mygame SHARED ${SOURCES})

	target_include_directories(mygame PRIVATE
		${ANDROID_NDK}/sources/android/native_app_glue
		../../../../../../src
		../../../../../include
	)

	# add lib dependencies
	target_link_libraries(mygame
		android
		native_app_glue
		EGL
		GLESv3
		OpenSLES
		log
		z
		jngl
	)


	add_library(bootstrap SHARED android/app/src/main/cpp/bootstrap.cpp)

	target_include_directories(bootstrap PRIVATE
		${ANDROID_NDK}/sources/android/native_app_glue)

	# add lib dependencies
	target_link_libraries(bootstrap
		android
		native_app_glue
		log)
else()
	if(WIN32)
		add_executable(mygame ${SOURCES})
	else()
		add_executable(mygame ${SOURCES})
	endif()
	if(APPLE)
		target_link_libraries(mygame PRIVATE "-framework AppKit")
	elseif(NOT WIN32)
		target_link_libraries(mygame PRIVATE
			stdc++fs
		)
	endif()
	target_link_libraries(mygame PRIVATE
		jngl
	)
endif()

file(GLOB GFX_FILES RELATIVE ${CMAKE_SOURCE_DIR}/data CONFIGURE_DEPENDS data/*.webp data/*.png
                                                                        data/*/*.webp)
file(GLOB SFX_FILES RELATIVE ${CMAKE_SOURCE_DIR}/data data/sfx/*.ogg)
# configure_file(src/engine/datafiles.hpp.in include/datafiles.hpp @ONLY)
target_include_directories(mygame PRIVATE ${CMAKE_BINARY_DIR}/include subprojects/cereal/include
                                           subprojects/spine-runtimes/spine-c/spine-c/include)

if(WIN32)
	target_compile_definitions(mygame PRIVATE _USE_MATH_DEFINES)
endif()

if(CMAKE_BUILD_TYPE STREQUAL "Release")
	set_target_properties(mygame PROPERTIES WIN32_EXECUTABLE 1)
endif()
  1. Now on Mac and Linux you can build and run your game with these three commands.
cmake -Bbuild -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_BUILD_TYPE=Debug
cmake --build build
./build/mygame

On Windows please use the Mingw64 Shell you have installed in step 2. VSCode uses Powershell on windows by default. To change that for your project create .vscode/settings.json with this content. Maybe you have to reload VSCode and allow to change the terminal.

{
"terminal.integrated.shellArgs.windows": [
    "--login"
  ],
  "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe",
  "terminal.integrated.env.windows": {
    "MSYSTEM": "MINGW64",
    "MSYS2_PATH_TYPE": "inherit",
    "CHERE_INVOKING": "1"
  },
}

Then run this three commands.

cmake -H. -Bbuild -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=0 -G"MSYS Makefiles"
cmake --build build
./build/mygame.exe
  1. To setup VS Code you have to create two config files in a .vscode folder. (Yes with the . in front of the folder name)
mygame/
├── .vscode/
│   ├── launch.json
│   └── tasks.json
├── src/
│   └── game.cpp
├── data/
├── subprojects/
└── CMakeLists.txt

.vscode/launch.json

{
	"version": "0.2.0",
	"configurations": [
		{
			"type": "lldb",
			"request": "launch",
			"name": "mygame (LLDB extension)",
			"program": "${workspaceRoot}/build/mygame",
			"args": [],
			"cwd": "${workspaceRoot}",
			"preLaunchTask": "build"
		},
		{
			"name": "mygame (C/C++ extension)",
			"type": "cppdbg",
			"request": "launch",
			"program": "${workspaceFolder}/build/mygame",
			"args": [],
			"stopAtEntry": false,
			"cwd": "${workspaceFolder}",
			"environment": [],
			"MIMode": "gdb",
			"windows": {
				"miDebuggerPath": "C:/msys64/mingw64/bin/gdb.exe"
			},
			"setupCommands": [
				{
					"description": "Enable pretty-printing for gdb",
					"text": "-enable-pretty-printing",
					"ignoreFailures": true
				}
			],
			"preLaunchTask": "build"
		},
		{
			"type": "gdb",
			"request": "launch",
			"name": "mygame (GDB extension)",
			"target": "./build/mygame",
			"cwd": "${workspaceRoot}",
			"valuesFormatting": "prettyPrinters",
			"preLaunchTask": "build"
		},
	]
}

.vscode/tasks.json

{
	"version": "2.0.0",
	"windows": {
		"command": "C:\\msys64\\usr\\bin\\bash.exe",
		"args": ["-lc", "([ -f build/Makefile ] || (mkdir build && cd build && cmake -G'MSYS Makefiles' -DCMAKE_BUILD_TYPE=Debug .. && cd ..)) && cd build && make -j8"]
	},
	"linux": {
		"args": ["-lc", "cd \"\"${workspaceRoot}\"\" && ([ -d build ] || (mkdir build && cd build && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_BUILD_TYPE=Debug ..)) && make -C build && $@"],
		"command": "/bin/bash"
	},
	"osx": {
		"args": ["-lc", "cd \"\"${workspaceRoot}\"\" && ([ -d build ] || (mkdir build && cd build && cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DCMAKE_BUILD_TYPE=Debug ..)) && make -C build && $@"],
		"command": "/bin/bash"
	},
	"options": {
		"env": {
			"LANG": "C.UTF-8",
			"PYTHONUNBUFFERD": "1",
			"MSYSTEM": "MINGW64",
			"CHERE_INVOKING": "1"
		}
	},
	"tasks": [
		{
			"label": "build",
			"problemMatcher": {
				"owner": "cpp",
				"fileLocation": [
					"autoDetect",
					"${workspaceRoot}/build"
				],
				"pattern": {
					"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error|fatal error):\\s+(.*)$",
					"file": 1,
					"line": 2,
					"column": 3,
					"severity": 4,
					"message": 5
				}
			},
			"group": {
				"kind": "build",
				"isDefault": true
			}
		},
		{
			"label": "rebuild_cache",
			"problemMatcher": [],
			"command": "/bin/bash",
			"args": ["-c", "git submodule update && ninja rebuild_cache -Cbuild"]
		}
	],
	"presentation": {
		"echo": true,
		"reveal": "always",
		"focus": false,
		"panel": "shared",
		"showReuseMessage": true,
		"clear": true
	}
}
  1. Now you can delete the old build folder and go to the debugging tab of VSCode and select mygame (C/C++ extension) and press F5
Clone this wiki locally