better build program
authorhgn <hgodden00@gmail.com>
Thu, 21 Dec 2023 16:22:47 +0000 (16:22 +0000)
committerhgn <hgodden00@gmail.com>
Thu, 21 Dec 2023 17:17:07 +0000 (17:17 +0000)
vg.h
vg_build.h
vg_build_utils_shader.h
vg_log.h
vg_mem.h

diff --git a/vg.h b/vg.h
index e62eb24dd9ecbd776dd3dac7753353e5e5f69a1f..aa86ab547a27e3cb84d106b0154c6f36246bdc54 100644 (file)
--- 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 */
index f1b14350b9a5f2969fa64e8bf08ebd231a3767aa..965f14cac3941c73e687985360410d581b5008a3 100644 (file)
+/* zig cc scripting tools */
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <time.h>
 
 #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 );
 }
index 642e7fc4003ec4d734bc0db12820602a4df0a261..39943b3c0de63494d6b97dc976b25d96ef30deaa 100644 (file)
@@ -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 )
index 9c8d59f373a4c4084406de3e835acac3cd4922b5..f80c3b366c528f4d35fd1614d9ae03eee0145aae 100644 (file)
--- 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( ... ) \
index 9b104f1186af0cdc26e16ade54527838d8c5fd44..48969d9d13be9588f811b898f9454fd9de96c609 100644 (file)
--- 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" );
    }