Tools/udibuild - Implemented linking
authorJohn Hodge <[email protected]>
Tue, 1 Oct 2013 08:25:48 +0000 (16:25 +0800)
committerJohn Hodge <[email protected]>
Tue, 1 Oct 2013 08:25:48 +0000 (16:25 +0800)
Tools/udibuild/src/build.c
Tools/udibuild/src/include/common.h [new file with mode: 0644]
Tools/udibuild/src/include/udiprops.h
Tools/udibuild/src/main.c
Tools/udibuild/src/udiprops.c

index b070c37..2ccd2b2 100644 (file)
@@ -7,15 +7,13 @@
  */
 #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)
@@ -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 (file)
index 0000000..0cb419b
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * udibuild - UDI Compilation Utility
+ * - By John Hodge (thePowersGang)
+ *
+ * common.h
+ * - Common helpers
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <stdarg.h>
+
+#ifndef __GNUC__
+# define __attribute__(...)
+#endif
+
+extern char    *mkstr(const char *fmt, ...) __attribute__((format(printf,1,2)));
+
+#endif
+
index 5849ddc..fa22d66 100644 (file)
@@ -20,6 +20,8 @@ struct sUdiprops_Srcfile
 
 struct sUdiprops
 {
+       const char      *ModuleName;
+        int    nSourceFiles;
        tUdiprops_Srcfile       **SourceFiles;
 };
 
index 51ecbb5..1f43cec 100644 (file)
@@ -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]);
index c1ddf1c..6b158f7 100644 (file)
@@ -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

UCC git Repository :: git.ucc.asn.au