1 /*-------------------------------------------------------------------------
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1999)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
36 // This is a bit messy because we define link ourself
37 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
42 // No unistd.h in Borland C++
43 extern int access (const char *, int);
49 extern int yyparse ();
51 FILE *srcFile; /* source file */
52 FILE *cdbFile = NULL; /* debugger information output file */
53 char *fullSrcFileName; /* full name for the source file */
54 char *srcFileName; /* source file name with the .c stripped */
55 char *moduleName; /* module name is srcFilename stripped of any path */
56 const char *preArgv[128]; /* pre-processor arguments */
58 struct optimize optimize;
59 struct options options;
60 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
61 short preProcOnly = 0;
63 char *linkOptions[128];
64 const char *asmOptions[128];
71 bool verboseExec = FALSE;
74 // In MSC VC6 default search path for exe's to path for this
76 char DefaultExePath[128];
78 /* Far functions, far data */
79 #define OPTION_LARGE_MODEL "-model-large"
80 /* Far functions, near data */
81 #define OPTION_MEDIUM_MODEL "-model-medium"
82 #define OPTION_SMALL_MODEL "-model-small"
83 #define OPTION_FLAT24_MODEL "-model-flat24"
84 #define OPTION_STACK_AUTO "-stack-auto"
85 #define OPTION_STACK_8BIT "-stack-8bit"
86 #define OPTION_STACK_10BIT "-stack-10bit"
87 #define OPTION_XSTACK "-xstack"
88 #define OPTION_GENERIC "-generic"
89 #define OPTION_NO_GCSE "-nogcse"
90 #define OPTION_NO_LOOP_INV "-noinvariant"
91 #define OPTION_NO_LOOP_IND "-noinduction"
92 #define OPTION_NO_JTBOUND "-nojtbound"
93 #define OPTION_NO_LOOPREV "-noloopreverse"
94 #define OPTION_XREGS "-regextend"
95 #define OPTION_COMP_ONLY "-compile-only"
96 #define OPTION_DUMP_RAW "-dumpraw"
97 #define OPTION_DUMP_GCSE "-dumpgcse"
98 #define OPTION_DUMP_LOOP "-dumploop"
99 #define OPTION_DUMP_KILL "-dumpdeadcode"
100 #define OPTION_DUMP_RANGE "-dumpliverange"
101 #define OPTION_DUMP_PACK "-dumpregpack"
102 #define OPTION_DUMP_RASSGN "-dumpregassign"
103 #define OPTION_DUMP_ALL "-dumpall"
104 #define OPTION_XRAM_LOC "-xram-loc"
105 #define OPTION_IRAM_SIZE "-iram-size"
106 #define OPTION_XSTACK_LOC "-xstack-loc"
107 #define OPTION_CODE_LOC "-code-loc"
108 #define OPTION_STACK_LOC "-stack-loc"
109 #define OPTION_DATA_LOC "-data-loc"
110 #define OPTION_IDATA_LOC "-idata-loc"
111 #define OPTION_PEEP_FILE "-peep-file"
112 #define OPTION_LIB_PATH "-lib-path"
113 #define OPTION_INTLONG_RENT "-int-long-reent"
114 #define OPTION_FLOAT_RENT "-float-reent"
115 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
116 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
117 #define OPTION_CYCLOMATIC "-cyclomatic"
118 #define OPTION_NOOVERLAY "-nooverlay"
119 #define OPTION_MAINRETURN "-main-return"
120 #define OPTION_NOPEEP "-no-peep"
121 #define OPTION_ASMPEEP "-peep-asm"
122 #define OPTION_DEBUG "-debug"
123 #define OPTION_NODEBUG "-nodebug"
124 #define OPTION_VERSION "-version"
125 #define OPTION_STKAFTRDATA "-stack-after-data"
126 #define OPTION_PREPROC_ONLY "-preprocessonly"
127 #define OPTION_C1_MODE "-c1mode"
128 #define OPTION_HELP "-help"
129 #define OPTION_CALLEE_SAVES "-callee-saves"
130 #define OPTION_NOSTDLIB "-nostdlib"
131 #define OPTION_NOSTDINC "-nostdinc"
132 #define OPTION_VERBOSE "-verbose"
133 static const char *_preCmd[] =
135 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
136 "$l", "$1", "$2", NULL
141 static PORT *_ports[] =
143 #if !OPT_DISABLE_MCS51
146 #if !OPT_DISABLE_GBZ80
155 #if !OPT_DISABLE_DS390
161 #if !OPT_DISABLE_I186
164 #if !OPT_DISABLE_TLCS900H
169 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
172 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
174 extern void picglue ();
176 /** Sets the port to the one given by the command line option.
177 @param The name minus the option (eg 'mcs51')
178 @return 0 on success.
181 _setPort (const char *name)
184 for (i = 0; i < NUM_PORTS; i++)
186 if (!strcmp (_ports[i]->target, name))
192 /* Error - didnt find */
193 werror (E_UNKNOWN_TARGET, name);
198 _validatePorts (void)
201 for (i = 0; i < NUM_PORTS; i++)
203 if (_ports[i]->magic != PORT_MAGIC)
205 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
212 buildCmdLine (char *into, const char **cmds,
213 const char *p1, const char *p2,
214 const char *p3, const char **list)
216 const char *p, *from;
226 /* See if it has a '$' anywhere - if not, just copy */
227 if ((p = strchr (from, '$')))
229 strncat (into, from, p - from);
250 const char **tmp = list;
266 strcat (into, from); // this includes the ".asm" from "$1.asm"
272 /*-----------------------------------------------------------------*/
273 /* printVersionInfo - prints the version info */
274 /*-----------------------------------------------------------------*/
282 for (i = 0; i < NUM_PORTS; i++)
283 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
285 fprintf (stderr, " %s"
286 #ifdef SDCC_SUB_VERSION_STR
287 "/" SDCC_SUB_VERSION_STR
295 #if defined(_MSC_VER)
307 /*-----------------------------------------------------------------*/
308 /* printUsage - prints command line syntax */
309 /*-----------------------------------------------------------------*/
315 "Usage : [options] filename\n"
317 "\t-m<proc> - Target processor <proc>. Default %s\n"
318 "\t Try --version for supported values of <proc>\n"
319 "\t--model-large - Large Model\n"
320 "\t--model-small - Small Model (default)\n"
321 "\t--stack-auto - Stack automatic variables\n"
322 "\t--xstack - Use external stack\n"
323 "\t--xram-loc <nnnn> - External Ram start location\n"
324 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
325 "\t--code-loc <nnnn> - Code Segment Location\n"
326 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
327 "\t--data-loc <nnnn> - Direct data start location\n"
328 "\t--idata-loc <nnnn> - Indirect data start location\n"
329 "\t--iram-size <nnnn> - Internal Ram size\n"
330 "\t--nojtbound - Don't generate boundary check for jump tables\n"
331 "\t--generic - All unqualified ptrs converted to '_generic'\n"
332 "PreProcessor Options :-\n"
333 "\t-Dmacro - Define Macro\n"
334 "\t-Ipath - Include \"*.h\" path\n"
335 "Note: this is NOT a complete list of options see docs for details\n",
341 /*-----------------------------------------------------------------*/
342 /* parseWithComma - separates string with comma */
343 /*-----------------------------------------------------------------*/
345 parseWithComma (char **dest, char *src)
349 strtok (src, "\n \t");
350 /* skip the initial white spaces */
351 while (isspace (*src))
368 /*-----------------------------------------------------------------*/
369 /* setDefaultOptions - sets the default options */
370 /*-----------------------------------------------------------------*/
376 for (i = 0; i < 128; i++)
377 preArgv[i] = asmOptions[i] =
378 linkOptions[i] = relFiles[i] = libFiles[i] =
381 /* first the options part */
382 options.stack_loc = 0; /* stack pointer initialised to 0 */
383 options.xstack_loc = 0; /* xternal stack starts at 0 */
384 options.code_loc = 0; /* code starts at 0 */
385 options.data_loc = 0x0030; /* data starts at 0x0030 */
386 options.xdata_loc = 0;
387 options.idata_loc = 0x80;
388 options.genericPtr = 1; /* default on */
390 options.model = port->general.default_model;
391 options.nostdlib = 0;
392 options.nostdinc = 0;
395 options.stack10bit=0;
397 /* now for the optimizations */
398 /* turn on the everything */
399 optimize.global_cse = 1;
404 optimize.loopInvariant = 1;
405 optimize.loopInduction = 1;
407 /* now for the ports */
408 port->setDefaultOptions ();
411 /*-----------------------------------------------------------------*/
412 /* processFile - determines the type of file from the extension */
413 /*-----------------------------------------------------------------*/
415 processFile (char *s)
419 /* get the file extension */
420 fext = s + strlen (s);
421 while ((fext != s) && *fext != '.')
424 /* now if no '.' then we don't know what the file type is
425 so give a warning and return */
428 werror (W_UNKNOWN_FEXT, s);
432 /* otherwise depending on the file type */
433 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
435 /* source file name : not if we already have a
439 werror (W_TOO_MANY_SRC, s);
443 /* the only source file */
444 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
446 werror (E_FILE_OPEN_ERR, s);
450 /* copy the file name into the buffer */
453 /* get rid of the "." */
454 strtok (buffer, ".");
455 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
456 strcpy (srcFileName, buffer);
458 /* get rid of any path information
459 for the module name; do this by going
460 backwards till we get to either '/' or '\' or ':'
461 or start of buffer */
462 fext = buffer + strlen (buffer);
463 while (fext != buffer &&
464 *(fext - 1) != '\\' &&
465 *(fext - 1) != '/' &&
468 moduleName = Safe_calloc (1, strlen (fext) + 1);
469 strcpy (moduleName, fext);
474 /* if the extention is type .rel or .r or .REL or .R
475 addtional object file will be passed to the linker */
476 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
477 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
478 strcmp (fext, port->linker.rel_ext) == 0)
480 relFiles[nrelFiles++] = s;
484 /* if .lib or .LIB */
485 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
487 libFiles[nlibFiles++] = s;
491 werror (W_UNKNOWN_FEXT, s);
496 _processC1Arg (char *s)
500 if (options.out_name)
502 werror (W_TOO_MANY_SRC, s);
505 options.out_name = strdup (s);
514 _addToList (const char **list, const char *str)
516 /* This is the bad way to do things :) */
519 *list = strdup (str);
522 werror (E_OUT_OF_MEM, __FILE__, 0);
529 _setModel (int model, const char *sz)
531 if (port->general.supported_models & model)
532 options.model = model;
534 werror (W_UNSUPPORTED_MODEL, sz, port->target);
537 /*-----------------------------------------------------------------*/
538 /* parseCmdLine - parses the command line and sets the options */
539 /*-----------------------------------------------------------------*/
541 parseCmdLine (int argc, char **argv)
546 /* go thru all whole command line */
547 for (i = 1; i < argc; i++)
553 if (argv[i][0] == '-' && argv[i][1] == '-')
556 if (strcmp (&argv[i][1], OPTION_HELP) == 0)
562 if (strcmp (&argv[i][1], OPTION_XREGS) == 0)
564 options.regExtend = 1;
568 if (strcmp (&argv[i][1], OPTION_LARGE_MODEL) == 0)
570 _setModel (MODEL_LARGE, argv[i]);
574 if (strcmp (&argv[i][1], OPTION_MEDIUM_MODEL) == 0)
576 _setModel (MODEL_MEDIUM, argv[i]);
580 if (strcmp (&argv[i][1], OPTION_SMALL_MODEL) == 0)
582 _setModel (MODEL_SMALL, argv[i]);
586 if (strcmp (&argv[i][1], OPTION_FLAT24_MODEL) == 0)
588 _setModel (MODEL_FLAT24, argv[i]);
592 if (strcmp (&argv[i][1], OPTION_STACK_10BIT) == 0)
594 options.stack10bit = 1;
598 if (strcmp (&argv[i][1], OPTION_STACK_8BIT) == 0)
600 options.stack10bit = 0;
604 if (strcmp (&argv[i][1], OPTION_STACK_AUTO) == 0)
606 options.stackAuto = 1;
610 if (strcmp (&argv[i][1], OPTION_DUMP_RAW) == 0)
612 options.dump_raw = 1;
616 if (strcmp (&argv[i][1], OPTION_CYCLOMATIC) == 0)
618 options.cyclomatic = 1;
622 if (strcmp (&argv[i][1], OPTION_DUMP_GCSE) == 0)
624 options.dump_gcse = 1;
628 if (strcmp (&argv[i][1], OPTION_DUMP_LOOP) == 0)
630 options.dump_loop = 1;
634 if (strcmp (&argv[i][1], OPTION_DUMP_KILL) == 0)
636 options.dump_kill = 1;
640 if (strcmp (&argv[i][1], OPTION_INTLONG_RENT) == 0)
642 options.intlong_rent = 1;
646 if (strcmp (&argv[i][1], OPTION_FLOAT_RENT) == 0)
648 options.float_rent = 1;
652 if (strcmp (&argv[i][1], OPTION_DUMP_RANGE) == 0)
654 options.dump_range = 1;
658 if (strcmp (&argv[i][1], OPTION_DUMP_PACK) == 0)
660 options.dump_pack = 1;
664 if (strcmp (&argv[i][1], OPTION_DUMP_RASSGN) == 0)
666 options.dump_rassgn = 1;
670 if (strcmp (&argv[i][1], OPTION_OUT_FMT_IHX) == 0)
676 if (strcmp (&argv[i][1], OPTION_OUT_FMT_S19) == 0)
682 if (strcmp (&argv[i][1], OPTION_NOOVERLAY) == 0)
684 options.noOverlay = 1;
688 if (strcmp (&argv[i][1], OPTION_STKAFTRDATA) == 0)
690 options.stackOnData = 1;
694 if (strcmp (&argv[i][1], OPTION_PREPROC_ONLY) == 0)
700 if (strcmp (&argv[i][1], OPTION_C1_MODE) == 0)
707 if (strcmp (&argv[i][1], OPTION_DUMP_ALL) == 0)
709 options.dump_rassgn =
715 options.dump_raw = 1;
719 if (strcmp (&argv[i][1], OPTION_COMP_ONLY) == 0)
725 if (strcmp (&argv[i][1], OPTION_GENERIC) == 0)
727 options.genericPtr = 1;
731 if (strcmp (&argv[i][1], OPTION_NOPEEP) == 0)
737 if (strcmp (&argv[i][1], OPTION_ASMPEEP) == 0)
743 if (strcmp (&argv[i][1], OPTION_DEBUG) == 0)
749 if (strcmp (&argv[i][1], OPTION_NODEBUG) == 0)
755 if (strcmp (&argv[i][1], OPTION_PEEP_FILE) == 0)
757 if (argv[i][1 + strlen (OPTION_PEEP_FILE)])
759 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
761 options.peep_file = argv[++i];
765 if (strcmp (&argv[i][1], OPTION_LIB_PATH) == 0)
767 if (argv[i][1 + strlen (OPTION_LIB_PATH)])
768 libPaths[nlibPaths++] =
769 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
771 libPaths[nlibPaths++] = argv[++i];
775 if (strcmp (&argv[i][1], OPTION_XSTACK_LOC) == 0)
778 if (argv[i][1 + strlen (OPTION_XSTACK_LOC)])
780 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XSTACK_LOC)]));
783 (int) floatFromVal (constVal (argv[++i]));
787 if (strcmp (&argv[i][1], OPTION_XSTACK) == 0)
789 options.useXstack = 1;
793 if (strcmp (&argv[i][1], OPTION_MAINRETURN) == 0)
795 options.mainreturn = 1;
799 if (strcmp (&argv[i][1], OPTION_CALLEE_SAVES) == 0)
801 if (argv[i][1 + strlen (OPTION_CALLEE_SAVES)])
802 parseWithComma (options.calleeSaves
803 ,&argv[i][1 + strlen (OPTION_CALLEE_SAVES)]);
805 parseWithComma (options.calleeSaves, argv[++i]);
809 if (strcmp (&argv[i][1], OPTION_STACK_LOC) == 0)
812 if (argv[i][1 + strlen (OPTION_STACK_LOC)])
814 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_STACK_LOC)]));
817 (int) floatFromVal (constVal (argv[++i]));
821 if (strcmp (&argv[i][1], OPTION_XRAM_LOC) == 0)
824 if (argv[i][1 + strlen (OPTION_XRAM_LOC)])
826 (unsigned int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XRAM_LOC)]));
829 (unsigned int) floatFromVal (constVal (argv[++i]));
833 if (strcmp (&argv[i][1], OPTION_IRAM_SIZE) == 0)
836 if (argv[i][1 + strlen (OPTION_IRAM_SIZE)])
838 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IRAM_SIZE)]));
841 (int) floatFromVal (constVal (argv[++i]));
845 if (strcmp (&argv[i][1], OPTION_VERSION) == 0)
852 if (strcmp (&argv[i][1], OPTION_DATA_LOC) == 0)
855 if (argv[i][1 + strlen (OPTION_DATA_LOC)])
857 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_DATA_LOC)]));
860 (int) floatFromVal (constVal (argv[++i]));
864 if (strcmp (&argv[i][1], OPTION_IDATA_LOC) == 0)
867 if (argv[i][1 + strlen (OPTION_IDATA_LOC)])
869 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IDATA_LOC)]));
872 (int) floatFromVal (constVal (argv[++i]));
876 if (strcmp (&argv[i][1], OPTION_CODE_LOC) == 0)
879 if (argv[i][1 + strlen (OPTION_CODE_LOC)])
881 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_CODE_LOC)]));
884 (int) floatFromVal (constVal (argv[++i]));
889 if (strcmp (&argv[i][1], OPTION_NO_JTBOUND) == 0)
891 optimize.noJTabBoundary = 1;
895 if (strcmp (&argv[i][1], OPTION_NO_GCSE) == 0)
897 optimize.global_cse = 0;
901 if (strcmp (&argv[i][1], OPTION_NO_LOOP_INV) == 0)
903 optimize.loopInvariant = 0;
907 if (strcmp (&argv[i][1], OPTION_NO_LOOP_IND) == 0)
909 optimize.loopInduction = 0;
913 if (strcmp (&argv[i][1], OPTION_NO_LOOPREV) == 0)
915 optimize.noLoopReverse = 1;
919 if (strcmp (&argv[i][1], OPTION_NOSTDLIB) == 0)
921 options.nostdlib = 1;
925 if (strcmp (&argv[i][1], OPTION_NOSTDINC) == 0)
927 options.nostdinc = 1;
931 if (strcmp (&argv[i][1], OPTION_VERBOSE) == 0)
937 if (!port->parseOption (&argc, argv, &i))
939 werror (W_UNKNOWN_OPTION, argv[i]);
948 /* if preceded by '-' then option */
963 /* Used to select the port */
964 _setPort (argv[i] + 2);
968 werror (W_UNSUPP_OPTION, "-a", "use --stack-auto instead");
972 werror (W_UNSUPP_OPTION, "-g", "use --generic instead");
975 case 'X': /* use external stack */
976 werror (W_UNSUPP_OPTION, "-X", "use --xstack-loc instead");
980 werror (W_UNSUPP_OPTION, "-x", "use --xstack instead");
983 case 'p': /* stack pointer intial value */
985 werror (W_UNSUPP_OPTION, "-p", "use --stack-loc instead");
989 werror (W_UNSUPP_OPTION, "-i", "use --idata-loc instead");
993 werror (W_UNSUPP_OPTION, "-r", "use --xdata-loc instead");
997 werror (W_UNSUPP_OPTION, "-s", "use --code-loc instead");
1001 options.cc_only = 1;
1005 werror (W_UNSUPP_OPTION, "-Y", "use -I instead");
1010 libPaths[nlibPaths++] = &argv[i][2];
1012 libPaths[nlibPaths++] = argv[++i];
1016 /* linker options */
1017 if (argv[i][2] == 'l')
1020 parseWithComma (linkOptions, &argv[i][3]);
1022 parseWithComma (linkOptions, argv[++i]);
1026 /* assembler options */
1027 if (argv[i][2] == 'a')
1030 parseWithComma ((char **) asmOptions, &argv[i][3]);
1032 parseWithComma ((char **) asmOptions, argv[++i]);
1037 werror (W_UNKNOWN_OPTION, argv[i]);
1050 printVersionInfo ();
1054 /* preprocessor options */
1058 _addToList (preArgv, "-M");
1063 _addToList (preArgv, "-C");
1072 char sOpt = argv[i][1];
1075 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1083 if (argv[i][1] == 'Y')
1086 sprintf (buffer, "-%c%s", sOpt, rest);
1087 _addToList (preArgv, buffer);
1092 if (!port->parseOption (&argc, argv, &i))
1093 werror (W_UNKNOWN_OPTION, argv[i]);
1098 if (!port->parseOption (&argc, argv, &i))
1100 /* no option must be a filename */
1102 _processC1Arg (argv[i]);
1104 processFile (argv[i]);
1108 /* set up external stack location if not explicitly specified */
1109 if (!options.xstack_loc)
1110 options.xstack_loc = options.xdata_loc;
1112 /* if debug option is set the open the cdbFile */
1113 if (!options.nodebug && srcFileName)
1115 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
1116 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
1117 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1120 /* add a module record */
1121 fprintf (cdbFile, "M:%s\n", moduleName);
1127 /*-----------------------------------------------------------------*/
1128 /* my_system - will call a program with arguments */
1129 /*-----------------------------------------------------------------*/
1134 //char *try_dir[]= {SRCDIR "/bin",PREFIX "/bin", NULL};
1136 {NULL, NULL}; /* First entry may be overwritten, so use two. */
1140 my_system (const char *cmd)
1142 int argsStart, e, i = 0;
1143 char *cmdLine = NULL;
1145 argsStart = strstr (cmd, " ") - cmd;
1147 // try to find the command in predefined path's
1150 cmdLine = (char *) Safe_malloc (strlen (try_dir[i]) + strlen (cmd) + 10);
1151 strcpy (cmdLine, try_dir[i]); // the path
1153 strcat (cmdLine, DIR_SEPARATOR_STRING);
1154 strncat (cmdLine, cmd, argsStart); // the command
1157 strcat (cmdLine, ".exe");
1160 if (access (cmdLine, X_OK) == 0)
1163 strcat (cmdLine, cmd + argsStart);
1173 printf ("+ %s\n", cmdLine ? cmdLine : cmd);
1178 // command found in predefined path
1179 e = system (cmdLine);
1191 /*-----------------------------------------------------------------*/
1192 /* linkEdit : - calls the linkage editor with options */
1193 /*-----------------------------------------------------------------*/
1195 linkEdit (char **envp)
1202 srcFileName = "temp";
1204 /* first we need to create the <filename>.lnk file */
1205 sprintf (buffer, "%s.lnk", srcFileName);
1206 if (!(lnkfile = fopen (buffer, "w")))
1208 werror (E_FILE_OPEN_ERR, buffer);
1212 /* now write the options */
1213 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1215 /* if iram size specified */
1216 if (options.iram_size)
1217 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1219 /*if (options.debug) */
1220 fprintf (lnkfile, "-z\n");
1222 #define WRITE_SEG_LOC(N, L) \
1223 segName = strdup(N); \
1224 c = strtok(segName, " \t"); \
1225 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1226 if (segName) { free(segName); }
1228 /* code segment start */
1229 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1231 /* data segment start */
1232 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1235 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1238 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1240 /* bit segment start */
1241 WRITE_SEG_LOC (BIT_NAME, 0);
1243 /* add the extra linker options */
1244 for (i = 0; linkOptions[i]; i++)
1245 fprintf (lnkfile, "%s\n", linkOptions[i]);
1247 /* other library paths if specified */
1248 for (i = 0; i < nlibPaths; i++)
1249 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1251 /* standard library path */
1252 if (!options.nostdlib)
1254 if (TARGET_IS_DS390)
1260 switch (options.model)
1272 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1277 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1279 /* standard library files */
1280 if (strcmp (port->target, "ds390") == 0)
1282 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1284 fprintf (lnkfile, "-l %s\n", STD_LIB);
1285 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1286 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1287 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1290 /* additional libraries if any */
1291 for (i = 0; i < nlibFiles; i++)
1292 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1294 /* put in the object files */
1295 if (strcmp (srcFileName, "temp"))
1296 fprintf (lnkfile, "%s ", srcFileName);
1298 for (i = 0; i < nrelFiles; i++)
1299 fprintf (lnkfile, "%s\n", relFiles[i]);
1301 fprintf (lnkfile, "\n-e\n");
1304 if (options.verbose)
1305 printf ("sdcc: Calling linker...\n");
1307 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1308 if (my_system (buffer))
1313 if (strcmp (srcFileName, "temp") == 0)
1315 /* rename "temp.cdb" to "firstRelFile.cdb" */
1316 char *f = strtok (strdup (relFiles[0]), ".");
1317 f = strcat (f, ".cdb");
1318 rename ("temp.cdb", f);
1323 /*-----------------------------------------------------------------*/
1324 /* assemble - spawns the assembler with arguments */
1325 /*-----------------------------------------------------------------*/
1327 assemble (char **envp)
1329 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1330 if (my_system (buffer))
1332 /* either system() or the assembler itself has reported an error
1333 perror ("Cannot exec assembler");
1341 /*-----------------------------------------------------------------*/
1342 /* preProcess - spawns the preprocessor with arguments */
1343 /*-----------------------------------------------------------------*/
1345 preProcess (char **envp)
1351 if (!options.c1mode)
1353 /* if using external stack define the macro */
1354 if (options.useXstack)
1355 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1357 /* set the macro for stack autos */
1358 if (options.stackAuto)
1359 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1361 /* set the macro for stack autos */
1362 if (options.stack10bit)
1363 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1365 /* set the macro for large model */
1366 switch (options.model)
1369 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1372 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1375 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1378 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1381 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1384 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1388 /* standard include path */
1389 if (!options.nostdinc) {
1390 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1393 /* add port (processor information to processor */
1394 sprintf (procDef, "-DSDCC_%s", port->target);
1395 _addToList (preArgv, procDef);
1396 sprintf (procDef, "-D__%s", port->target);
1397 _addToList (preArgv, procDef);
1400 preOutName = strdup (tmpnam (NULL));
1402 if (options.verbose)
1403 printf ("sdcc: Calling preprocessor...\n");
1405 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1406 preOutName, srcFileName, preArgv);
1407 if (my_system (buffer))
1409 // @FIX: Dario Vecchio 03-05-2001
1412 unlink (preOutName);
1424 preOutName = fullSrcFileName;
1427 yyin = fopen (preOutName, "r");
1430 perror ("Preproc file not found\n");
1438 _findPort (int argc, char **argv)
1445 if (!strncmp (*argv, "-m", 2))
1447 _setPort (*argv + 2);
1453 /* Use the first in the list */
1459 * initialises and calls the parser
1463 main (int argc, char **argv, char **envp)
1465 /* turn all optimizations off by default */
1466 memset (&optimize, 0, sizeof (struct optimize));
1468 /*printVersionInfo (); */
1471 fprintf (stderr, "Build error: no ports are enabled.\n");
1475 _findPort (argc, argv);
1476 /* Initalise the port. */
1480 // Create a default exe search path from the path to the sdcc command
1484 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1486 strcpy (DefaultExePath, argv[0]);
1487 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1488 try_dir[0] = DefaultExePath;
1492 setDefaultOptions ();
1493 parseCmdLine (argc, argv);
1497 port->finaliseOptions ();
1499 /* if no input then printUsage & exit */
1500 if ((!options.c1mode && !srcFileName && !nrelFiles) || (options.c1mode && !srcFileName && !options.out_name))
1515 if (options.verbose)
1516 printf ("sdcc: Generating code...\n");
1522 if (TARGET_IS_PIC) {
1523 /* TSD PIC port hack - if the PIC port option is enabled
1524 and SDCC is used to generate PIC code, then we will
1525 generate .asm files in gpasm's format instead of SDCC's
1528 #if !OPT_DISABLE_PIC
1537 // @FIX: Dario Vecchio 03-05-2001
1540 if (yyin && yyin != stdin)
1542 unlink (preOutName);
1548 if (!options.c1mode)
1550 if (options.verbose)
1551 printf ("sdcc: Calling assembler...\n");
1557 // @FIX: Dario Vecchio 03-05-2001
1560 if (yyin && yyin != stdin)
1562 unlink (preOutName);
1574 if (!options.cc_only &&
1578 (srcFileName || nrelFiles))
1580 if (port->linker.do_link)
1581 port->linker.do_link ();
1586 if (yyin && yyin != stdin)
1589 if (preOutName && !options.c1mode)
1591 unlink (preOutName);