ecere/Desktop3D: (WIP) Attempts to fix full screen mode
[sdk] / epj2make / epj2make.ec
1 #ifdef ECERE_STATIC
2 public import static "ecere"
3 #else
4 public import "ecere"
5 #endif
6
7 import "Project"
8
9 #if defined(__WIN32__)
10 define pathListSep = ";";
11 #else
12 define pathListSep = ":";
13 #endif
14
15 #if defined(_DEBUG) && defined(__WIN32__)
16 extern int getch(void);
17 #endif
18
19 void ParseDirList(char * string, Container<String> list)
20 {
21    int c;
22    byte * tokens[256];
23    int numTokens = TokenizeWith(string, sizeof(tokens) / sizeof(byte *), tokens, ";", false);
24    list.Free();
25    for(c = 0; c < numTokens; c++)
26       list.Add(CopyString(tokens[c]));
27 }
28
29 // NOTE: FileMonitors are not to be used by an Application class. globalSystem is not set up properly otherwise.
30 // Mantis ticket #545 was filed regarding this.
31 class epj2makeApp : GuiApplication
32 {
33    void Main()
34    {
35       int c;
36       bool valid = true;
37       char * configName = null;
38       char * epjPath = null;
39       char * makePath = null;
40       /*
41       char ** argv = null;
42       int argc = 0;
43       */
44
45       Platform targetPlatform = GetRuntimePlatform();
46
47       Project project = null;
48
49       CompilerConfig optionsCompiler { };
50
51       bool noGlobalSettings = false;
52       bool noResources = false;
53       bool noWarnings = false;
54       char * overrideObjDir = null;
55       char * includemkPath = null;
56
57       /*
58       for(c = 0; c < this.argc; c++)
59       {
60          char * arg = this.argv[c];
61          int argLen = strlen(arg);
62
63          argv = renew argv char *[argc + 1];
64          argv[argc] = new char[argLen + 1];
65          strcpy(argv[argc], arg);
66
67          while(argv[argc][argLen - 1] == '\\' && c < this.argc-1)
68          {
69             int len;
70
71             c++;
72             arg = this.argv[c];
73             len = strlen(arg);
74             argv[argc] = renew argv[argc] char[argLen + len + 1];
75
76             argv[argc][argLen - 1] = ' ';
77             strcpy(argv[argc] + argLen, arg);
78             argLen += len;
79          }
80          argc++;
81       }
82       */
83
84       for(c = 1; c < argc; c++)
85       {
86          char * arg = argv[c];
87          if(arg[0] == '-')
88          {
89             if(!strcmpi(arg+1, "make"))
90             {
91                if(++c < argc)
92                   optionsCompiler.makeCommand = argv[c];
93                else
94                   valid = false;
95             }
96             else if(!strcmpi(arg+1, "cpp"))
97             {
98                if(++c < argc)
99                   optionsCompiler.cppCommand = argv[c];
100                else
101                   valid = false;
102             }
103             else if(!strcmpi(arg+1, "cc"))
104             {
105                if(++c < argc)
106                   optionsCompiler.ccCommand = argv[c];
107                else
108                   valid = false;
109             }
110             else if(!strcmpi(arg+1, "ecp"))
111             {
112                if(++c < argc)
113                   optionsCompiler.ecpCommand = argv[c];
114                else
115                   valid = false;
116             }
117             else if(!strcmpi(arg+1, "ecc"))
118             {
119                if(++c < argc)
120                   optionsCompiler.eccCommand = argv[c];
121                else
122                   valid = false;
123             }
124             else if(!strcmpi(arg+1, "ecs"))
125             {
126                if(++c < argc)
127                   optionsCompiler.ecsCommand = argv[c];
128                else
129                   valid = false;
130             }
131             else if(!strcmpi(arg+1, "ear"))
132             {
133                if(++c < argc)
134                   optionsCompiler.earCommand = argv[c];
135                else
136                   valid = false;
137             }
138             else if(!strcmpi(arg+1, "noglobalsettings"))
139             {
140                noGlobalSettings = true;
141             }
142             else if(!strcmpi(arg+1, "noresources"))
143             {
144                noResources = true;
145             }
146             else if(!strcmpi(arg+1, "includemk"))
147             {
148                if(++c < argc)
149                   includemkPath = argv[c];
150                else
151                   valid = false;
152             }
153             else if(arg[1] == 'w' && !arg[2])
154             {
155                noWarnings = true;
156             }
157             else if(arg[1] == 'c' && !arg[2])
158             {
159                if(++c < argc)
160                {
161                   int argLen = strlen(argv[c]);
162                   configName = new char[argLen + 1];
163                   strcpy(configName, argv[c]);
164                }
165                else
166                   valid = false;
167             }
168             else if(arg[1] == 't' && !arg[2])
169             {
170                if(++c < argc)
171                   targetPlatform = argv[c];
172                else
173                   valid = false;
174             }
175             else if(arg[1] == 'o')
176             {
177                if(++c < argc)
178                {
179                   int argLen = strlen(argv[c]);
180                   makePath = new char[argLen + 1];
181                   strcpy(makePath, argv[c]);
182                }
183                else
184                   valid = false;
185             }
186             else if(arg[1] == 'i')
187             {
188                if(++c < argc)
189                   ParseDirList(argv[c], optionsCompiler.includeDirs);
190                else
191                   valid = false;
192             }
193             else if(arg[1] == 'l')
194             {
195                if(++c < argc)
196                   ParseDirList(argv[c], optionsCompiler.libraryDirs);
197                else
198                   valid = false;
199             }
200             else if(arg[1] == 'd' && !arg[2])
201             {
202                if(++c < argc)
203                   overrideObjDir = argv[c];
204                else
205                   valid = false;
206             }
207             else
208             {
209                valid = false;
210                printf($"invalid option: %s\n", arg);
211             }
212          }
213          else
214          {
215             if(!epjPath)
216             {
217                int argLen = strlen(arg);
218                epjPath = new char[argLen + 1];
219                strcpy(epjPath, arg);
220                c++;
221             }
222             else
223                valid = false;
224          }
225       }
226       if(!epjPath)
227          valid = false;
228
229       if(!valid)
230       {
231          printf($"Syntax:\n");
232          printf($"   epj2make [-t <target platform>] [-c <configuration>] [toolchain] [directories] [options] [-o <output>] <input>\n");
233          printf($"      toolchain:\n");
234          printf($"         [-make <make tool>]\n");
235          printf($"         [-cpp <c preprocessor>]\n");
236          printf($"         [-cc <c compiler>]\n");
237          printf($"         [-ecp <eC preprocessor>]\n");
238          printf($"         [-ecc <eC compiler>]\n");
239          printf($"         [-ecs <eC symbol generator>]\n");
240          printf($"         [-ear <Ecere Archiver>]\n");
241          printf($"      directories:\n");
242          printf($"         [-i <include dir[;inc dir[...]]>]\n");
243          printf($"         [-l <library dir[;lib dir[...]]>]\n");
244          printf($"      options:\n");
245          printf($"         [-noglobalsettings]\n");
246          printf($"         [-noresources]\n");
247          printf($"         [-d <intermediate objects directory>]\n");
248          printf($"         [-includemk <crossplatform.mk path>]\n");
249       }
250       else
251       {
252          if(FileExists(epjPath).isFile)
253          {
254             char extension[MAX_EXTENSION] = "";
255             GetExtension(epjPath, extension);
256             strlwr(extension);
257             if(!strcmp(extension, ProjectExtension))
258             {
259                if(noGlobalSettings)
260                {
261                   defaultCompiler = MakeDefaultCompiler("Default", true);
262                   delete ideSettings;
263                }
264                else
265                {
266                   char * compiler = getenv("COMPILER");
267                   if(!compiler) compiler = "Default";
268                   settingsContainer.Load();
269                   //incref ideSettings;
270                   delete settingsContainer;
271
272       // TODO: Command line option to choose between the two
273       // or a command line option to not use global settings
274       //defaultCompiler = MakeDefaultCompiler();
275                   defaultCompiler = ideSettings.GetCompilerConfig(compiler);
276       // possible TODO: use the workspace to select the active compiler
277       // TODO: option to specify compiler name when using global settings
278                }
279
280                if(optionsCompiler.makeCommand)
281                   defaultCompiler.makeCommand = optionsCompiler.makeCommand;
282                if(optionsCompiler.cppCommand)
283                   defaultCompiler.cppCommand = optionsCompiler.cppCommand;
284                if(optionsCompiler.ccCommand)
285                   defaultCompiler.ccCommand = optionsCompiler.ccCommand;
286                if(optionsCompiler.ecpCommand)
287                   defaultCompiler.ecpCommand = optionsCompiler.ecpCommand;
288                if(optionsCompiler.eccCommand)
289                   defaultCompiler.eccCommand = optionsCompiler.eccCommand;
290                if(optionsCompiler.ecsCommand)
291                   defaultCompiler.ecsCommand = optionsCompiler.ecsCommand;
292                if(optionsCompiler.earCommand)
293                   defaultCompiler.earCommand = optionsCompiler.earCommand;
294                // TODO: Pass/combine/override the include and library dirs
295                for(dir : optionsCompiler.includeDirs)
296                   defaultCompiler.includeDirs.Add(dir);
297                for(dir : optionsCompiler.libraryDirs)
298                   defaultCompiler.libraryDirs.Add(dir);
299                delete optionsCompiler;
300
301                project = LoadProject(epjPath, null);
302                if(project)
303                {
304                   ProjectConfig defaultConfig = null;
305                   if(configName)
306                   {
307                      valid = false;
308                      for(config : project.configurations)
309                      {
310                         if(!strcmpi(configName, config.name))
311                         {
312                            project.config = config;
313                            valid = true;
314                            break;
315                         }
316                      }
317                      if(!valid)
318                         printf($"Error: Project configuration (%s) was not found.\n", configName);
319                   }
320                   else
321                   {
322                      ProjectConfig releaseConfig = null;
323                      for(config : project.configurations)
324                      {
325                         if(!strcmpi(config.name, "Release"))
326                         {
327                            releaseConfig = config;
328                            break;
329                         }
330                      }
331                      if(!releaseConfig && project.configurations.count)
332                      {
333                         releaseConfig = project.configurations[0];
334                         printf($"Notice: Project configuration (%s) will be used.\n", releaseConfig.name);
335                      }
336
337                      if(releaseConfig)
338                      {
339                         project.config = releaseConfig;
340                         if(overrideObjDir)
341                         {
342                            delete releaseConfig.options.targetDirectory;
343                            releaseConfig.options.targetDirectory = CopyString(overrideObjDir);
344                            delete releaseConfig.options.objectsDirectory;
345                            releaseConfig.options.objectsDirectory = CopyString(overrideObjDir);
346                         }
347                         if(noWarnings)
348                            releaseConfig.options.warnings = none;
349                      }
350                      else if(overrideObjDir)
351                      {
352                         delete project.options.targetDirectory;
353                         project.options.targetDirectory = CopyString(overrideObjDir);
354                         delete project.options.objectsDirectory;
355                         project.options.objectsDirectory = CopyString(overrideObjDir);
356                      }
357                      if(noWarnings)
358                         project.options.warnings = none;
359                   }
360                   if(valid)
361                   {
362                      project.GenerateCompilerCf(defaultCompiler, project.topNode.ContainsFilesWithExtension("ec", project.config));
363                      project.GenerateCrossPlatformMk(null);
364                      if(project.GenerateMakefile(makePath, noResources, includemkPath, project.config))
365                      {
366                         if(makePath)
367                            printf("%s\n", makePath);
368                      }
369                   }
370
371                   if(noGlobalSettings)
372                      delete defaultCompiler;
373
374                   delete defaultConfig;
375                   delete project;
376                }
377                else
378                   printf($"Error: Unable to open project file (%s) due to unknown error.\n", epjPath);
379             }
380          }
381          else
382             printf($"Error: Input file (%s) does not exist.\n", epjPath);
383       }
384
385       //if(optionsCompiler) // how to fix those leaks?
386       delete optionsCompiler;
387
388       delete configName;
389       delete epjPath;
390       delete makePath;
391
392       // Why do we need to free this here?
393       delete defaultCompiler;
394
395       /*
396       for(c = 0; c<argc; c++)
397          delete argv[c];
398       delete argv;
399       */
400
401       // CheckMemory();
402       delete ideSettings;
403 #if defined(_DEBUG) && defined(__WIN32__)
404       getch();
405 #endif
406    }
407 }