From 4c6e540b4b8a74b11e805a3e44ae7f7ebfba85e3 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Tue, 1 Oct 2013 16:25:48 +0800 Subject: [PATCH] Tools/udibuild - Implemented linking --- Tools/udibuild/src/build.c | 54 ++++++++++++++++++++++----- Tools/udibuild/src/include/common.h | 20 ++++++++++ Tools/udibuild/src/include/udiprops.h | 2 + Tools/udibuild/src/main.c | 2 +- Tools/udibuild/src/udiprops.c | 21 ++++++++--- 5 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 Tools/udibuild/src/include/common.h diff --git a/Tools/udibuild/src/build.c b/Tools/udibuild/src/build.c index b070c373..2ccd2b2a 100644 --- a/Tools/udibuild/src/build.c +++ b/Tools/udibuild/src/build.c @@ -7,15 +7,13 @@ */ #include #include +#include +#include // 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) @@ -24,7 +22,7 @@ int Build_CompileFile(tIniFile *opts, const char *abi, tUdiprops *udiprops, tUdi 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 @@ -32,7 +30,7 @@ int Build_CompileFile(tIniFile *opts, const char *abi, tUdiprops *udiprops, tUdi // - 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, @@ -49,10 +47,48 @@ int Build_CompileFile(tIniFile *opts, const char *abi, tUdiprops *udiprops, tUdi 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); } + diff --git a/Tools/udibuild/src/include/common.h b/Tools/udibuild/src/include/common.h new file mode 100644 index 00000000..0cb419b6 --- /dev/null +++ b/Tools/udibuild/src/include/common.h @@ -0,0 +1,20 @@ +/* + * udibuild - UDI Compilation Utility + * - By John Hodge (thePowersGang) + * + * common.h + * - Common helpers + */ +#ifndef _COMMON_H_ +#define _COMMON_H_ + +#include + +#ifndef __GNUC__ +# define __attribute__(...) +#endif + +extern char *mkstr(const char *fmt, ...) __attribute__((format(printf,1,2))); + +#endif + diff --git a/Tools/udibuild/src/include/udiprops.h b/Tools/udibuild/src/include/udiprops.h index 5849ddc6..fa22d66b 100644 --- a/Tools/udibuild/src/include/udiprops.h +++ b/Tools/udibuild/src/include/udiprops.h @@ -20,6 +20,8 @@ struct sUdiprops_Srcfile struct sUdiprops { + const char *ModuleName; + int nSourceFiles; tUdiprops_Srcfile **SourceFiles; }; diff --git a/Tools/udibuild/src/main.c b/Tools/udibuild/src/main.c index 51ecbb58..1f43cec3 100644 --- a/Tools/udibuild/src/main.c +++ b/Tools/udibuild/src/main.c @@ -87,7 +87,7 @@ int main(int argc, char *argv[]) assert(gpUdipropsBuild->SourceFiles); // Do build - for( int i = 0; gpUdipropsBuild->SourceFiles[i]; i ++ ) + for( int i = 0; i < gpUdipropsBuild->nSourceFiles; i ++ ) { int rv = Build_CompileFile(gpOptions, gsOpt_ABIName, gpUdipropsBuild, gpUdipropsBuild->SourceFiles[i]); diff --git a/Tools/udibuild/src/udiprops.c b/Tools/udibuild/src/udiprops.c index c1ddf1c0..6b158f74 100644 --- a/Tools/udibuild/src/udiprops.c +++ b/Tools/udibuild/src/udiprops.c @@ -53,6 +53,12 @@ static void rtrim(char *str) *--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"); @@ -77,7 +83,9 @@ tUdiprops *Udiprops_LoadBuild(const char *Filename) 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 @@ -89,21 +97,24 @@ tUdiprops *Udiprops_LoadBuild(const char *Filename) 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 -- 2.20.1