*/
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h> // mkdir
#include "include/build.h"
#include "include/common.h"
-#ifndef __GNUC__
-# define __attribute__(...)
-#endif
-
// === PROTOTYPES ===
-char *get_objfile(tIniFile *opts, const char *srcfile);
+char *get_objfile(tIniFile *opts, const char *abi, const char *srcfile);
// === CODE ===
int Build_CompileFile(tIniFile *opts, const char *abi, tUdiprops *udiprops, tUdiprops_Srcfile *srcfile)
const char *cc_prog = IniFile_Get(opts, abi, "CC", NULL);
if( !cc_prog ) {
fprintf(stderr, "No 'CC' defined for ABI %s\n", abi);
- return 1;
+ return -1;
}
// Build up compiler's command line
// - defines from udiprops
// - Object file is srcfile with .o appended
// > Place in 'obj/' dir?
- char *objfile = get_objfile(opts, srcfile->Filename);
+ char *objfile = get_objfile(opts, abi, srcfile->Filename);
char *cmd = mkstr("%s -DUDI_ABI_is_%s %s %s -c %s -o %s",
cc_prog,
abi,
int Build_LinkObjects(tIniFile *opts, const char *abi, tUdiprops *udiprops)
{
- return 0;
+ const char *linker = IniFile_Get(opts, abi, "LD", NULL);
+ if( !linker ) {
+ fprintf(stderr, "No 'LD' defined for ABI %s\n", abi);
+ return -1;
+ }
+
+ char *objfiles[udiprops->nSourceFiles];
+ size_t objfiles_len = 0;
+ for( int i = 0; i < udiprops->nSourceFiles; i ++ ) {
+ objfiles[i] = get_objfile(opts, abi, udiprops->SourceFiles[i]->Filename);
+ objfiles_len += strlen(objfiles[i])+1;
+ }
+
+ // Create command string
+ char *objfiles_str = malloc(objfiles_len);
+ objfiles_len = 0;
+ for( int i = 0; i < udiprops->nSourceFiles; i ++ ) {
+ strcpy(objfiles_str + objfiles_len, objfiles[i]);
+ objfiles_len += strlen(objfiles[i])+1;
+ objfiles_str[objfiles_len-1] = ' ';
+ free( objfiles[i] );
+ }
+ objfiles_str[objfiles_len-1] = '\0';
+
+ mkdir("bin", 0755);
+ char *abidir = mkstr("bin/%s", abi);
+ mkdir(abidir, 0755);
+ free(abidir);
+
+ char *cmd = mkstr("%s %s -o bin/%s/%s -r %s",
+ linker, IniFile_Get(opts, abi, "LDFLAGS", ""),
+ abi, udiprops->ModuleName, objfiles_str);
+ printf("--- Linking: bin/%s/%s\n", abi, udiprops->ModuleName);
+ int rv = system(cmd);
+ free(cmd);
+ free(objfiles_str);
+
+ return rv;
}
-char *get_objfile(tIniFile *opts, const char *srcfile)
+char *get_objfile(tIniFile *opts, const char *abi, const char *srcfile)
{
return mkstr("%s.o", srcfile);
}
+
*--pos = '\0';
}
+static char *my_strdup(const char *str)
+{
+ char *ret = malloc(strlen(str)+1);
+ return strcpy(ret, str);
+}
+
tUdiprops *Udiprops_LoadBuild(const char *Filename)
{
FILE *fp = fopen(Filename, "r");
if( !str[0] ) continue ;
int sym = _get_token_sym(str, (const char**)&str,
- "source_files", "compile_options", "source_requires", NULL);
+ "source_files", "compile_options", "source_requires",
+ "module",
+ NULL);
switch(sym)
{
case 0: // source_files
strcpy((char*)srcfile->Filename, file);
n_srcfiles ++;
- ret->SourceFiles = realloc(ret->SourceFiles, (n_srcfiles+1)*sizeof(void*));
+ ret->SourceFiles = realloc(ret->SourceFiles, n_srcfiles*sizeof(void*));
ret->SourceFiles[n_srcfiles-1] = srcfile;
- ret->SourceFiles[n_srcfiles] = NULL;
}
break;
case 1: // compile_options
- current_compile_opts = malloc(strlen(str)+1);
- strcpy(current_compile_opts, str);
+ current_compile_opts = my_strdup(str);
break;
case 2: // source_requires
// TODO: Use source_requires
break;
+ case 3: // module
+ ret->ModuleName = my_strdup(str);
+ break;
}
}
+ ret->nSourceFiles = n_srcfiles;
+
// "Intentional" memory leak
// - current_compile_opts not freed, and shared between srcfiles
// - If two compile_options statements appear in a row, one is definitely leaked