Tools/udibuild - Implemented linking
[tpg/acess2.git] / Tools / udibuild / src / main.c
1 /*
2  * udibuild - UDI Compilation Utility
3  * - By John Hodge (thePowersGang)
4  *
5  * main.c
6  * - Core
7  */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>     // getopt
11 #include <getopt.h>
12 #include <string.h>     // strrchr
13 #include <assert.h>
14 #include "include/common.h"
15 #include "include/build.h"
16 #include "include/inifile.h"
17 #include "include/udiprops.h"
18
19 #ifdef __ACESS__
20 #define CONFIG_FILE     "/Acess/Conf/UDI/udibuild.ini"
21 #else
22 #define CONFIG_FILE     "/etc/udi/udibuild.ini"
23 #endif
24
25 // === PROTOTYPES ===
26  int    main(int argc, char *argv[]);
27  int    ParseArguments(int argc, char *argv[]);
28 void    Usage(const char *progname);
29
30 // === GLOBALS ===
31 const char *gsOpt_ConfigFile;
32 const char *gsOpt_WorkingDir;
33 const char *gsOpt_UdipropsFile;
34 const char *gsOpt_ABIName = "ia32";
35 tIniFile        *gpOptions;
36 tUdiprops       *gpUdipropsBuild;
37
38 // === CODE ===
39 int main(int argc, char *argv[])
40 {
41         if( ParseArguments(argc, argv) ) {
42                 return 1;
43         }
44
45         // Locate udibuild.ini
46         // 1. Check CWD
47         if( !gsOpt_ConfigFile ) {
48                 //if( file_exists("./udibuild.ini") )
49                 //{
50                 //      gsOpt_ConfigFile = "udibuild.ini";
51                 //}
52         }
53         // 2. Check program dir (if not invoked from PATH)
54         if( !gsOpt_ConfigFile && (argv[0][0] == '.' || argv[0][0] == '/') ) {
55                 char *last_slash = strrchr(argv[0], '/');
56                 if( last_slash ) {
57                         gsOpt_ConfigFile = mkstr("%.*s/udibuild.ini",
58                                 last_slash-argv[0], argv[0]);
59                 }
60                 //if( !file_exists(gsOpt_ConfigFile) ) {
61                 //      free(gsOpt_ConfigFile);
62                 //      gsOpt_ConfigFile = NULL;
63                 //}
64         }
65         // 3. Check ~/.config/udi/udibuild.ini
66         // 4. Check CONFIGNAME
67
68         // #. Oh well   
69         if( !gsOpt_ConfigFile ) {
70                 fprintf(stderr, "Can't locate udibuild.ini file, please specify using '-c'\n");
71                 exit(2);
72         }
73         
74         // Load udibuild.ini
75         gpOptions = IniFile_Load(gsOpt_ConfigFile);
76         assert(gpOptions);
77
78         // Change to working directory (-C <dir>)
79         if( gsOpt_WorkingDir )
80         {
81                 chdir(gsOpt_WorkingDir);
82         }
83
84         // Load udiprops
85         gpUdipropsBuild = Udiprops_LoadBuild( gsOpt_UdipropsFile ? gsOpt_UdipropsFile : "udiprops.txt" );
86         assert(gpUdipropsBuild);
87         assert(gpUdipropsBuild->SourceFiles);
88
89         // Do build
90         for( int i = 0; i < gpUdipropsBuild->nSourceFiles; i ++ )
91         {
92                 int rv = Build_CompileFile(gpOptions, gsOpt_ABIName, gpUdipropsBuild,
93                         gpUdipropsBuild->SourceFiles[i]);
94                 if( rv ) {
95                         fprintf(stderr, "*** Exit status: %i\n", rv);
96                         return rv;
97                 }
98         }
99         Build_LinkObjects(gpOptions, gsOpt_ABIName, gpUdipropsBuild);
100
101         return 0;
102 }
103
104 int ParseArguments(int argc, char *argv[])
105 {
106          int    opt;
107         while( (opt = getopt(argc, argv, "hC:c:f:a:")) != -1 )
108         {
109                 switch(opt)
110                 {
111                 case 'h':
112                         Usage(argv[0]);
113                         exit(0);
114                 case 'C':
115                         gsOpt_WorkingDir = optarg;
116                         break;
117                 case 'c':
118                         gsOpt_ConfigFile = optarg;
119                         break;
120                 case 'f':
121                         gsOpt_UdipropsFile = optarg;
122                         break;
123                 case 'a':
124                         gsOpt_ABIName = optarg;
125                         break;
126                 case '?':
127                         Usage(argv[0]);
128                         return 1;
129                 default:
130                         fprintf(stderr, "BUG: Unhandled optarg %i '%c'\n", opt, opt);
131                         break;
132                 }
133         }
134         return 0;
135 }
136
137 void Usage(const char *progname)
138 {
139         fprintf(stderr, "Usage: %s [-C workingdir] [-c udibuild.ini] [-f udiprops.txt] [-a abiname]\n",
140                 progname);
141         fprintf(stderr, "\n"
142                 "-C workingdir   : Change to the specified directory before looking for udiprops.txt\n"
143                 "-c udibuild.ini : Override the default udibuild config file\n"
144                 "-f udiprops.txt : Override the default udiprops file\n"
145                 "-a abiname      : Select a different ABI\n"
146                 "\n");
147 }
148
149 char *mkstr(const char *fmt, ...)
150 {
151         va_list args;
152         va_start(args, fmt);
153         size_t len = vsnprintf(NULL, 0, fmt, args);
154         va_end(args);
155         va_start(args, fmt);
156         char *ret = malloc(len+1);
157         vsnprintf(ret, len+1, fmt, args);
158         va_end(args);
159         return ret;
160 }
161

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