support zig cc
[vg.git] / vg_build.h
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <unistd.h>
4
5 #include "vg_log.h"
6
7 struct compiler_info
8 {
9 char name[64],
10 file[512],
11 link[512],
12 library[512],
13 include[512],
14 build_dir[512],
15 executable[512];
16
17 enum optimization_profile
18 {
19 k_optimization_profile_debug,
20 k_optimization_profile_release
21 }
22 optimization_profile;
23
24 enum target_file
25 {
26 k_target_file_game,
27 k_target_file_server
28 }
29 target_file;
30
31 enum compiler
32 {
33 k_compiler_clang,
34 k_compiler_gcc,
35 k_compiler_mingw,
36 k_compiler_zigcc,
37 k_compiler_none
38 }
39 compiler;
40
41 int clean;
42 }
43
44 static vg_compiler;
45
46 void vg_build_syscall(const char *fmt, ...)
47 {
48 va_list args;
49 va_start( args, fmt );
50
51 char call[4096];
52 vsnprintf( call, vg_list_size( call ), fmt, args );
53
54 va_end( args );
55
56 puts( call );
57
58 if( system(call) )
59 exit(0);
60 }
61
62 void vg_build_object( const char *file )
63 {
64 strcat( vg_compiler.file, file );
65 }
66
67 void vg_build_library_dir( const char *ldir )
68 {
69 strcat( vg_compiler.library, ldir );
70 }
71
72 void vg_build_link( const char *link )
73 {
74 strcat( vg_compiler.link, link );
75 }
76
77 void vg_build_include( const char *inc )
78 {
79 strcat( vg_compiler.include, inc );
80 }
81
82 const char *vg_compiler_str(void)
83 {
84 return (const char *[])
85 { "clang", "gcc", "i686-w64-mingw32-gcc", "zig", "none" }
86 [vg_compiler.compiler];
87 }
88
89 void vg_build_start( const char *name, enum compiler compiler )
90 {
91 vg_compiler.file[0] = '\0';
92 vg_compiler.link[0] = '\0';
93 vg_compiler.include[0] = '\0';
94 vg_compiler.library[0] = '\0';
95 vg_compiler.compiler = compiler;
96 strcpy( vg_compiler.name, name );
97
98 snprintf( vg_compiler.build_dir, 512,
99 "bin/%s-%s",
100 name,
101 vg_compiler_str() );
102
103 if( vg_compiler.clean ){
104 vg_build_syscall( "rm -rf %s", vg_compiler.build_dir );
105 }
106
107 vg_build_syscall( "mkdir -p %s", vg_compiler.build_dir );
108 vg_build_include( "-I. -I./vg " );
109 vg_build_library_dir( "-L. " );
110
111 if( vg_compiler.compiler == k_compiler_zigcc )
112 vg_build_library_dir( "-L/usr/lib " );
113 }
114
115 void vg_build_add_link_for_graphics(void)
116 {
117 if( (vg_compiler.compiler == k_compiler_gcc) ||
118 (vg_compiler.compiler == k_compiler_clang ) ||
119 (vg_compiler.compiler == k_compiler_zigcc) )
120 {
121 vg_build_link( "-lSDL2 -lGL -lX11 -lXxf86vm -lXrandr -lXi -ldl " );
122 }
123 else
124 {
125 vg_build_link( "-lmingw32 -lSDL2main -lSDL2 -lopengl32 -mwindows \\\n" );
126 vg_build_link( " -Wl,--dynamicbase -Wl,--nxcompat \\\n" );
127
128 /* + 26.05.23: Suddenly something is pulling in winpthread.
129 * cant work out whats doing it or why. */
130 vg_build_link( " -Wl,-Bstatic,--whole-archive \\\n" );
131 vg_build_link( " -lwinpthread \\\n" );
132 vg_build_link( " -Wl,--no-whole-archive " );
133 }
134
135 vg_build_object( "vg/dep/glad/glad.c " );
136
137 vg_build_link( "-lm " );
138 if( vg_compiler.compiler == k_compiler_mingw ){
139 //vg_build_link( "-mthreads " );
140 //vg_build_link( "-static-libgcc " );
141 }
142 else{
143 vg_build_link( "-pthread " );
144 }
145 }
146
147 void vg_build_add_link_for_game(void)
148 {
149 if( (vg_compiler.compiler == k_compiler_gcc) ||
150 (vg_compiler.compiler == k_compiler_clang ) ||
151 (vg_compiler.compiler == k_compiler_zigcc) )
152 {
153 vg_build_link( "-lsteam_api " );
154 }
155 else
156 {
157 vg_build_library_dir( "-L./vg/dep/sdl " );
158 vg_build_link( "vg/dep/steam/steam_api.dll " );
159 }
160
161 vg_build_include( "-I./vg/dep " );
162 vg_build_library_dir( "-L./vg/dep/steam " );
163 }
164
165 void vg_build_bin_dependency_file( const char *src )
166 {
167 vg_build_syscall( "cp %s %s", src, vg_compiler.build_dir );
168 }
169
170 void vg_build_symbolic_link( const char *folder, const char *bin_name )
171 {
172 char dest[512];
173 snprintf( dest, 512, "%s/%s", vg_compiler.build_dir, bin_name );
174
175 if( !access( dest, F_OK ) )
176 vg_build_syscall( "unlink %s", dest );
177
178 vg_build_syscall( "ln -srf %s %s", folder, dest );
179 }
180
181 void vg_build_copy_graphics_dependencies(void)
182 {
183 if( vg_compiler.compiler == k_compiler_mingw )
184 {
185 vg_build_bin_dependency_file( "vg/dep/sdl/SDL2.dll" );
186 }
187 }
188
189 void vg_build_copy_game_dependencies(void)
190 {
191 vg_build_bin_dependency_file(
192 "vg/submodules/SDL_GameControllerDB/gamecontrollerdb.txt" );
193
194 if( (vg_compiler.compiler == k_compiler_gcc) ||
195 (vg_compiler.compiler == k_compiler_clang) ||
196 (vg_compiler.compiler == k_compiler_zigcc) )
197 {
198 vg_build_bin_dependency_file( "vg/dep/steam/libsteam_api.so" );
199 }
200 else
201 {
202 vg_build_bin_dependency_file( "vg/dep/steam/steam_api.dll" );
203 }
204 }
205
206 void vg_build_mode_release(void)
207 {
208 vg_compiler.optimization_profile = k_optimization_profile_release;
209 }
210
211 void vg_build_mode_debug(void)
212 {
213 vg_compiler.optimization_profile = k_optimization_profile_debug;
214 }
215
216 void vg_build_clean(void){
217 vg_compiler.clean = 1;
218 }
219
220 void vg_build(void)
221 {
222 char cmd[8192];
223 cmd[0] = '\0';
224
225 /* Compiler */
226 strcat( cmd, "ccache " );
227 strcat( cmd, vg_compiler_str() );
228 strcat( cmd, " cc" );
229 strcat( cmd, " -std=gnu99 -D_REENTRANT \\\n" );
230
231 /* Debugging information */
232 if( vg_compiler.optimization_profile == k_optimization_profile_debug )
233 {
234 strcat( cmd, " -O0 -ggdb3 -fno-omit-frame-pointer " );
235
236 if( (vg_compiler.compiler == k_compiler_gcc) ||
237 (vg_compiler.compiler == k_compiler_clang ) ||
238 (vg_compiler.compiler == k_compiler_zigcc) )
239 {
240 strcat( cmd, "-rdynamic -fsanitize=address "
241 "-fPIE -fstack-protector-strong " );
242 }
243
244 strcat( cmd, "\\\n" );
245 }
246 else
247 {
248 strcat( cmd, " -O3 -DVG_RELEASE\\\n" );
249 }
250
251 /* Warnings */
252 strcat( cmd,
253 " -Wall\\\n"
254 " -Wno-unused-function -Wno-unused-variable -Wno-format-truncation\\\n"
255 " -Wno-unused-command-line-argument -Wno-unused-but-set-variable\\\n"
256 );
257
258 if( vg_compiler.compiler == k_compiler_clang ){
259 strcat( cmd,
260 " -ferror-limit=5\\\n" );
261 }
262
263 /* Include */
264 strcat( cmd, " " );
265 strcat( cmd, vg_compiler.include );
266 strcat( cmd, "\\\n" );
267
268 /* Library */
269 strcat( cmd, " " );
270 strcat( cmd, vg_compiler.library );
271 strcat( cmd, "\\\n" );
272
273 /* Targets */
274 strcat( cmd, " " );
275 strcat( cmd, vg_compiler.file );
276 strcat( cmd, "\\\n" );
277
278 /* Output */
279 strcat( cmd, " -o " );
280 vg_compiler.executable[0] = '\0';
281 strcat( vg_compiler.executable, vg_compiler.build_dir );
282 strcat( vg_compiler.executable, "/" );
283 strcat( vg_compiler.executable, vg_compiler.name );
284
285 if( vg_compiler.compiler == k_compiler_mingw )
286 strcat( vg_compiler.executable, ".exe" );
287
288 strcat( cmd, vg_compiler.executable );
289 strcat( cmd, "\\\n" );
290
291 /* Link */
292 strcat( cmd, " " );
293 strcat( cmd, vg_compiler.link );
294 strcat( cmd, "\\\n" );
295
296 strcat( cmd, " -Wl,-rpath=./" );
297
298 if( vg_compiler.compiler == k_compiler_zigcc ){
299 strcat( cmd, " -target native-native-gnu.2.23" );
300 }
301
302 vg_build_syscall( cmd );
303 }