summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt138
-rw-r--r--docs/cmake-integration.md9
-rw-r--r--include/engine/logging.h6
-rw-r--r--src/logging.c1
-rw-r--r--src/rendering.c8
-rw-r--r--src/state.c9
-rw-r--r--src/ui_rendering.c6
-rw-r--r--tools/cmake/DawAddState.cmake44
8 files changed, 157 insertions, 64 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6067c5c..655e664 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,13 +1,57 @@
-cmake_minimum_required(VERSION 3.16)
+cmake_minimum_required(VERSION 3.24)
+project(daw VERSION 0.0.1 LANGUAGES C)
-if(NOT DEFINED PROJECT_NAME)
+# We really don't want any in-source builds
+set(CMAKE_DISABLE_IN_SOURCE_BUILD ON CACHE BOOL "Prevents cmake -S. -B.")
+set(CMAKE_DISABLE_SOURCE_CHANGES ON CACHE BOOL "Prevent writing files to CMAKE_SOURCE_DIR under configure")
+
+if(NOT CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(NOT_SUBPROJECT ON)
else()
set(NOT_SUBPROJECT OFF)
endif()
-option(ENGINE_DEBUG "Compile engine with debugging features" OFF)
-option(ENGINE_HOT_RELOADING "Compile with hot-reloading enabled (only works with debug mode)" ON)
+include(CMakeDependentOption)
+
+option(ASAN "Enable address sanitizer")
+option(UBSAN "Enable undefined behaviour sanitizer")
+
+cmake_dependent_option(DAW_BUILD_DEBUG
+ "Compile daw engine with debugging features" ON
+ "CMAKE_BUILD_TYPE STREQUAL Debug" OFF)
+
+# unused
+cmake_dependent_option(DAW_BUILD_HOTRELOAD
+ "Compile daw engine with hot reloading enabled" ON
+ "NOT CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME;CMAKE_BUILD_TYPE STREQUAL Debug;NOT WIN32" OFF)
+
+cmake_dependent_option(DAW_BUILD_ASAN
+ "Compile daw engine with address sanitizer (asan)" ON
+ "DAW_BUILD_DEBUG;ASAN" OFF)
+
+cmake_dependent_option(DAW_BUILD_UBSAN
+ "Compile daw engine with undefined behaviour sanitizer (ubsan)" ON
+ "DAW_BUILD_DEBUG;UBSAN" OFF)
+
+# unused
+cmake_dependent_option(DAW_BUILD_STANDALONE
+ # Would require us to enable dynamically registered states.
+ "Compile daw as a standalone library. This is not implemented yet." OFF
+ "TRUE" OFF)
+
+# unused
+cmake_dependent_option(DAW_BUILD_TOOLS
+ "Build tools to manipulate a daw project" ON
+ "CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME" OFF)
+
+if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
+ message("Enabling LTO")
+ set(${CMAKE_INTERPROCEDURAL_OPTIMIZATION} TRUE)
+endif()
+
+if(DAW_BUILD_UBSAN AND DAW_BUILD_ASAN)
+ message(FATAL_ERROR "You cannot build both asan and ubsan")
+endif()
set(ENGINE_SOURCES
src/btree.c
@@ -25,64 +69,54 @@ set(ENGINE_SOURCES
src/vector.c
)
-add_library(engine ${ENGINE_SOURCES})
+add_library(daw
+ ${ENGINE_SOURCES})
-target_include_directories(engine PUBLIC
- include
- ${CMAKE_BINARY_DIR}/include
- ${ENGINE_INCLUDE})
-target_link_libraries(engine SDL2 SDL2_image SDL2_ttf m)
-target_compile_features(engine PRIVATE c_std_99)
+target_include_directories(daw PUBLIC
+ include ${CMAKE_BINARY_DIR}/include ${ENGINE_INCLUDE})
-configure_file(${CMAKE_CURRENT_LIST_DIR}/state_type_list.h.in
- ${CMAKE_BINARY_DIR}/include/state_type_list.h)
+target_link_libraries(${PROJECT_NAME}
+ SDL2 SDL2_image SDL2_ttf
+ $<$<NOT:$<PLATFORM_ID:Windows>>:m>
+ $<$<AND:$<NOT:$<C_COMPILER_ID:MSVC>>,$<BOOL:${DAW_BUILD_UBSAN}>>:ubsan>
+)
-configure_file(${CMAKE_CURRENT_LIST_DIR}/include_states.h.in
- ${CMAKE_BINARY_DIR}/include/include_states.h)
+target_compile_features(${PROJECT_NAME} PRIVATE c_std_99)
+target_compile_options(${PROJECT_NAME} PUBLIC
+ $<$<NOT:$<C_COMPILER_ID:MSVC>>:-Wall -Wextra -pedantic>
+ $<$<C_COMPILER_ID:MSVC>:/W4>
+ # Debug related flags. sorry windows, you're just not that important.
+ $<$<AND:$<NOT:$<C_COMPILER_ID:MSVC>>,$<BOOL:${DAW_BUILD_DEBUG}>>:-Og -ggdb3 -fno-omit-frame-pointer>
+ $<$<AND:$<NOT:$<C_COMPILER_ID:MSVC>>,$<BOOL:${DAW_BUILD_ASAN}>>:-fsanitize=address -fsanitize=leak -fsanitize-address-use-after-scope>
+ $<$<AND:$<NOT:$<C_COMPILER_ID:MSVC>>,$<BOOL:${DAW_BUILD_UBSAN}>>:-fsanitize=undefined -fsanitize-undefined-trap-on-error -fno-sanitize-recover>
-# Add the directory to the list of states
-# The directorys contents will be compiled into a shared object file and linked
-# to the main executable
-macro(add_state STATEDIR)
- if(NOT_SUBPROJECT)
- else()
- set_property(TARGET engine
- APPEND PROPERTY INCLUDE_DIRECTORIES
- ${CMAKE_SOURCE_DIR}/state_${STATEDIR}/include)
+ $<$<AND:$<NOT:$<C_COMPILER_ID:MSVC>>,$<NOT:$<BOOL:${DAW_BUILD_DEBUG}>>>:-O2 -flto=auto -fuse-linker-plugin -ffat-lto-objects -funroll-loops -ffast-math -fno-signed-zeros -fno-trapping-math -ffunction-sections -fdata-sections>
+)
- file(APPEND ${CMAKE_BINARY_DIR}/include/state_type_list.h
- "State(${STATEDIR})\n")
+target_compile_definitions(${PROJECT_NAME} PUBLIC
+ $<$<BOOL:${DAW_BUILD_DEBUG}>:DAW_BUILD_DEBUG>
+)
- file(APPEND ${CMAKE_BINARY_DIR}/include/include_states.h
- "#include <states/${STATEDIR}.h>\n")
- file(GLOB STATE_SOURCES
- LIST_DIRECTORIES false
- state_${STATEDIR}/src/*.c
- )
+configure_file(${CMAKE_CURRENT_LIST_DIR}/state_type_list.h.in
+ ${CMAKE_BINARY_DIR}/include/state_type_list.h)
- # TODO: When state reloading is implemented properly, add MODULE library
- # option In general, this should only be available when debugging.
- if(BUILD_SHARED_LIBS)
- add_library(${STATEDIR} SHARED ${STATE_SOURCES})
- else()
- add_library(${STATEDIR} OBJECT ${STATE_SOURCES})
- endif()
+configure_file(${CMAKE_CURRENT_LIST_DIR}/include_states.h.in
+ ${CMAKE_BINARY_DIR}/include/include_states.h)
- target_include_directories(${STATEDIR} PUBLIC
- state_${STATEDIR}/include
- engine/include
- ${CMAKE_BINARY_DIR}/include
- include
- )
- set_property(TARGET engine
- APPEND PROPERTY LINK_LIBRARIES
- ${STATEDIR})
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/tools/cmake")
+if (NOT NOT_SUBPROJECT)
+ set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE)
+endif()
+include(DawAddState)
- endif()
- list(APPEND STATE_LIST ${STATEDIR})
- #list(APPEND ENGINE_INCLUDE state_${STATEDIR}/include)
-endmacro()
+message("Configured ${PROJECT_NAME} ${PROJECT_VERSION}")
+message("Build type: ${CMAKE_BUILD_TYPE}")
+message("enable debug: ${DAW_BUILD_DEBUG}")
+message("enable hotreload: ${DAW_BUILD_HOTRELOAD}")
+message("enable asan: ${DAW_BUILD_ASAN}")
+message("enable ubsan: ${DAW_BUILD_UBSAN}")
+message("build tools: ${DAW_BUILD_TOOLS}")
diff --git a/docs/cmake-integration.md b/docs/cmake-integration.md
new file mode 100644
index 0000000..1b688e0
--- /dev/null
+++ b/docs/cmake-integration.md
@@ -0,0 +1,9 @@
+# Cmake targets
+
+The preferred way to include daw in your CMake project is to use `FetchContent`:
+```CMake
+FetchContent_Declare(daw
+ GIT_REPOSITORY https://github.com/0undefined/daw.git
+ GIT_TAG latest
+)
+```
diff --git a/include/engine/logging.h b/include/engine/logging.h
index 1365a5b..0ac5025 100644
--- a/include/engine/logging.h
+++ b/include/engine/logging.h
@@ -34,8 +34,12 @@ void LOG(const char *fmt, ...);
void INFO_(const char *fmt, ...);
void INFO(const char *fmt, ...);
-#define _DEBUG(...) __DEBUG(__FILE__,__LINE__, __func__, __VA_ARGS__)
+#ifdef DAW_BUILD_DEBUG
+#define DEBUG(fmt, ...) __DEBUG(__FILE__,__LINE__, __func__, fmt, __VA_ARGS__)
void __DEBUG(const char* file, const i32 line, const char* func, const char *fmt, ...);
+#else
+#define DEBUG(...)
+#endif
void WARN(const char *fmt, ...);
diff --git a/src/logging.c b/src/logging.c
index 2ca5368..e8c2199 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -1,4 +1,5 @@
#include <stdlib.h>
+#include <engine/types.h>
#include <engine/logging.h>
char *itoa(i32 x) {
diff --git a/src/rendering.c b/src/rendering.c
index 755eda0..580be9e 100644
--- a/src/rendering.c
+++ b/src/rendering.c
@@ -22,7 +22,7 @@ i32 drawcall_len = 0;
/* Clear the screen,
* To be used inbetween draw calls */
void render_begin(Window *w) {
-#ifdef DEBUG
+#ifdef DAW_BUILD_DEBUG
SDL_SetRenderDrawColor(w->renderer, 0x10, 0x0a, 0x33, 0x00);
#else
SDL_SetRenderDrawColor(w->renderer, 0x00, 0x00, 0x00, 0x00);
@@ -42,7 +42,7 @@ void render_present(Window *w) {
break;
case RenderDrawCallType_Sprite:
{
-#ifdef DEBUG
+#ifdef DAW_BUILD_DEBUG
if (dc.data.sprite.sprite == NULL) {
__asm__("int3;");
WARN("Sprite %lx in drawcall %d/%d had NULL reference", dc.data.sprite.sprite, i, drawcall_len);
@@ -110,7 +110,7 @@ void engine_draw_uitree(UITree *t) {
void engine_draw_sprite(Sprite *s, v2_i32 *pos, f32 scale) {
if (drawcall_len + 1 >= drawcall_limit) return;
-#ifdef DEBUG
+#ifdef DAW_BUILD_DEBUG
if (s == NULL) __asm__("int3;");
#endif
drawcalls[drawcall_len++] = (RenderDrawCall){
@@ -127,7 +127,7 @@ void engine_draw_sprite(Sprite *s, v2_i32 *pos, f32 scale) {
void engine_draw_sprite_ex(Sprite *s, v2_i32 *pos, f32 scale, Engine_color colormod) {
if (drawcall_len + 1 >= drawcall_limit) return;
-#ifdef DEBUG
+#ifdef DAW_BUILD_DEBUG
if (s == NULL) __asm__("int3;");
#endif
drawcalls[drawcall_len++] = (RenderDrawCall){
diff --git a/src/state.c b/src/state.c
index 6b1f9c8..ee8b2fd 100644
--- a/src/state.c
+++ b/src/state.c
@@ -1,4 +1,5 @@
#include <engine/state.h>
+#include <engine/logging.h>
#include <include_states.h>
@@ -23,7 +24,7 @@ void State_init(StateType type, memory *mem) {
#undef State
case STATE_null:
case STATE_quit:
- _DEBUG("Got %s state.\n", StateTypeStr[type]);
+ DEBUG("Got %s state.\n", StateTypeStr[type]);
break;
default:
exit(EXIT_FAILURE);
@@ -42,7 +43,7 @@ void State_free(StateType type, memory *mem) {
#undef State
case STATE_null:
case STATE_quit:
- _DEBUG("Got %s state.\n", StateTypeStr[type]);
+ DEBUG("Got %s state.\n", StateTypeStr[type]);
break;
default:
exit(EXIT_FAILURE);
@@ -62,7 +63,7 @@ StateType (*State_updateFunc(StateType type))(void*) {
#undef State
case STATE_null:
case STATE_quit:
- return NULL; //_DEBUG("Got %s state.\n", StateTypeStr[type]);
+ return NULL; //DEBUG("Got %s state.\n", StateTypeStr[type]);
break;
default:
exit(EXIT_FAILURE);
@@ -82,7 +83,7 @@ StateType State_update(StateType type, memory *mem) {
#undef State
case STATE_null:
case STATE_quit:
- _DEBUG("Got %s state.\n", StateTypeStr[type]);
+ DEBUG("Got %s state.\n", StateTypeStr[type]);
break;
default:
exit(EXIT_FAILURE);
diff --git a/src/ui_rendering.c b/src/ui_rendering.c
index 7024e0b..a831a66 100644
--- a/src/ui_rendering.c
+++ b/src/ui_rendering.c
@@ -64,7 +64,7 @@ void render_container(Window *w, UITree_container *t) {
SDL_RenderDrawRect(w->renderer, &r);
-#ifdef DEBUG
+#ifdef DAW_BUILD_DEBUG
r.x += t->padding;
r.y += t->padding;
r.w -= t->padding * 2;
@@ -162,7 +162,7 @@ void render_title(Window *w, UITree_title *t) {
NULL,
&r);
-#ifdef DEBUG
+#ifdef DAW_BUILD_DEBUG
SDL_SetRenderDrawColor(w->renderer,
0xFF,
0xFF,
@@ -196,7 +196,7 @@ void render_text(Window *w, UITree_text *t) {
NULL,
&r);
-#ifdef DEBUG
+#ifdef DAW_BUILD_DEBUG
SDL_SetRenderDrawColor(w->renderer,
0xFF,
0xFF,
diff --git a/tools/cmake/DawAddState.cmake b/tools/cmake/DawAddState.cmake
new file mode 100644
index 0000000..a20aac7
--- /dev/null
+++ b/tools/cmake/DawAddState.cmake
@@ -0,0 +1,44 @@
+# Add the directory to the list of states.
+# The directories contents will be compiled into a shared object file and linked
+# to the main daw library
+macro(daw_add_state STATEDIR)
+ set_property(TARGET daw
+ APPEND PROPERTY INCLUDE_DIRECTORIES
+ ${CMAKE_SOURCE_DIR}/state_${STATEDIR}/include)
+
+ file(APPEND ${CMAKE_BINARY_DIR}/include/state_type_list.h
+ "State(${STATEDIR})\n")
+
+ file(APPEND ${CMAKE_BINARY_DIR}/include/include_states.h
+ "#include <states/${STATEDIR}.h>\n")
+
+ file(GLOB STATE_SOURCES
+ LIST_DIRECTORIES false
+ state_${STATEDIR}/src/*.c
+ )
+
+ # TODO: When state reloading is implemented properly, add MODULE library
+ # option In general, this should only be available when debugging.
+ if(BUILD_SHARED_LIBS)
+ if(DAW_BUILD_DEBUG AND DAW_BUILD_HOTRELOAD)
+ add_library(${STATEDIR} MODULE ${STATE_SOURCES})
+ else()
+ add_library(${STATEDIR} SHARED ${STATE_SOURCES})
+ endif()
+ else()
+ add_library(${STATEDIR} OBJECT ${STATE_SOURCES})
+ endif()
+
+ target_include_directories(${STATEDIR} PUBLIC
+ state_${STATEDIR}/include
+ ${daw_SOURCE_DIR}/include
+ ${CMAKE_BINARY_DIR}/include
+ include
+ )
+
+ set_property(TARGET daw
+ APPEND PROPERTY LINK_LIBRARIES
+ ${STATEDIR})
+
+ list(APPEND STATE_LIST ${STATEDIR})
+endmacro()