From 9578dfc2859abc101f78c02c271aae44b351abca Mon Sep 17 00:00:00 2001 From: hgn Date: Thu, 21 Dec 2023 16:22:47 +0000 Subject: [PATCH] better build program --- vg.h | 2 +- vg_build.h | 500 +++++++++++++++++++++------------------- vg_build_utils_shader.h | 2 +- vg_log.h | 2 +- vg_mem.h | 8 - 5 files changed, 264 insertions(+), 250 deletions(-) diff --git a/vg.h b/vg.h index e62eb24..aa86ab5 100644 --- a/vg.h +++ b/vg.h @@ -904,7 +904,7 @@ static void vg_fatal_error( const char *fmt, ... ) va_start( args, fmt ); _vg_logx_va( stderr, NULL, "fatal", KRED, fmt, args ); va_end( args ); - exit(0); + exit(1); } #endif /* VG_GAME */ diff --git a/vg_build.h b/vg_build.h index f1b1435..965f14c 100644 --- a/vg_build.h +++ b/vg_build.h @@ -1,303 +1,325 @@ +/* zig cc scripting tools */ + #include #include #include +#include #include "vg_log.h" -struct compiler_info -{ - char name[64], - file[512], - link[512], - library[512], - include[512], - build_dir[512], - executable[512]; - - enum optimization_profile - { - k_optimization_profile_debug, - k_optimization_profile_release +/* we dont free dynamic vg_strs in this program. so, we dont care.. */ +const char *__asan_default_options() { return "detect_leaks=0"; } + +struct { + vg_str include, + library, + link, + sources, + dest, + project_name; + + u32 optimization, + warnings; + bool fresh, + debug_asan; + + enum platform { + k_platform_anyplatform, + k_platform_windows, + k_platform_linux } - optimization_profile; + platform; - enum target_file - { - k_target_file_game, - k_target_file_server + enum architecture { + k_architecture_anyarch, + k_architecture_i386, + k_architecture_x86_64, } - target_file; - - enum compiler - { + arch; + + enum compiler { + k_compiler_blob, k_compiler_clang, - k_compiler_gcc, - k_compiler_mingw, - k_compiler_zigcc, - k_compiler_none + k_compiler_zigcc } compiler; - int clean; + enum libc_version { + k_libc_version_native, + k_libc_version_2_23, + } + libc; +} +static vg_build = { .debug_asan = 1 }; + +/* + * string tables + * -------------------------------------------------------------------------- */ + +static const char *platform_names[] = { + [k_platform_anyplatform] = "anyplatform", + [k_platform_windows] = "windows", + [k_platform_linux] = "linux" +}; + +static const char *architecture_names[] = { + [k_architecture_anyarch] = "anyarch", + [k_architecture_i386] = "i386", + [k_architecture_x86_64] = "x86_64" +}; + +static const char *compiler_names[] = { + [k_compiler_blob] = "blob", + [k_compiler_clang] = "clang", + [k_compiler_zigcc] = "zig-cc" +}; + +static const char *compiler_paths[] = { + [k_compiler_blob] = NULL, + [k_compiler_clang] = "clang", + [k_compiler_zigcc] = "zig cc" +}; + +static const char *libc_names[] = { + [k_libc_version_native] = "", + [k_libc_version_2_23] = ".2.23" +}; + +/* + * source specification + * -------------------------------------------------------------------------- */ + +void vg_add_source( const char *source ){ + vg_strcat( &vg_build.sources, source ); + vg_strcat( &vg_build.sources, " " ); +} + +void vg_include_dir( const char *dir ){ + vg_strcat( &vg_build.include, dir ); + vg_strcat( &vg_build.include, " " ); } -static vg_compiler; +void vg_library_dir( const char *dir ){ + vg_strcat( &vg_build.library, dir ); + vg_strcat( &vg_build.library, " " ); +} -void vg_build_syscall(const char *fmt, ...) -{ +void vg_link( const char *lib ){ + vg_strcat( &vg_build.link, lib ); +} + +/* + * OS & file tools + * -------------------------------------------------------------------------- */ + +void vg_syscall( const char *fmt, ... ){ va_list args; va_start( args, fmt ); char call[4096]; - vsnprintf( call, vg_list_size( call ), fmt, args ); + vsnprintf( call, sizeof(call), fmt, args ); va_end( args ); - - puts( call ); - + vg_low( "%s\n", call ); if( system(call) ) - exit(0); + exit(1); } -void vg_build_object( const char *file ) -{ - strcat( vg_compiler.file, file ); +void vg_add_blob( const char *blob, const char *dest ){ + vg_syscall( "cp %s bin/%s/%s", blob, vg_build.project_name.buffer, dest ); } -void vg_build_library_dir( const char *ldir ) -{ - strcat( vg_compiler.library, ldir ); +void vg_symlink( const char *folder, const char *bin_name ){ + char dest[512]; + snprintf( dest, 512, "bin/%s/%s", vg_build.project_name.buffer, bin_name ); + if( !access( dest, F_OK ) ) + vg_syscall( "unlink %s", dest ); + vg_syscall( "ln -srf %s %s", folder, dest ); } -void vg_build_link( const char *link ) -{ - strcat( vg_compiler.link, link ); +void vg_tarball_last_project(void){ + vg_syscall( "tar -chzvf dist/%s-%u.tar.gz bin/%s/", + vg_build.project_name.buffer, time(NULL), + vg_build.project_name.buffer ); } -void vg_build_include( const char *inc ) -{ - strcat( vg_compiler.include, inc ); -} -const char *vg_compiler_str(void) -{ - return (const char *[]) - { "clang", "gcc", "i686-w64-mingw32-gcc", "zig", "none" } - [vg_compiler.compiler]; -} +/* + * Standard VG includes & libraries which we use for games/graphics + * -------------------------------------------------------------------------- */ -void vg_build_start( const char *name, enum compiler compiler ) -{ - vg_compiler.file[0] = '\0'; - vg_compiler.link[0] = '\0'; - vg_compiler.include[0] = '\0'; - vg_compiler.library[0] = '\0'; - vg_compiler.compiler = compiler; - strcpy( vg_compiler.name, name ); - - snprintf( vg_compiler.build_dir, 512, - "bin/%s-%s", - name, - vg_compiler_str() ); - - if( vg_compiler.clean ){ - vg_build_syscall( "rm -rf %s", vg_compiler.build_dir ); - } +void vg_add_graphics(void){ + vg_add_source( "vg/dep/glad/glad.c" ); - vg_build_syscall( "mkdir -p %s", vg_compiler.build_dir ); - vg_build_include( "-I. -I./vg " ); - vg_build_library_dir( "-L. " ); + if( vg_build.platform == k_platform_windows ) + vg_add_blob( "vg/dep/sdl/SDL2.dll", "" ); - if( vg_compiler.compiler == k_compiler_zigcc ) - vg_build_library_dir( "-L/usr/lib " ); -} + vg_link( "-lm " ); -void vg_build_add_link_for_graphics(void) -{ - if( (vg_compiler.compiler == k_compiler_gcc) || - (vg_compiler.compiler == k_compiler_clang ) || - (vg_compiler.compiler == k_compiler_zigcc) ) - { - vg_build_link( "-lSDL2 -lGL -lX11 -lXxf86vm -lXrandr -lXi -ldl " ); - } + if( vg_build.platform == k_platform_linux ) + vg_link( "-lSDL2 -lGL -lX11 -lXxf86vm -lXrandr -lXi -ldl -pthread " ); else - { - vg_build_link( "-lmingw32 -lSDL2main -lSDL2 -lopengl32 -mwindows \\\n" ); - vg_build_link( " -Wl,--dynamicbase -Wl,--nxcompat \\\n" ); - - /* + 26.05.23: Suddenly something is pulling in winpthread. - * cant work out whats doing it or why. */ - vg_build_link( " -Wl,-Bstatic,--whole-archive \\\n" ); - vg_build_link( " -lwinpthread \\\n" ); - vg_build_link( " -Wl,--no-whole-archive " ); - } - - vg_build_object( "vg/dep/glad/glad.c " ); - - vg_build_link( "-lm " ); - if( vg_compiler.compiler == k_compiler_mingw ){ - //vg_build_link( "-mthreads " ); - //vg_build_link( "-static-libgcc " ); - } - else{ - vg_build_link( "-pthread " ); - } + vg_link( "-lmingw32 -lSDL2main -lSDL2 -lopengl32 \\\n" ); } -void vg_build_add_link_for_game(void) -{ - if( (vg_compiler.compiler == k_compiler_gcc) || - (vg_compiler.compiler == k_compiler_clang ) || - (vg_compiler.compiler == k_compiler_zigcc) ) - { - vg_build_link( "-lsteam_api " ); +void vg_add_game_stuff(void){ + vg_add_blob( "vg/submodules/SDL_GameControllerDB/gamecontrollerdb.txt", "" ); + + if( vg_build.platform == k_platform_linux ){ + vg_add_blob( "vg/dep/steam/libsteam_api.so", "" ); + vg_link( "-lsteam_api " ); } - else - { - vg_build_library_dir( "-L./vg/dep/sdl " ); - vg_build_link( "vg/dep/steam/steam_api.dll " ); + else if( vg_build.platform == k_platform_windows ){ + vg_add_blob( "vg/dep/steam/steam_api64.dll", "" ); + vg_link( "vg/dep/steam/steam_api64.dll " ); + vg_link( "vg/dep/sdl/SDL2.dll " ); + vg_library_dir( "-L./vg/dep/sdl " ); } - vg_build_include( "-I./vg/dep " ); - vg_build_library_dir( "-L./vg/dep/steam " ); -} - -void vg_build_bin_dependency_file( const char *src ) -{ - vg_build_syscall( "cp %s %s", src, vg_compiler.build_dir ); -} - -void vg_build_symbolic_link( const char *folder, const char *bin_name ) -{ - char dest[512]; - snprintf( dest, 512, "%s/%s", vg_compiler.build_dir, bin_name ); - - if( !access( dest, F_OK ) ) - vg_build_syscall( "unlink %s", dest ); - - vg_build_syscall( "ln -srf %s %s", folder, dest ); + vg_include_dir( "-I./vg/dep " ); + vg_library_dir( "-L./vg/dep/steam " ); } -void vg_build_copy_graphics_dependencies(void) -{ - if( vg_compiler.compiler == k_compiler_mingw ) - { - vg_build_bin_dependency_file( "vg/dep/sdl/SDL2.dll" ); +/* + * The project configurator and compiler. + * -------------------------------------------------------------------------- */ + +void vg_build_new( const char *name ){ + vg_strnull( &vg_build.include, NULL, -1 ); + vg_strnull( &vg_build.library, NULL, -1 ); + vg_strnull( &vg_build.link, NULL, -1 ); + vg_strnull( &vg_build.sources, NULL, -1 ); + vg_strnull( &vg_build.dest, NULL, -1 ); + vg_strnull( &vg_build.project_name, NULL, -1 ); + + /* check for problems in configuration */ + if( vg_build.libc != k_libc_version_native ){ + if( vg_build.compiler != k_compiler_zigcc ){ + vg_build.warnings ++; + vg_warn( "Cannot specify libc version using the '%s' compiler.\n", + compiler_names[ vg_build.compiler ] ); + } } -} - -void vg_build_copy_game_dependencies(void) -{ - vg_build_bin_dependency_file( - "vg/submodules/SDL_GameControllerDB/gamecontrollerdb.txt" ); - if( (vg_compiler.compiler == k_compiler_gcc) || - (vg_compiler.compiler == k_compiler_clang) || - (vg_compiler.compiler == k_compiler_zigcc) ) - { - vg_build_bin_dependency_file( "vg/dep/steam/libsteam_api.so" ); - } - else - { - vg_build_bin_dependency_file( "vg/dep/steam/steam_api.dll" ); + if( vg_build.compiler == k_compiler_clang ){ + if( vg_build.platform != k_platform_linux ){ + vg_build.warnings ++; + vg_warn( "Cannot compile for '%s' using the '%s' compiler;" ); + } } -} -void vg_build_mode_release(void) -{ - vg_compiler.optimization_profile = k_optimization_profile_release; + vg_str *proj = &vg_build.project_name; + + vg_strcat( proj, name ); + vg_strcatch( proj, '-' ); + vg_strcat( proj, platform_names[ vg_build.platform ] ); + vg_strcatch( proj, '-' ); + vg_strcat( proj, architecture_names[ vg_build.arch ] ); + vg_strcatch( proj, '-' ); + vg_strcat( proj, compiler_names[ vg_build.compiler ] ); + + vg_info( "project: %s (%s, %s, compiler: %s, opt:%u, fresh: %s)\n", + name, + platform_names[vg_build.platform], + architecture_names[vg_build.arch], + compiler_names[vg_build.compiler], + vg_build.optimization, + vg_build.fresh? "yes":"no"); + + if( proj->i < 3 ) + vg_fatal_error( "failed to create output directory\n" ); + + if( vg_build.fresh ) + vg_syscall( "rm -rf bin/%s", proj->buffer ); + vg_syscall( "mkdir -p bin/%s", proj->buffer ); + + vg_include_dir( "-I." ); + vg_include_dir( "-I./vg" ); + vg_library_dir( "-L." ); + vg_library_dir( "-L/usr/lib" ); } -void vg_build_mode_debug(void) -{ - vg_compiler.optimization_profile = k_optimization_profile_debug; -} +void vg_compile( const char *name ){ + vg_str cmd; + vg_strnull( &cmd, NULL, -1 ); -void vg_build_clean(void){ - vg_compiler.clean = 1; -} + /* compiler specification */ + vg_strcat( &cmd, "ccache " ); + vg_strcat( &cmd, compiler_paths[ vg_build.compiler ] ); + vg_strcat( &cmd, " -std=gnu99 -D_REENTRANT \\\n" ); -void vg_build(void) -{ - char cmd[8192]; - cmd[0] = '\0'; - - /* Compiler */ - strcat( cmd, "ccache " ); - strcat( cmd, vg_compiler_str() ); - strcat( cmd, " cc" ); - strcat( cmd, " -std=gnu99 -D_REENTRANT \\\n" ); - - /* Debugging information */ - if( vg_compiler.optimization_profile == k_optimization_profile_debug ) - { - strcat( cmd, " -O0 -ggdb3 -fno-omit-frame-pointer " ); - - if( (vg_compiler.compiler == k_compiler_gcc) || - (vg_compiler.compiler == k_compiler_clang ) || - (vg_compiler.compiler == k_compiler_zigcc) ) - { - strcat( cmd, "-rdynamic -fsanitize=address " - "-fPIE -fstack-protector-strong " ); + if( vg_build.optimization ){ + vg_strcat( &cmd, " -O" ); + vg_strcati32( &cmd, vg_build.optimization ); + vg_strcat( &cmd, " -DVG_RELEASE\\\n" ); + } + else { + /* add debugger / asan information */ + vg_strcat( &cmd, " -O0 -ggdb3 -fno-omit-frame-pointer " ); + + if( (vg_build.compiler == k_compiler_clang) && vg_build.debug_asan ){ + vg_strcat( &cmd, " -rdynamic -fsanitize=address -fPIE " + "-fstack-protector-strong " ); } - strcat( cmd, "\\\n" ); - } - else - { - strcat( cmd, " -O3 -DVG_RELEASE\\\n" ); + vg_strcat( &cmd, "\\\n" ); } - /* Warnings */ - strcat( cmd, - " -Wall\\\n" + /* want a lot of warnings but not useless ones */ + vg_strcat( &cmd, " -Wall -ferror-limit=8\\\n" " -Wno-unused-function -Wno-unused-variable -Wno-format-truncation\\\n" " -Wno-unused-command-line-argument -Wno-unused-but-set-variable\\\n" ); - if( vg_compiler.compiler == k_compiler_clang ){ - strcat( cmd, - " -ferror-limit=5\\\n" ); - } - - /* Include */ - strcat( cmd, " " ); - strcat( cmd, vg_compiler.include ); - strcat( cmd, "\\\n" ); - - /* Library */ - strcat( cmd, " " ); - strcat( cmd, vg_compiler.library ); - strcat( cmd, "\\\n" ); - - /* Targets */ - strcat( cmd, " " ); - strcat( cmd, vg_compiler.file ); - strcat( cmd, "\\\n" ); - - /* Output */ - strcat( cmd, " -o " ); - vg_compiler.executable[0] = '\0'; - strcat( vg_compiler.executable, vg_compiler.build_dir ); - strcat( vg_compiler.executable, "/" ); - strcat( vg_compiler.executable, vg_compiler.name ); - - if( vg_compiler.compiler == k_compiler_mingw ) - strcat( vg_compiler.executable, ".exe" ); - - strcat( cmd, vg_compiler.executable ); - strcat( cmd, "\\\n" ); - - /* Link */ - strcat( cmd, " " ); - strcat( cmd, vg_compiler.link ); - strcat( cmd, "\\\n" ); - - strcat( cmd, " -Wl,-rpath=./" ); + /* include paths */ + vg_strcat( &cmd, " " ); + vg_strcat( &cmd, vg_build.include.buffer ); + vg_strcat( &cmd, "\\\n" ); + + /* library paths */ + vg_strcat( &cmd, " " ); + vg_strcat( &cmd, vg_build.library.buffer ); + vg_strcat( &cmd, "\\\n" ); + + /* sources */ + vg_strcat( &cmd, " " ); + vg_strcat( &cmd, vg_build.sources.buffer ); + vg_strcat( &cmd, "\\\n" ); + + /* output */ + vg_strcat( &cmd, " -o bin/" ); + vg_strcat( &cmd, vg_build.project_name.buffer ); + vg_strcat( &cmd, "/" ); + vg_strcat( &cmd, name ); + if( vg_build.platform == k_platform_windows ) + vg_strcat( &cmd, ".exe" ); + vg_strcat( &cmd, "\\\n" ); + + /* link */ + vg_strcat( &cmd, " " ); + vg_strcat( &cmd, vg_build.link.buffer ); + vg_strcat( &cmd, "\\\n" ); + + /* dont remember what this does */ + vg_strcat( &cmd, " -Wl,-rpath=./\\\n" ); + + /* target platform specification (zig-cc only) */ + if( vg_build.compiler == k_compiler_zigcc ){ + vg_strcat( &cmd, " -target " ); + vg_strcat( &cmd, architecture_names[vg_build.arch] ); + vg_strcat( &cmd, "-" ); + vg_strcat( &cmd, platform_names[vg_build.platform] ); + + if( vg_build.platform == k_platform_linux ){ + vg_strcat( &cmd, "-gnu" ); + vg_strcat( &cmd, libc_names[vg_build.libc] ); + } - if( vg_compiler.compiler == k_compiler_zigcc ){ - strcat( cmd, " -target native-native-gnu.2.23" ); + if( vg_build.platform == k_platform_windows ){ + /* we currently dont want pdb pretty much ever. goodbye! */ + vg_strcat( &cmd, " /SUBSYSTEM:windows /pdb:/dev/null" ); + } } - vg_build_syscall( cmd ); + vg_syscall( cmd.buffer ); } diff --git a/vg_build_utils_shader.h b/vg_build_utils_shader.h index 642e7fc..39943b3 100644 --- a/vg_build_utils_shader.h +++ b/vg_build_utils_shader.h @@ -148,7 +148,7 @@ int vg_build_shader( char *src_vert, /* path/to/vert.vs */ strcat( path, name ); strcat( path, ".h" ); - printf( "Compiling shader called '%s'\n", name ); + vg_low( "Compiling shader called '%s'\r", name ); FILE *header = fopen( path, "w" ); if( !header ) diff --git a/vg_log.h b/vg_log.h index 9c8d59f..f80c3b3 100644 --- a/vg_log.h +++ b/vg_log.h @@ -12,7 +12,7 @@ #define vg_success( ... ) \ vg_logx(stdout,VG_LOG_WHERE,"success",KGRN,__VA_ARGS__) #define vg_info( ... ) \ - vg_logx(stdout,VG_LOG_WHERE,"info",KWHT,__VA_ARGS__) + vg_logx(stdout,VG_LOG_WHERE,"info",KNRM,__VA_ARGS__) #define vg_warn( ... ) \ vg_logx(stdout,VG_LOG_WHERE,"warn",KYEL,__VA_ARGS__ ) #define vg_error( ... ) \ diff --git a/vg_mem.h b/vg_mem.h index 9b104f1..48969d9 100644 --- a/vg_mem.h +++ b/vg_mem.h @@ -157,11 +157,7 @@ static void *_vg_linear_alloc( void *buffer, u32 size, vg_print_backtrace(); size = vg_align8( size ); } -#ifdef _WIN32 - if( ((u32)buffer) % 8 ){ -#else if( ((u64)buffer) % 8 ){ -#endif vg_fatal_error( "unaligned buffer (%p)", buffer ); } @@ -201,11 +197,7 @@ static void *_vg_linear_alloc( void *buffer, u32 size, alloc->last_alloc_size = size; alloc->cur += size; -#ifdef _WIN32 - if( ((u32)data) % 8 ){ -#else if( ((u64)data) % 8 ){ -#endif vg_fatal_error( "unaligned" ); } -- 2.25.1