1 /* zig cc scripting tools */
10 /* we dont free dynamic vg_strs in this program. so, we dont care.. */
11 const char *__asan_default_options() { return "detect_leaks=0"; }
27 k_platform_anyplatform
,
34 k_architecture_anyarch
,
36 k_architecture_x86_64
,
48 k_libc_version_native
,
53 static vg_build
= { .debug_asan
= 1 };
57 * -------------------------------------------------------------------------- */
59 static const char *platform_names
[] = {
60 [k_platform_anyplatform
] = "anyplatform",
61 [k_platform_windows
] = "windows",
62 [k_platform_linux
] = "linux"
65 static const char *architecture_names
[] = {
66 [k_architecture_anyarch
] = "anyarch",
67 [k_architecture_i386
] = "i386",
68 [k_architecture_x86_64
] = "x86_64"
71 static const char *compiler_names
[] = {
72 [k_compiler_blob
] = "blob",
73 [k_compiler_clang
] = "clang",
74 [k_compiler_zigcc
] = "zig-cc"
77 static const char *compiler_paths
[] = {
78 [k_compiler_blob
] = NULL
,
79 [k_compiler_clang
] = "clang",
80 [k_compiler_zigcc
] = "zig cc"
83 static const char *libc_names
[] = {
84 [k_libc_version_native
] = "",
85 [k_libc_version_2_23
] = ".2.23"
89 * source specification
90 * -------------------------------------------------------------------------- */
92 void vg_add_source( const char *source
){
93 vg_strcat( &vg_build
.sources
, source
);
94 vg_strcat( &vg_build
.sources
, " " );
97 void vg_include_dir( const char *dir
){
98 vg_strcat( &vg_build
.include
, dir
);
99 vg_strcat( &vg_build
.include
, " " );
102 void vg_library_dir( const char *dir
){
103 vg_strcat( &vg_build
.library
, dir
);
104 vg_strcat( &vg_build
.library
, " " );
107 void vg_link( const char *lib
){
108 vg_strcat( &vg_build
.link
, lib
);
113 * -------------------------------------------------------------------------- */
115 void vg_syscall( const char *fmt
, ... ){
117 va_start( args
, fmt
);
120 vsnprintf( call
, sizeof(call
), fmt
, args
);
123 vg_low( "%s\n", call
);
128 void vg_add_blob( const char *blob
, const char *dest
){
129 vg_syscall( "cp %s bin/%s/%s", blob
, vg_build
.project_name
.buffer
, dest
);
132 void vg_symlink( const char *folder
, const char *bin_name
){
134 snprintf( dest
, 512, "bin/%s/%s", vg_build
.project_name
.buffer
, bin_name
);
135 if( !access( dest
, F_OK
) )
136 vg_syscall( "unlink %s", dest
);
137 vg_syscall( "ln -srf %s %s", folder
, dest
);
140 void vg_tarball_last_project(void){
141 vg_syscall( "tar -chzvf dist/%s-%u.tar.gz bin/%s/",
142 vg_build
.project_name
.buffer
, time(NULL
),
143 vg_build
.project_name
.buffer
);
148 * Standard VG includes & libraries which we use for games/graphics
149 * -------------------------------------------------------------------------- */
151 void vg_add_graphics(void){
152 vg_add_source( "vg/dep/glad/glad.c" );
154 if( vg_build
.platform
== k_platform_windows
)
155 vg_add_blob( "vg/dep/sdl/SDL2.dll", "" );
159 if( vg_build
.platform
== k_platform_linux
)
160 vg_link( "-lSDL2 -lGL -lX11 -lXxf86vm -lXrandr -lXi -ldl -pthread " );
162 vg_link( "-lmingw32 -lSDL2main -lSDL2 -lopengl32 \\\n" );
165 void vg_add_game_stuff(void){
166 vg_add_blob( "vg/submodules/SDL_GameControllerDB/gamecontrollerdb.txt", "" );
168 if( vg_build
.platform
== k_platform_linux
){
169 vg_add_blob( "vg/dep/steam/libsteam_api.so", "" );
170 vg_link( "-lsteam_api " );
172 else if( vg_build
.platform
== k_platform_windows
){
173 vg_add_blob( "vg/dep/steam/steam_api64.dll", "" );
174 vg_link( "vg/dep/steam/steam_api64.dll " );
175 vg_link( "vg/dep/sdl/SDL2.dll " );
176 vg_library_dir( "-L./vg/dep/sdl " );
179 vg_include_dir( "-I./vg/dep " );
180 vg_library_dir( "-L./vg/dep/steam " );
184 * The project configurator and compiler.
185 * -------------------------------------------------------------------------- */
187 void vg_build_new( const char *name
){
188 vg_strnull( &vg_build
.include
, NULL
, -1 );
189 vg_strnull( &vg_build
.library
, NULL
, -1 );
190 vg_strnull( &vg_build
.link
, NULL
, -1 );
191 vg_strnull( &vg_build
.sources
, NULL
, -1 );
192 vg_strnull( &vg_build
.dest
, NULL
, -1 );
193 vg_strnull( &vg_build
.project_name
, NULL
, -1 );
195 /* check for problems in configuration */
196 if( vg_build
.libc
!= k_libc_version_native
){
197 if( vg_build
.compiler
!= k_compiler_zigcc
){
198 vg_build
.warnings
++;
199 vg_warn( "Cannot specify libc version using the '%s' compiler.\n",
200 compiler_names
[ vg_build
.compiler
] );
204 if( vg_build
.compiler
== k_compiler_clang
){
205 if( vg_build
.platform
!= k_platform_linux
){
206 vg_build
.warnings
++;
207 vg_warn( "Cannot compile for '%s' using the '%s' compiler;" );
211 vg_str
*proj
= &vg_build
.project_name
;
213 vg_strcat( proj
, name
);
214 vg_strcatch( proj
, '-' );
215 vg_strcat( proj
, platform_names
[ vg_build
.platform
] );
216 vg_strcatch( proj
, '-' );
217 vg_strcat( proj
, architecture_names
[ vg_build
.arch
] );
218 vg_strcatch( proj
, '-' );
219 vg_strcat( proj
, compiler_names
[ vg_build
.compiler
] );
221 vg_info( "project: %s (%s, %s, compiler: %s, opt:%u, fresh: %s)\n",
223 platform_names
[vg_build
.platform
],
224 architecture_names
[vg_build
.arch
],
225 compiler_names
[vg_build
.compiler
],
226 vg_build
.optimization
,
227 vg_build
.fresh
? "yes":"no");
230 vg_fatal_error( "failed to create output directory\n" );
233 vg_syscall( "rm -rf bin/%s", proj
->buffer
);
234 vg_syscall( "mkdir -p bin/%s", proj
->buffer
);
236 vg_include_dir( "-I." );
237 vg_include_dir( "-I./vg" );
238 vg_library_dir( "-L." );
239 vg_library_dir( "-L/usr/lib" );
242 void vg_compile( const char *name
){
244 vg_strnull( &cmd
, NULL
, -1 );
246 /* compiler specification */
247 vg_strcat( &cmd
, "ccache " );
248 vg_strcat( &cmd
, compiler_paths
[ vg_build
.compiler
] );
249 vg_strcat( &cmd
, " -std=gnu99 -D_REENTRANT \\\n" );
251 if( vg_build
.optimization
){
252 vg_strcat( &cmd
, " -O" );
253 vg_strcati32( &cmd
, vg_build
.optimization
);
254 vg_strcat( &cmd
, " -DVG_RELEASE\\\n" );
257 /* add debugger / asan information */
258 vg_strcat( &cmd
, " -O0 -ggdb3 -fno-omit-frame-pointer " );
260 if( (vg_build
.compiler
== k_compiler_clang
) && vg_build
.debug_asan
){
261 vg_strcat( &cmd
, " -rdynamic -fsanitize=address -fPIE "
262 "-fstack-protector-strong " );
265 vg_strcat( &cmd
, "\\\n" );
268 /* want a lot of warnings but not useless ones */
269 vg_strcat( &cmd
, " -Wall -ferror-limit=8\\\n"
270 " -Wno-unused-function -Wno-unused-variable -Wno-format-truncation\\\n"
271 " -Wno-unused-command-line-argument -Wno-unused-but-set-variable\\\n"
275 vg_strcat( &cmd
, " " );
276 vg_strcat( &cmd
, vg_build
.include
.buffer
);
277 vg_strcat( &cmd
, "\\\n" );
280 vg_strcat( &cmd
, " " );
281 vg_strcat( &cmd
, vg_build
.library
.buffer
);
282 vg_strcat( &cmd
, "\\\n" );
285 vg_strcat( &cmd
, " " );
286 vg_strcat( &cmd
, vg_build
.sources
.buffer
);
287 vg_strcat( &cmd
, "\\\n" );
290 vg_strcat( &cmd
, " -o bin/" );
291 vg_strcat( &cmd
, vg_build
.project_name
.buffer
);
292 vg_strcat( &cmd
, "/" );
293 vg_strcat( &cmd
, name
);
294 if( vg_build
.platform
== k_platform_windows
)
295 vg_strcat( &cmd
, ".exe" );
296 vg_strcat( &cmd
, "\\\n" );
299 vg_strcat( &cmd
, " " );
300 vg_strcat( &cmd
, vg_build
.link
.buffer
);
301 vg_strcat( &cmd
, "\\\n" );
303 /* dont remember what this does */
304 vg_strcat( &cmd
, " -Wl,-rpath=./\\\n" );
306 /* target platform specification (zig-cc only) */
307 if( vg_build
.compiler
== k_compiler_zigcc
){
308 vg_strcat( &cmd
, " -target " );
309 vg_strcat( &cmd
, architecture_names
[vg_build
.arch
] );
310 vg_strcat( &cmd
, "-" );
311 vg_strcat( &cmd
, platform_names
[vg_build
.platform
] );
313 if( vg_build
.platform
== k_platform_linux
){
314 vg_strcat( &cmd
, "-gnu" );
315 vg_strcat( &cmd
, libc_names
[vg_build
.libc
] );
318 if( vg_build
.platform
== k_platform_windows
){
319 /* we currently dont want pdb pretty much ever. goodbye! */
320 vg_strcat( &cmd
, " /SUBSYSTEM:windows /pdb:/dev/null" );
324 vg_syscall( cmd
.buffer
);