wip

improve project structure & build automation

autumn f437af19 2c63487b

+139 -65
+1 -1
.gitignore
··· 1 - .object 1 + .temp 2 2 program 3 3 manifesto
+4 -17
code/_vk/basics.c crone/_vk/basics.c
··· 1 1 2 - #include <stdlib.h> 3 - 4 - #include <vulkan/vulkan.h> 5 - 6 - #include <vk.h> 7 - #include <crone_util.h> 8 - #include <ptr_list.h> 2 + #include ".h" 9 3 10 4 #ifdef DO_VALIDATION 11 5 #include "debug.h" 12 6 #endif 13 - #include "macros.h" 14 - 15 - typedef struct vulkan_state { 16 - VkInstance instance; 17 - ptr_list physicalDevices; 18 - VkDebugUtilsMessengerEXT debugMessenger; 19 - VkAllocationCallbacks *pAllocator; 20 - } vulkan_state; 21 7 22 8 ptr_list getRequiredExtensions() { 23 9 ptr_list list = ptrs_allocate(4); ··· 27 13 #endif 28 14 29 15 ptrs_append(&list, "VK_KHR_surface"); 16 + 17 + #ifdef USE_X11 30 18 ptrs_append(&list, "VK_KHR_xlib_surface"); 19 + #endif 31 20 return list; 32 21 } 33 - 34 - const char* validationLayers[] = { "VK_LAYER_KHRONOS_validation" }; 35 22 36 23 void* vulkan_init() { 37 24 vulkan_state *vk = malloc(sizeof(vulkan_state));
+3 -5
code/_vk/debug.h crone/_vk/debug.h
··· 2 2 #include <string.h> 3 3 #include <stdio.h> 4 4 5 - const char* const requestedLayers[] = { 6 - "VK_LAYER_KHRONOS_validation" 7 - }; 5 + const char* validationLayers[] = { "VK_LAYER_KHRONOS_validation" }; 8 6 9 7 static bool validationLayersSupported() { 10 8 uint32_t layerCount; ··· 13 11 VkLayerProperties availableLayers[layerCount]; 14 12 vkEnumerateInstanceLayerProperties(&layerCount, availableLayers); 15 13 16 - size_t requestedLayerCount = sizeof(requestedLayers) / sizeof(const char*); 14 + size_t requestedLayerCount = sizeof(validationLayers) / sizeof(const char*); 17 15 18 16 for (int reqIndex = 0; reqIndex < requestedLayerCount; ++reqIndex) { 19 17 bool layerFound = false; 20 - const char* layerName = requestedLayers[reqIndex]; 18 + const char* layerName = validationLayers[reqIndex]; 21 19 22 20 for (int availIndex = 0; availIndex < layerCount; ++availIndex) { 23 21 VkLayerProperties layer = availableLayers[availIndex];
code/_vk/macros.h crone/_vk/macros.h
+16 -2
code/_x11/window.c crone/_x11/window.c
··· 5 5 #include <X11/Xlib.h> 6 6 #include <X11/Xutil.h> 7 7 8 + #include <core.h> 8 9 #include <window.h> 9 - #include <crone_util.h> 10 10 11 11 typedef struct XWindow { 12 12 Window window; 13 13 Display *display; 14 14 Atom wmDeleteMessage; 15 + XVisualInfo visualInfo; 15 16 bool shouldClose; 16 17 } XWindow; 17 18 ··· 56 57 ptr -> window = window; 57 58 ptr -> display = display; 58 59 ptr -> wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False); // TODO what is this 60 + ptr -> visualInfo = visualInfo; 59 61 ptr -> shouldClose = false; 60 - // events 62 + // TODO queue for events 61 63 62 64 XSetWMProtocols(display, window, &ptr->wmDeleteMessage, 1); // TODO ?? 63 65 ··· 86 88 free(window); 87 89 } 88 90 91 + inline void* window_display_ptr(void *window_void) { 92 + return ((XWindow *)window_void)->display; 93 + } 94 + 95 + inline void* window_window_ptr(void *window_void) { 96 + return &(((XWindow *)window_void)->window); 97 + } 98 + 99 + inline void* window_visual_id_ptr(void *window_void) { 100 + return &(((XWindow *)window_void)->visualInfo.visualid); 101 + } 102 +
+1 -2
code/crone.c program.c
··· 3 3 #include <stdlib.h> 4 4 #include <setjmp.h> 5 5 6 - #include <window.h> 7 - #include <vk.h> 6 + #include <crone.h> 8 7 9 8 int main() { 10 9 window_handle window = window_getWindow();
code/headers/crone_util.h crone/interface/core/dev.h
+2 -10
code/headers/ptr_list.h crone/core/ptr_list.h
··· 1 1 2 - #include "crone_util.h" 3 - 4 - typedef struct ptr_list { 5 - size_t count; 6 - size_t capacity; 7 - void* *data; 8 - } ptr_list; 9 - 10 - static inline ptr_list ptrs_allocate(size_t initial_capacity) { 2 + extern inline ptr_list ptrs_allocate(size_t initial_capacity) { 11 3 ptr_list list = { 12 4 .count = 0, 13 5 .capacity = initial_capacity, ··· 40 32 list->data[list->count - 1] = item; 41 33 } 42 34 43 - static inline void ptrs_cleanup(ptr_list list) { 35 + extern inline void ptrs_cleanup(ptr_list list) { 44 36 free(list.data); 45 37 } 46 38
code/headers/vk.h crone/interface/vk.h
-11
code/headers/window.h
··· 1 - 2 - typedef void* window_handle; 3 - 4 - window_handle window_getWindow(); 5 - 6 - void window_pollEvents(window_handle window); 7 - 8 - bool window_shouldClose(window_handle window); 9 - 10 - void window_cleanup(window_handle window); 11 -
+13
crone/_vk/.h
··· 1 + 2 + #include <stdio.h> 3 + #include <stdlib.h> 4 + #include <string.h> 5 + 6 + #include <vulkan/vulkan.h> 7 + 8 + #include <core.h> 9 + #include <vk.h> 10 + 11 + #include "macros.h" 12 + #include "structs.h" 13 +
crone/_vk/graphics.c

