gwenhywfar  5.7.2
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 
20 #include <gwenhywfar/debug.h>
21 #include <gwenhywfar/directory.h>
22 #include <gwenhywfar/text.h>
23 
24 #include <sys/stat.h>
25 #include <errno.h>
26 #include <unistd.h>
27 
28 
29 
30 static int _prepareContextForSetup(GWB_CONTEXT *firstContext, GWEN_DB_NODE *dbArgs);
31 static void _determineTarget(GWB_CONTEXT *context, GWEN_DB_NODE *dbArgs);
32 static int _determineTools(GWB_CONTEXT *context, GWEN_DB_NODE *dbArgs);
33 static int _getAllToolPaths(GWEN_DB_NODE *dbVars, const char *sCompileTarget, const GWEN_STRINGLIST *sl);
34 static int _getToolPath(GWEN_DB_NODE *dbVars, const char *sTarget, const GWEN_STRINGLIST *sl,
35  const char *sCommand, const char *sEnvVar, const char *sVarName);
37 static void _copyEnvironmentVariableToDb(GWEN_DB_NODE *db, const char *envName, const char *dbVarName);
38 static GWB_KEYVALUEPAIR_LIST *_readOptionsFromDb(GWEN_DB_NODE *db);
39 static int _writeStaticLibHelper(const char *fileName);
40 
41 
42 
43 
44 int GWB_Setup(GWEN_DB_NODE *dbArgs)
45 {
46  GWENBUILD *gwenbuild;
47  GWB_CONTEXT *firstContext;
48  GWB_PROJECT *project;
49  GWB_BUILD_CONTEXT *buildCtx;
50  const char *folder;
51  int doDump;
52  GWB_KEYVALUEPAIR_LIST *givenOptionList;
53  int rv;
54 
55  doDump=GWEN_DB_GetIntValue(dbArgs, "dump", 0, 0);
56 
57  folder=GWEN_DB_GetCharValue(dbArgs, "folder", 0, NULL);
58  if (!(folder && *folder)) {
59  fprintf(stderr, "ERROR: Folder needed.\n");
60  return 1;
61  }
62  if (strcasecmp(folder, ".")==0) {
63  fprintf(stderr, "ERROR: Only building outside source folder supported.\n");
64  return 1;
65  }
66 
67  givenOptionList=_readOptionsFromDb(dbArgs);
68 
69 
70  gwenbuild=GWBUILD_new();
71  if (GWEN_DB_GetIntValue(dbArgs, "static", 0, 0))
73 
74  firstContext=GWB_Context_new(gwenbuild);
75  rv=_prepareContextForSetup(firstContext, dbArgs);
76  if (rv<0) {
77  fprintf(stderr, "ERROR: Error preparing first context.\n");
78  return 2;
79  }
80 
81  project=GWB_Parser_ReadBuildTree(gwenbuild, firstContext, folder, givenOptionList);
82  if (project==NULL) {
83  fprintf(stderr, "ERROR: Error reading build files.\n");
84  return 2;
85  }
86 
88  if (rv<0) {
89  fprintf(stderr, "ERROR: Error making builders for targets.\n");
90  return 2;
91  }
92 
93  buildCtx=GWBUILD_MakeBuildCommands(project);
94  if (buildCtx==NULL) {
95  fprintf(stderr, "ERROR: Could not generate build commands.\n");
96  return 2;
97  }
98 
99  rv=GWB_BuildCtx_WriteToXmlFile(buildCtx, ".gwbuild.ctx");
100  if (rv<0) {
101  fprintf(stderr, "ERROR: Error writing build context file.\n");
102  return 3;
103  }
104 
105  rv=GWB_Utils_WriteProjectFileList(project, ".gwbuild.files");
106  if (rv<0) {
107  fprintf(stderr, "ERROR: Error writing file list file.\n");
108  return 3;
109  }
110 
111  GWB_Utils_WriteBuildFileList(gwenbuild, ".gwbuild.buildfiles");
112 
113  rv=GWEN_DB_WriteFile(dbArgs, ".gwbuild.args", GWEN_DB_FLAGS_DEFAULT);
114  if (rv<0) {
115  fprintf(stderr, "ERROR: Error writing file list file.\n");
116  return 3;
117  }
118 
119  rv=GWB_Utils_WriteInstallFileList(project, ".gwbuild.installfiles");
120  if (rv<0) {
121  fprintf(stderr, "ERROR: Error writing install file list.\n");
122  return 3;
123  }
124 
125 #if 0
126  rv=GWB_Utils_WriteProjectToFile(project, ".gwbuild.project");
127  if (rv<0) {
128  fprintf(stderr, "ERROR: Error writing project to file.\n");
129  return 3;
130  }
131 #endif
132 
133  rv=GWB_Utils_WriteProjectInfoToFile(project, ".gwbuild.projectinfo");
134  if (rv<0) {
135  fprintf(stderr, "ERROR: Error writing project info to file.\n");
136  return 3;
137  }
138 
139 
141  ".gwbuild.ctxtree");
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 
159 int 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);
168  GWEN_DB_Group_free(db);
169  return rv;
170  }
171 
172  rv=GWB_Setup(db);
173  if (rv!=0) {
174  DBG_INFO(NULL, "here (%d)", rv);
175  GWEN_DB_Group_free(db);
176  return rv;
177  }
178  GWEN_DB_Group_free(db);
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 
214  dbVars=GWB_Context_GetVars(context);
215 
216  gwenbuild=GWB_Context_GetGwenbuild(context);
217 
218  sTarget=GWEN_DB_GetCharValue(dbArgs, "crossCompileFor", 0, NULL);
219  if (sTarget) {
220  s=GWBUILD_GetArchFromTriplet(sTarget);
221  GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "GWBUILD_ARCH", s);
222  sTargetSystem=GWBUILD_GetSystemFromTriplet(sTarget);
223  }
224  else {
226  sTargetSystem=GWBUILD_GetHostSystem();
227  }
228 
229  if (GWBUILD_GetFlags(gwenbuild) & GWENBUILD_FLAGS_STATIC)
230  GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "GWBUILD_LIBTYPE", "staticlib");
231  else
232  GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "GWBUILD_LIBTYPE", "sharedlib");
233 
234  GWEN_DB_SetCharValue(dbVars, GWEN_DB_FLAGS_OVERWRITE_VARS, "GWBUILD_SYSTEM", sTargetSystem);
235  GWBUILD_SetTargetSystem(gwenbuild, sTargetSystem);
236  GWBUILD_SetTargetIsWindows(gwenbuild, (strcasecmp(sTargetSystem, "windows")==0)?1:0);
237 }
238 
239 
240 
242 {
243  GWEN_DB_NODE *dbVars;
244  const char *sTarget;
245  GWEN_STRINGLIST *sl;
246  int rv;
247 
248  dbVars=GWB_Context_GetVars(context);
249  sTarget=GWEN_DB_GetCharValue(dbArgs, "crossCompileFor", 0, NULL);
250 
252  if (sl==NULL)
253  sl=GWEN_StringList_new();
254 
255  GWEN_StringList_AppendString(sl, "/usr/local/bin", 0, 1);
256  GWEN_StringList_AppendString(sl, "/usr/bin", 0, 1);
257  GWEN_StringList_AppendString(sl, "/bin", 0, 1);
258 
259  rv=_getAllToolPaths(dbVars, sTarget, sl);
260  if (rv<0) {
261  DBG_INFO(NULL, "here (%d)", rv);
263  return rv;
264  }
266 
267  return 0;
268 }
269 
270 
271 
272 int _getAllToolPaths(GWEN_DB_NODE *dbVars, const char *sCompileTarget, const GWEN_STRINGLIST *sl)
273 {
274  int rv;
275 
276  rv=_getToolPath(dbVars, sCompileTarget, sl, "gcc", "CC", "GWBUILD_TOOL_CC");
277  if (rv<0)
278  return rv;
279 
280  rv=_getToolPath(dbVars, sCompileTarget, sl, "g++", "CXX", "GWBUILD_TOOL_CXX");
281  if (rv<0)
282  return rv;
283 
284  rv=_getToolPath(dbVars, sCompileTarget, sl, "ld", "LD", "GWBUILD_TOOL_LD");
285  if (rv<0)
286  return rv;
287 
288  rv=_getToolPath(dbVars, sCompileTarget, sl, "ar", "AR", "GWBUILD_TOOL_AR");
289  if (rv<0)
290  return rv;
291 
292  rv=_getToolPath(dbVars, sCompileTarget, sl, "ranlib", "RANLIB", "GWBUILD_TOOL_RANLIB");
293  if (rv<0)
294  return rv;
295 
296  rv=_getToolPath(dbVars, NULL, sl, "typemaker2", "TYPEMAKER2", "GWBUILD_TOOL_TYPEMAKER2");
297  if (rv<0)
298  return rv;
299 
300 
301  return 0;
302 }
303 
304 
305 
306 int _getToolPath(GWEN_DB_NODE *dbVars, const char *sCompileTarget, const GWEN_STRINGLIST *sl,
307  const char *sCommand, const char *sEnvVar, const char *sVarName)
308 {
309  GWEN_BUFFER *fbufIn;
310  GWEN_BUFFER *fbufOut;
311  const char *s;
312  int rv;
313 
314  fbufIn=GWEN_Buffer_new(0, 256, 0, 1);
315 
316  if (sCompileTarget && *sCompileTarget) {
317  GWEN_Buffer_AppendString(fbufIn, sCompileTarget);
318  GWEN_Buffer_AppendString(fbufIn, "-");
319  }
320 
321  s=getenv(sEnvVar);
322  if (s)
323  GWEN_Buffer_AppendString(fbufIn, s);
324  else
325  GWEN_Buffer_AppendString(fbufIn, sCommand);
326 
327  fbufOut=GWEN_Buffer_new(0, 256, 0, 1);
328  rv=GWEN_Directory_FindFileInPaths(sl, GWEN_Buffer_GetStart(fbufIn), fbufOut);
329  if (rv<0) {
330  DBG_ERROR(NULL, "Tool \"%s\" not available (%d)", GWEN_Buffer_GetStart(fbufIn), rv);
331  GWEN_Buffer_free(fbufOut);
332  GWEN_Buffer_free(fbufIn);
333  return rv;
334  }
335 
337  GWEN_Buffer_free(fbufOut);
338  GWEN_Buffer_free(fbufIn);
339  return 0;
340 }
341 
342 
343 
345 {
346  _copyEnvironmentVariableToDb(db, "CFLAGS", "CFLAGS");
347  _copyEnvironmentVariableToDb(db, "CXXFLAGS", "CXXFLAGS");
348  _copyEnvironmentVariableToDb(db, "CPPFLAGS", "CPPFLAGS");
349  _copyEnvironmentVariableToDb(db, "LDFLAGS", "LDFLAGS");
350  _copyEnvironmentVariableToDb(db, "TM2FLAGS", "TM2FLAGS");
351 }
352 
353 
354 
355 
356 
357 void _copyEnvironmentVariableToDb(GWEN_DB_NODE *db, const char *envName, const char *dbVarName)
358 {
359  const char *s;
360 
361  s=getenv(envName);
362  if (s && *s)
364 }
365 
366 
367 
368 GWB_KEYVALUEPAIR_LIST *_readOptionsFromDb(GWEN_DB_NODE *db)
369 {
370  int i;
371  GWB_KEYVALUEPAIR_LIST *kvpList;
372 
373  kvpList=GWB_KeyValuePair_List_new();
374  for (i=0; i<100; i++) {
375  const char *sOption;
376  GWEN_STRINGLIST *sl;
377 
378  sOption=GWEN_DB_GetCharValue(db, "option", i, NULL);
379  if (sOption==NULL)
380  break;
381 
383  if (sl) {
384  const char *name;
385  const char *value;
386 
387  name=GWEN_StringList_StringAt(sl, 0);
388  value=GWEN_StringList_StringAt(sl, 1);
389  if (name) {
390  GWB_KEYVALUEPAIR *kvp;
391 
392  kvp=GWB_KeyValuePair_new(name, value);
393  GWB_KeyValuePair_List_Add(kvp, kvpList);
394  }
396  }
397  } /* for */
398 
399  if (GWB_KeyValuePair_List_GetCount(kvpList)==0) {
400  GWB_KeyValuePair_List_free(kvpList);
401  return NULL;
402  }
403 
404  return kvpList;
405 }
406 
407 
408 
409 int _writeStaticLibHelper(const char *fileName)
410 {
411  int rv;
412  static char *staticLibHelperContent=
413  "#!/bin/sh\n"
414  "\n"
415  "TOOL=$1\n"
416  "LIB=$2\n"
417  "\n"
418  "$TOOL -t $LIB | xargs ar rvs $LIB.new && mv -v $LIB.new $LIB";
419 
420  unlink(fileName);
421  rv=GWEN_SyncIo_Helper_WriteFile(fileName, (const uint8_t*) staticLibHelperContent, strlen(staticLibHelperContent));
422  if (rv<0) {
423  DBG_ERROR(NULL, "Error writing static lib helper to \"%s\" (%d)", fileName, rv);
424  return rv;
425  }
426  if (chmod(fileName, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP)==-1) {
427  DBG_ERROR(NULL, "Error on chmod(%s): %s", fileName, strerror(errno));
428  return GWEN_ERROR_GENERIC;
429  }
430 
431  return 0;
432 }
433 
434 
435 
436 
437 
static int _prepareContextForSetup(GWB_CONTEXT *firstContext, GWEN_DB_NODE *dbArgs)
Definition: c_setup.c:186
GWEN_STRINGLIST * GWEN_StringList_fromString2(const char *str, const char *delimiters, int checkDouble, uint32_t flags)
Definition: stringlist.c:801
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
static int _getAllToolPaths(GWEN_DB_NODE *dbVars, const char *sCompileTarget, const GWEN_STRINGLIST *sl)
Definition: c_setup.c:272
const char * GWBUILD_GetHostArch()
Definition: gwenbuild.c:897
struct GWB_CONTEXT GWB_CONTEXT
Definition: context.h:17
#define GWEN_DB_FLAGS_OVERWRITE_VARS
Definition: db.h:121
int GWB_Setup(GWEN_DB_NODE *dbArgs)
Definition: c_setup.c:44
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
int GWB_RepeatLastSetup(const char *fileName)
Definition: c_setup.c:159
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition: db.c:421
int GWB_Utils_WriteInstallFileList(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:149
GWENBUILD * GWBUILD_new(void)
Definition: gwenbuild.c:60
static int _determineTools(GWB_CONTEXT *context, GWEN_DB_NODE *dbArgs)
Definition: c_setup.c:241
struct GWB_BUILD_CONTEXT GWB_BUILD_CONTEXT
Definition: buildctx.h:16
void GWB_Project_Dump(const GWB_PROJECT *project, int indent, int fullDump)
Definition: project.c:523
#define NULL
Definition: binreloc.c:300
const char * GWBUILD_GetHostSystem()
Definition: gwenbuild.c:945
#define GWENBUILD_FLAGS_STATIC
Definition: gwenbuild.h:31
void GWBUILD_AddFlags(GWENBUILD *gwenbuild, uint32_t f)
Definition: gwenbuild.c:98
struct GWB_PROJECT GWB_PROJECT
Definition: project.h:14
const char * GWBUILD_GetArchFromTriplet(const char *sTriplet)
Definition: gwenbuild.c:976
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
const char * GWEN_StringList_StringAt(const GWEN_STRINGLIST *sl, int idx)
Definition: stringlist.c:730
GWEN_STRINGLIST * GWBUILD_GetPathFromEnvironment()
Definition: gwenbuild.c:154
static void _determineTarget(GWB_CONTEXT *context, GWEN_DB_NODE *dbArgs)
Definition: c_setup.c:206
static int _writeStaticLibHelper(const char *fileName)
Definition: c_setup.c:409
void GWEN_StringList_free(GWEN_STRINGLIST *sl)
Definition: stringlist.c:62
GWEN_DB_NODE * GWB_Context_GetVars(const GWB_CONTEXT *ctx)
Definition: context.c:427
int GWB_Utils_WriteProjectToFile(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:406
int GWEN_StringList_AppendString(GWEN_STRINGLIST *sl, const char *s, int take, int checkDouble)
Definition: stringlist.c:245
int GWB_Utils_WriteProjectInfoToFile(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:538
GWB_CONTEXT * GWB_Context_new(GWENBUILD *gwenbuild)
Definition: context.c:34
GWENHYWFAR_API int GWEN_Directory_FindFileInPaths(const GWEN_STRINGLIST *paths, const char *filePath, GWEN_BUFFER *fbuf)
uint32_t GWBUILD_GetFlags(const GWENBUILD *gwenbuild)
Definition: gwenbuild.c:84
struct GWEN_STRINGLISTSTRUCT GWEN_STRINGLIST
Definition: stringlist.h:56
#define GWEN_ERROR_GENERIC
Definition: error.h:62
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:971
static void _copyEnvironmentVariableToDb(GWEN_DB_NODE *db, const char *envName, const char *dbVarName)
Definition: c_setup.c:357
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
GWB_PROJECT * GWB_Parser_ReadBuildTree(GWENBUILD *gwbuild, GWB_CONTEXT *currentContext, const char *srcDir, GWB_KEYVALUEPAIR_LIST *givenOptionList)
Definition: parser.c:56
GWB_BUILD_CONTEXT * GWBUILD_MakeBuildCommands(GWB_PROJECT *project)
Definition: gwenbuild.c:747
GWB_KEYVALUEPAIR * GWB_KeyValuePair_new(const char *key, const char *value)
Definition: keyvaluepair.c:34
int GWB_BuildCtx_WriteToXmlFile(const GWB_BUILD_CONTEXT *buildCtx, const char *fileName)
Definition: buildctx_xml.c:303
int GWBUILD_MakeBuildersForTargets(GWB_PROJECT *project)
Definition: gwenbuild.c:486
static GWB_KEYVALUEPAIR_LIST * _readOptionsFromDb(GWEN_DB_NODE *db)
Definition: c_setup.c:368
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
int GWB_Utils_WriteContextTreeToFile(const GWB_CONTEXT *ctx, const char *fileName)
Definition: utils.c:429
const char * GWBUILD_GetSystemFromTriplet(const char *sTriplet)
Definition: gwenbuild.c:988
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:997
void GWBUILD_SetTargetSystem(GWENBUILD *gwenbuild, const char *s)
Definition: gwenbuild.c:119
struct GWB_KEYVALUEPAIR GWB_KEYVALUEPAIR
Definition: keyvaluepair.h:19
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
#define GWEN_TEXT_FLAGS_DEL_QUOTES
Definition: text.h:49
GWENHYWFAR_API int GWEN_DB_ReadFile(GWEN_DB_NODE *n, const char *fname, uint32_t dbflags)
Definition: dbrw.c:1003
int GWB_Utils_WriteProjectFileList(const GWB_PROJECT *project, const char *fileName)
Definition: utils.c:39
int GWEN_DB_GetIntValue(GWEN_DB_NODE *n, const char *path, int idx, int defVal)
Definition: db.c:1163
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:173
GWENHYWFAR_API int GWEN_DB_WriteFile(GWEN_DB_NODE *n, const char *fname, uint32_t dbflags)
Definition: dbrw.c:535
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:306
#define GWEN_TEXT_FLAGS_CHECK_BACKSLASH
Definition: text.h:50
struct GWENBUILD GWENBUILD
Definition: gwenbuild.h:15
GWEN_STRINGLIST * GWEN_StringList_new(void)
Definition: stringlist.c:50
static void _copySomeEnvironmentVariablesToDb(GWEN_DB_NODE *db)
Definition: c_setup.c:344
GWB_CONTEXT * GWB_Project_GetRootContext(const GWB_PROJECT *project)
Definition: project.c:226
GWENBUILD * GWB_Context_GetGwenbuild(const GWB_CONTEXT *ctx)
Definition: context.c:117
int GWEN_SyncIo_Helper_WriteFile(const char *fName, const uint8_t *ptrSource, uint64_t lenSource)
Definition: syncio.c:586
void GWBUILD_SetTargetIsWindows(GWENBUILD *gwenbuild, int i)
Definition: gwenbuild.c:133
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
#define GWEN_DB_FLAGS_DEFAULT
Definition: db.h:168
int GWB_Utils_WriteBuildFileList(const GWENBUILD *gwenbuild, const char *fileName)
Definition: utils.c:103