gwenhywfar 5.12.0
c_setup.c
Go to the documentation of this file.
1/***************************************************************************
2 begin : Mon Feb 08 2021
3 copyright : (C) 2021 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10#ifdef HAVE_CONFIG_H
11# include <config.h>
12#endif
13
14
15#include "c_setup.h"
16#include "utils.h"
19#include "gwenbuild/filenames.h"
20
21#include <gwenhywfar/debug.h>
22#include <gwenhywfar/directory.h>
23#include <gwenhywfar/text.h>
24
25#include <sys/stat.h>
26#include <errno.h>
27#include <unistd.h>
28
29
30
31static int _prepareContextForSetup(GWB_CONTEXT *firstContext, GWEN_DB_NODE *dbArgs);
32static void _determineTarget(GWB_CONTEXT *context, GWEN_DB_NODE *dbArgs);
33static int _determineTools(GWB_CONTEXT *context, GWEN_DB_NODE *dbArgs);
34static int _getAllToolPaths(GWEN_DB_NODE *dbVars, const char *sCompileTarget, const GWEN_STRINGLIST *sl);
35static int _getToolPath(GWEN_DB_NODE *dbVars, const char *sTarget, const GWEN_STRINGLIST *sl,
36 const char *sCommand, const char *sEnvVar, const char *sVarName);
38static void _copyEnvironmentVariableToDb(GWEN_DB_NODE *db, const char *envName, const char *dbVarName);
39static GWB_KEYVALUEPAIR_LIST *_readOptionsFromDb(GWEN_DB_NODE *db);
40static int _writeStaticLibHelper(const char *fileName);
41
42
43
44
46{
47 GWENBUILD *gwenbuild;
48 GWB_CONTEXT *firstContext;
49 GWB_PROJECT *project;
50 GWB_BUILD_CONTEXT *buildCtx;
51 const char *folder;
52 int doDump;
53 GWB_KEYVALUEPAIR_LIST *givenOptionList;
54 int rv;
55
56 doDump=GWEN_DB_GetIntValue(dbArgs, "dump", 0, 0);
57
58 folder=GWEN_DB_GetCharValue(dbArgs, "folder", 0, NULL);
59 if (!(folder && *folder)) {
60 fprintf(stderr, "ERROR: Folder needed.\n");
61 return 1;
62 }
63 if (strcasecmp(folder, ".")==0) {
64 fprintf(stderr, "ERROR: Only building outside source folder supported.\n");
65 return 1;
66 }
67
68 givenOptionList=_readOptionsFromDb(dbArgs);
69
70
71 gwenbuild=GWBUILD_new();
72 if (GWEN_DB_GetIntValue(dbArgs, "static", 0, 0))
74
75 firstContext=GWB_Context_new(gwenbuild);
76 rv=_prepareContextForSetup(firstContext, dbArgs);
77 if (rv<0) {
78 fprintf(stderr, "ERROR: Error preparing first context.\n");
79 return 2;
80 }
81
82 project=GWB_Parser_ReadBuildTree(gwenbuild, firstContext, folder, givenOptionList);
83 if (project==NULL) {
84 fprintf(stderr, "ERROR: Error reading build files.\n");
85 return 2;
86 }
87
89 if (rv<0) {
90 fprintf(stderr, "ERROR: Error making builders for targets.\n");
91 return 2;
92 }
93
94 buildCtx=GWBUILD_MakeBuildCommands(project);
95 if (buildCtx==NULL) {
96 fprintf(stderr, "ERROR: Could not generate build commands.\n");
97 return 2;
98 }
99
101 if (rv<0) {
102 fprintf(stderr, "ERROR: Error writing build context file.\n");
103 return 3;
104 }
105
107 if (rv<0) {
108 fprintf(stderr, "ERROR: Error writing file list file.\n");
109 return 3;
110 }
111
113
115 if (rv<0) {
116 fprintf(stderr, "ERROR: Error writing file list file.\n");
117 return 3;
118 }
119
121 if (rv<0) {
122 fprintf(stderr, "ERROR: Error writing install file list.\n");
123 return 3;
124 }
125
126#if 0
128 if (rv<0) {
129 fprintf(stderr, "ERROR: Error writing project to file.\n");
130 return 3;
131 }
132#endif
133
135 if (rv<0) {
136 fprintf(stderr, "ERROR: Error writing project info to file.\n");
137 return 3;
138 }
139
140
142
143 rv=_writeStaticLibHelper("staticlibhelper.sh");
144 if (rv<0) {
145 fprintf(stderr, "ERROR: Error writing staticlibhelper.\n");
146 return 3;
147 }
148
149
150 if (doDump) {
151 GWB_Project_Dump(project, 2, 1);
152 }
153
154 return 0;
155}
156
157
158
159int GWB_RepeatLastSetup(const char *fileName)
160{
161 int rv;
162 GWEN_DB_NODE *db;
163
164 db=GWEN_DB_Group_new("args");
165 rv=GWEN_DB_ReadFile(db, fileName, GWEN_DB_FLAGS_DEFAULT);
166 if (rv<0) {
167 DBG_ERROR(NULL, "Error reading arguments from previous run (file \"%s\")", fileName);
169 return rv;
170 }
171
172 rv=GWB_Setup(db);
173 if (rv!=0) {
174 DBG_INFO(NULL, "here (%d)", rv);
176 return rv;
177 }
179
180 return 0;
181}
182
183
184
185
187{
188 GWEN_DB_NODE *dbVars;
189 int rv;
190
191 dbVars=GWB_Context_GetVars(context);
192 GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "prefix", "/usr/local");
193
195 _determineTarget(context, dbArgs);
196 rv=_determineTools(context, dbArgs);
197 if (rv<0) {
198 DBG_INFO(NULL, "here (%d)", rv);
199 return rv;
200 }
201 return 0;
202}
203
204
205
207{
208 GWENBUILD *gwenbuild;
209 GWEN_DB_NODE *dbVars;
210 const char *sTarget;
211 const char *sTargetSystem;
212 const char *s;
213 int systemIsWindows=0;
214
215 dbVars=GWB_Context_GetVars(context);
216
217 gwenbuild=GWB_Context_GetGwenbuild(context);
218
219 sTarget=GWEN_DB_GetCharValue(dbArgs, "crossCompileFor", 0, NULL);
220 if (sTarget) {
222 GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "GWBUILD_ARCH", s);
223 sTargetSystem=GWBUILD_GetSystemFromTriplet(sTarget);
224 }
225 else {
227 sTargetSystem=GWBUILD_GetHostSystem();
228 }
229 systemIsWindows=(strcasecmp(sTargetSystem, "windows")==0)?1:0;
230
232 GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "GWBUILD_LIBTYPE", "staticlib");
233 else
234 GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "GWBUILD_LIBTYPE", "sharedlib");
235
236 GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "GWBUILD_SYSTEM", sTargetSystem);
237 GWBUILD_SetTargetSystem(gwenbuild, sTargetSystem);
238 GWBUILD_SetTargetIsWindows(gwenbuild, systemIsWindows);
239 GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "GWBUILD_SYSTEMTYPE", systemIsWindows?"windows":"posix");
240}
241
242
243
245{
246 GWEN_DB_NODE *dbVars;
247 const char *sTarget;
248 GWEN_STRINGLIST *sl;
249 int rv;
250
251 dbVars=GWB_Context_GetVars(context);
252 sTarget=GWEN_DB_GetCharValue(dbArgs, "crossCompileFor", 0, NULL);
253
255 if (sl==NULL)
257
258 GWEN_StringList_AppendString(sl, "/usr/local/bin", 0, 1);
259 GWEN_StringList_AppendString(sl, "/usr/bin", 0, 1);
260 GWEN_StringList_AppendString(sl, "/bin", 0, 1);
261
262 rv=_getAllToolPaths(dbVars, sTarget, sl);
263 if (rv<0) {
264 DBG_INFO(NULL, "here (%d)", rv);
266 return rv;
267 }
269
270 return 0;
271}
272
273
274
275int _getAllToolPaths(GWEN_DB_NODE *dbVars, const char *sCompileTarget, const GWEN_STRINGLIST *sl)
276{
277 int rv;
278
279 rv=_getToolPath(dbVars, sCompileTarget, sl, "gcc", "CC", "GWBUILD_TOOL_CC");
280 if (rv<0)
281 return rv;
282
283 rv=_getToolPath(dbVars, sCompileTarget, sl, "g++", "CXX", "GWBUILD_TOOL_CXX");
284 if (rv<0)
285 return rv;
286
287 rv=_getToolPath(dbVars, sCompileTarget, sl, "ld", "LD", "GWBUILD_TOOL_LD");
288 if (rv<0)
289 return rv;
290
291 rv=_getToolPath(dbVars, sCompileTarget, sl, "ar", "AR", "GWBUILD_TOOL_AR");
292 if (rv<0)
293 return rv;
294
295 rv=_getToolPath(dbVars, sCompileTarget, sl, "ranlib", "RANLIB", "GWBUILD_TOOL_RANLIB");
296 if (rv<0)
297 return rv;
298
299 rv=_getToolPath(dbVars, NULL, sl, "typemaker2", "TYPEMAKER2", "GWBUILD_TOOL_TYPEMAKER2");
300 if (rv<0)
301 return rv;
302
303 /* optional tools */
304 rv=_getToolPath(dbVars, sCompileTarget, sl, "msgfmt", "MSGFMT", "GWBUILD_TOOL_MSGFMT");
305 if (rv<0) {
306 DBG_WARN(NULL, "Tool msgfmt not found, limited i18n support.");
307 GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "msgfmt_EXISTS", "FALSE");
308 }
309 else
310 GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "msgfmt_EXISTS", "TRUE");
311
312 rv=_getToolPath(dbVars, NULL, sl, "avra", "AVRA", "GWBUILD_TOOL_AVRA");
313 if (rv<0) {
314 DBG_INFO(NULL, "Tool avra not found, only needed when assembling AVR assembler code.");
315 }
316
317 /* add more tools here */
318
319
320 /* done */
321 return 0;
322}
323
324
325
326int _getToolPath(GWEN_DB_NODE *dbVars, const char *sCompileTarget, const GWEN_STRINGLIST *sl,
327 const char *sCommand, const char *sEnvVar, const char *sVarName)
328{
329 GWEN_BUFFER *fbufIn;
330 GWEN_BUFFER *fbufOut;
331 const char *s;
332 int rv;
333
334 fbufIn=GWEN_Buffer_new(0, 256, 0, 1);
335
336 if (sCompileTarget && *sCompileTarget) {
337 GWEN_Buffer_AppendString(fbufIn, sCompileTarget);
338 GWEN_Buffer_AppendString(fbufIn, "-");
339 }
340
341 s=getenv(sEnvVar);
342 if (s)
343 GWEN_Buffer_AppendString(fbufIn, s);
344 else
345 GWEN_Buffer_AppendString(fbufIn, sCommand);
346
347 fbufOut=GWEN_Buffer_new(0, 256, 0, 1);
349 if (rv<0) {
350 DBG_ERROR(NULL, "Tool \"%s\" not available (%d)", GWEN_Buffer_GetStart(fbufIn), rv);
351 GWEN_Buffer_free(fbufOut);
352 GWEN_Buffer_free(fbufIn);
353 return rv;
354 }
355
357 GWEN_Buffer_free(fbufOut);
358 GWEN_Buffer_free(fbufIn);
359 return 0;
360}
361
362
363
365{
366 _copyEnvironmentVariableToDb(db, "CFLAGS", "CFLAGS");
367 _copyEnvironmentVariableToDb(db, "CXXFLAGS", "CXXFLAGS");
368 _copyEnvironmentVariableToDb(db, "CPPFLAGS", "CPPFLAGS");
369 _copyEnvironmentVariableToDb(db, "LDFLAGS", "LDFLAGS");
370 _copyEnvironmentVariableToDb(db, "TM2FLAGS", "TM2FLAGS");
371}
372
373
374
375
376
377void _copyEnvironmentVariableToDb(GWEN_DB_NODE *db, const char *envName, const char *dbVarName)
378{
379 const char *s;
380
381 s=getenv(envName);
382 if (s && *s)
384}
385
386
387
388GWB_KEYVALUEPAIR_LIST *_readOptionsFromDb(GWEN_DB_NODE *db)
389{
390 int i;
391 GWB_KEYVALUEPAIR_LIST *kvpList;
392
393 kvpList=GWB_KeyValuePair_List_new();
394 for (i=0; i<100; i++) {
395 const char *sOption;
396 GWEN_STRINGLIST *sl;
397
398 sOption=GWEN_DB_GetCharValue(db, "option", i, NULL);
399 if (sOption==NULL)
400 break;
401
403 if (sl) {
404 const char *name;
405 const char *value;
406
407 name=GWEN_StringList_StringAt(sl, 0);
408 value=GWEN_StringList_StringAt(sl, 1);
409 if (name) {
410 GWB_KEYVALUEPAIR *kvp;
411
412 kvp=GWB_KeyValuePair_new(name, value);
413 GWB_KeyValuePair_List_Add(kvp, kvpList);
414 }
416 }
417 } /* for */
418
419 if (GWB_KeyValuePair_List_GetCount(kvpList)==0) {
420 GWB_KeyValuePair_List_free(kvpList);
421 return NULL;
422 }
423
424 return kvpList;
425}
426
427
428
429int _writeStaticLibHelper(const char *fileName)
430{
431 int rv;
432 static char *staticLibHelperContent=
433 "#!/bin/sh\n"
434 "\n"
435 "TOOL=$1\n"
436 "LIB=$2\n"
437 "\n"
438 "$TOOL -t $LIB | xargs ar rvs $LIB.new && mv -v $LIB.new $LIB";
439
440 unlink(fileName);
441 rv=GWEN_SyncIo_Helper_WriteFile(fileName, (const uint8_t*) staticLibHelperContent, strlen(staticLibHelperContent));
442 if (rv<0) {
443 DBG_ERROR(NULL, "Error writing static lib helper to \"%s\" (%d)", fileName, rv);
444 return rv;
445 }
446 if (chmod(fileName, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP)==-1) {
447 DBG_ERROR(NULL, "Error on chmod(%s): %s", fileName, strerror(errno));
448 return GWEN_ERROR_GENERIC;
449 }
450
451 return 0;
452}
453
454
455
456
457
#define NULL
Definition binreloc.c:300
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition buffer.c:42
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition buffer.c:89
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition buffer.c:992
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition buffer.c:235
struct GWB_BUILD_CONTEXT GWB_BUILD_CONTEXT
Definition buildctx.h:16
int GWB_BuildCtx_WriteToXmlFile(const GWB_BUILD_CONTEXT *buildCtx, const char *fileName)
static GWB_KEYVALUEPAIR_LIST * _readOptionsFromDb(GWEN_DB_NODE *db)
Definition c_setup.c:388
static int _prepareContextForSetup(GWB_CONTEXT *firstContext, GWEN_DB_NODE *dbArgs)
Definition c_setup.c:186
static void _copyEnvironmentVariableToDb(GWEN_DB_NODE *db, const char *envName, const char *dbVarName)
Definition c_setup.c:377
static int _writeStaticLibHelper(const char *fileName)
Definition c_setup.c:429
static int _getToolPath(GWEN_DB_NODE *dbVars, const char *sTarget, const GWEN_STRINGLIST *sl, const char *sCommand, const char *sEnvVar, const char *sVarName)
Definition c_setup.c:326
int GWB_Setup(GWEN_DB_NODE *dbArgs)
Definition c_setup.c:45
static void _determineTarget(GWB_CONTEXT *context, GWEN_DB_NODE *dbArgs)
Definition c_setup.c:206
int GWB_RepeatLastSetup(const char *fileName)
Definition c_setup.c:159
static int _determineTools(GWB_CONTEXT *context, GWEN_DB_NODE *dbArgs)
Definition c_setup.c:244
static void _copySomeEnvironmentVariablesToDb(GWEN_DB_NODE *db)
Definition c_setup.c:364
static int _getAllToolPaths(GWEN_DB_NODE *dbVars, const char *sCompileTarget, const GWEN_STRINGLIST *sl)
Definition c_setup.c:275
GWB_CONTEXT * GWB_Context_new(GWENBUILD *gwenbuild)
Definition context.c:34
GWEN_DB_NODE * GWB_Context_GetVars(const GWB_CONTEXT *ctx)
Definition context.c:427
GWENBUILD * GWB_Context_GetGwenbuild(const GWB_CONTEXT *ctx)
Definition context.c:117
struct GWB_CONTEXT GWB_CONTEXT
Definition context.h:17
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition db.c:971
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition db.c:173
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition db.c:997
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition db.c:1163
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition db.c:421
GWENHYWFAR_API int GWEN_DB_ReadFile(GWEN_DB_NODE *n, const char *fname, uint32_t dbflags)
Definition dbrw.c:1003
GWENHYWFAR_API int GWEN_DB_WriteFile(GWEN_DB_NODE *n, const char *fname, uint32_t dbflags)
Definition dbrw.c:535
#define GWEN_DB_FLAGS_DEFAULT
Definition db.h:168
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition db.h:121
struct GWEN_DB_NODE GWEN_DB_NODE
Definition db.h:228
#define DBG_INFO(dbg_logger, format,...)
Definition debug.h:181
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
#define DBG_WARN(dbg_logger, format,...)
Definition debug.h:125
GWENHYWFAR_API int GWEN_Directory_FindFileInPaths(const GWEN_STRINGLIST *paths, const char *filePath, GWEN_BUFFER *fbuf)
#define GWEN_ERROR_GENERIC
Definition error.h:62
#define GWBUILD_FILE_PROJECTINFO
Definition filenames.h:17
#define GWBUILD_FILE_PROJECT
Definition filenames.h:18
#define GWBUILD_FILE_BUILDFILES
Definition filenames.h:14
#define GWBUILD_FILE_INSTALLFILES
Definition filenames.h:19
#define GWBUILD_FILE_FILES
Definition filenames.h:16
#define GWBUILD_FILE_ARGS
Definition filenames.h:20
#define GWBUILD_FILE_CTXTREE
Definition filenames.h:21
#define GWBUILD_FILE_CTX
Definition filenames.h:15
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition buffer.h:38
const char * GWBUILD_GetHostSystem()
Definition gwenbuild.c:960
uint32_t GWBUILD_GetFlags(const GWENBUILD *gwenbuild)
Definition gwenbuild.c:84
int GWBUILD_MakeBuildersForTargets(GWB_PROJECT *project)
Definition gwenbuild.c:495
GWEN_STRINGLIST * GWBUILD_GetPathFromEnvironment()
Definition gwenbuild.c:154
const char * GWBUILD_GetSystemFromTriplet(const char *sTriplet)
Definition gwenbuild.c:1003
GWB_BUILD_CONTEXT * GWBUILD_MakeBuildCommands(GWB_PROJECT *project)
Definition gwenbuild.c:756
GWENBUILD * GWBUILD_new(void)
Definition gwenbuild.c:60
void GWBUILD_SetTargetIsWindows(GWENBUILD *gwenbuild, int i)
Definition gwenbuild.c:133
const char * GWBUILD_GetArchFromTriplet(const char *sTriplet)
Definition gwenbuild.c:991
void GWBUILD_SetTargetSystem(GWENBUILD *gwenbuild, const char *s)
Definition gwenbuild.c:119
const char * GWBUILD_GetHostArch()
Definition gwenbuild.c:912
void GWBUILD_AddFlags(GWENBUILD *gwenbuild, uint32_t f)
Definition gwenbuild.c:98
struct GWENBUILD GWENBUILD
Definition gwenbuild.h:15
#define GWENBUILD_FLAGS_STATIC
Definition gwenbuild.h:33
GWB_KEYVALUEPAIR * GWB_KeyValuePair_new(const char *key, const char *value)
struct GWB_KEYVALUEPAIR GWB_KEYVALUEPAIR
GWB_PROJECT * GWB_Parser_ReadBuildTree(GWENBUILD *gwbuild, GWB_CONTEXT *currentContext, const char *srcDir, GWB_KEYVALUEPAIR_LIST *givenOptionList)
Definition parser.c:60
GWB_CONTEXT * GWB_Project_GetRootContext(const GWB_PROJECT *project)
Definition project.c:226
void GWB_Project_Dump(const GWB_PROJECT *project, int indent, int fullDump)
Definition project.c:538
struct GWB_PROJECT GWB_PROJECT
Definition project.h:14
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition stringlist.c:62
GWEN_STRINGLIST * GWEN_StringList_fromString2(const char *str, const char *delimiters, int checkDouble, uint32_t flags)
Definition stringlist.c:818
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition stringlist.c:245
const char * GWEN_StringList_StringAt(const GWEN_STRINGLIST *sl, int idx)
Definition stringlist.c:730
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition stringlist.c:50
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition stringlist.h:56
int GWEN_SyncIo_Helper_WriteFile(const char *fName, const uint8_t *ptrSource, uint64_t lenSource)
Definition syncio.c:586
#define GWEN_TEXT_FLAGS_DEL_QUOTES
Definition text.h:49
#define GWEN_TEXT_FLAGS_CHECK_BACKSLASH
Definition text.h:50
int GWB_Utils_WriteProjectInfoToFile(const GWB_PROJECT *project, const char *fileName)
Definition utils.c:584
int GWB_Utils_WriteProjectToFile(const GWB_PROJECT *project, const char *fileName)
Definition utils.c:416
int GWB_Utils_WriteContextTreeToFile(const GWB_CONTEXT *ctx, const char *fileName)
Definition utils.c:439
int GWB_Utils_WriteInstallFileList(const GWB_PROJECT *project, const char *fileName)
Definition utils.c:154
int GWB_Utils_WriteBuildFileList(const GWENBUILD *gwenbuild, const char *fileName)
Definition utils.c:108
int GWB_Utils_WriteProjectFileList(const GWB_PROJECT *project, const char *fileName)
Definition utils.c:44