This is a binary file and will not be displayed.

+10
crone/_vk/structs.h
··· 1 + 2 + typedef struct vulkan_state { 3 + VkInstance instance; 4 + ptr_list physicalDevices; 5 + VkAllocationCallbacks *pAllocator; 6 + #ifdef DO_VALIDATION 7 + VkDebugUtilsMessengerEXT debugMessenger; 8 + #endif 9 + } vulkan_state; 10 +
+8
crone/core/core.c
··· 1 + 2 + #include <stdint.h> 3 + #include <stddef.h> 4 + 5 + #include <core.h> 6 + 7 + #include "ptr_list.h" 8 +
+4
crone/interface/core.h
··· 1 + 2 + #include "core/ptr_list.h" 3 + #include "core/dev.h" 4 +
+13
crone/interface/core/ptr_list.h
··· 1 + 2 + typedef struct ptr_list { 3 + size_t count; 4 + size_t capacity; 5 + void* *data; 6 + } ptr_list; 7 + 8 + ptr_list ptrs_allocate(size_t initial_capacity); 9 + 10 + void ptrs_append(ptr_list *list, void *item); 11 + 12 + void ptrs_cleanup(ptr_list list); 13 +
+5
crone/interface/crone.h
··· 1 + 2 + #include "core.h" 3 + #include "vk.h" 4 + #include "window.h" 5 +
+19
crone/interface/window.h
··· 1 + 2 + typedef void* window_handle; 3 + 4 + window_handle window_getWindow(); 5 + 6 + void window_pollEvents(window_handle window); 7 + 8 + bool window_shouldClose(window_handle window); 9 + 10 + void window_cleanup(window_handle window); 11 + 12 + #ifdef USE_X11 13 + void* window_display_ptr(window_handle window); 14 + 15 + void* window_window_ptr(window_handle window); 16 + 17 + void* window_visual_id_ptr(window_handle window); 18 + #endif 19 +
+40 -17
makefile
··· 2 2 _default: dirs 3 3 @echo "\"make test\" for debug builds, \"make release\" to build a release" 4 4 5 + OBJECT_DIR = .temp/object 6 + PROJECT_NAME = crone 7 + 5 8 .NOTINTERMEDIATE: # all 6 9 7 10 LINKS = -lX11 -lvulkan 8 - HEADERS = -I code/headers 11 + HEADERS = -I $(PROJECT_NAME)/interface 9 12 ERRORS = -Wfatal-errors -Wall -Werror=use-after-free -Wno-unused-variable 10 13 %_dev: VERSION_FLAGS = -Og -DDO_VALIDATION 11 14 %_release: VERSION_FLAGS = -O3 12 - COMMON_FLAGS = -std=c23 $(ERRORS) $(VERSION_FLAGS) $(HEADERS) 15 + FLAGS = -std=c23 $(ERRORS) $(VERSION_FLAGS) $(HEADERS) -DUSE_X11 13 16 14 - GCC = gcc $(COMMON_FLAGS) -o 17 + GCC = gcc $(FLAGS) -o 15 18 16 19 define MAKE_OBJECT 17 20 @echo "making $@" 18 21 @$(GCC) $@ $^ -c 19 22 endef 20 23 21 - .object/_x11_window%: code/_x11/window.c 22 - $(MAKE_OBJECT) 24 + .temp/make: $(shell find $(PROJECT_NAME) -type f -name '*.c') 25 + @find $(PROJECT_NAME) -type f -name '*.c' > .temp/cfiles 26 + @sed 's/$(PROJECT_NAME)\/\(.*\)\.c/\1/g;s/\//_/' .temp/cfiles > .temp/object_names 27 + @paste -d " " .temp/cfiles .temp/object_names > .temp/build_plan 28 + @sed 's/\(.*\) \(.*\)/$$(OBJECT_DIR)\/\2_%: \1\n\t$$(MAKE_OBJECT)/g' .temp/build_plan > $@ 29 + @echo -n ".temp/lib_%: " >> $@ 30 + @sed 's/.* \(.*\)/$$(OBJECT_DIR)\/\1_%/g' .temp/build_plan | tr "\n" " " >> $@ 31 + @echo -n -e "\n\t@echo \"linking \$$@\"" >> $@ 32 + @echo -n -e "\n\t@ld -r -o \$$@ $$^" >> $@ 23 33 24 - .object/_vk_basics%: code/_vk/basics.c 25 - $(MAKE_OBJECT) 34 + ifneq ("$(wildcard .temp)","") 35 + include .temp/make 36 + else 37 + .temp/lib_%: dirs 38 + make $@ 39 + endif 26 40 27 41 %_dev: SUFFIX = _dev 28 42 %_release: SUFFIX = _release 29 - program/crone_%: code/crone.c .object/_x11_window_% .object/_vk_basics_% 43 + %_dev: % 44 + %_release: % 45 + program/$(PROJECT_NAME)_%: program.c .temp/lib_% 30 46 @echo "making $@" 31 - @$(GCC) program/crone$(SUFFIX) $^ $(LINKS) 47 + @$(GCC) $@ $^ $(LINKS) 32 48 33 - .PHONY: _default dirs test clean release 49 + .PHONY: _default dirs test clean release self objects immaculate 34 50 35 51 dirs: 36 - @mkdir -p program .object 52 + @mkdir -p program $(OBJECT_DIR) 37 53 38 - test: dirs program/crone_dev 54 + test: objects program/$(PROJECT_NAME)_dev 39 55 @echo -e "\nlaunching..." 40 - @program/crone_dev 56 + @program/$(PROJECT_NAME)_dev 41 57 42 58 DATE := $(shell date '+%d.%m.%Y') 43 - release: dirs program/crone_release 44 - @cp program/crone_release program/crone_release_$(DATE) 45 - @echo -e "\nbuilt program/crone_release_$(DATE)" 59 + release: objects program/$(PROJECT_NAME)_release 60 + @cp program/$(PROJECT_NAME)_release program/$(PROJECT_NAME)_release_$(DATE) 61 + @echo -e "\nbuilt program/$(PROJECT_NAME)_release_$(DATE)" 46 62 47 63 clean: dirs 48 - @rm -f ./.object/* 64 + @rm -rf ./.temp/* 49 65 @rm -f ./program/* 66 + @mkdir -p program $(OBJECT_DIR) 67 + 68 + immaculate: 69 + @rm -rf .temp 70 + @rm -rf program 71 + 72 + objects: dirs .temp/make 50 73