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 -------------------------------------------------------------------------*/
38 // This is a bit messy because we define link ourself
39 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
44 // No unistd.h in Borland C++
46 extern int access (const char *, int);
53 extern int yyparse ();
55 FILE *srcFile; /* source file */
56 FILE *cdbFile = NULL; /* debugger information output file */
57 char *fullSrcFileName; /* full name for the source file */
58 char *srcFileName; /* source file name with the .c stripped */
59 char *moduleName; /* module name is srcFilename stripped of any path */
60 const char *preArgv[128]; /* pre-processor arguments */
62 struct optimize optimize;
63 struct options options;
64 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
65 short preProcOnly = 0;
67 char *linkOptions[128];
68 const char *asmOptions[128];
75 bool verboseExec = FALSE;
78 // In MSC VC6 default search path for exe's to path for this
80 char DefaultExePath[128];
82 /* Far functions, far data */
83 #define OPTION_LARGE_MODEL "-model-large"
84 /* Far functions, near data */
85 #define OPTION_MEDIUM_MODEL "-model-medium"
86 #define OPTION_SMALL_MODEL "-model-small"
87 #define OPTION_FLAT24_MODEL "-model-flat24"
88 #define OPTION_STACK_AUTO "-stack-auto"
89 #define OPTION_STACK_8BIT "-stack-8bit"
90 #define OPTION_STACK_10BIT "-stack-10bit"
91 #define OPTION_XSTACK "-xstack"
92 #define OPTION_GENERIC "-generic"
93 #define OPTION_NO_GCSE "-nogcse"
94 #define OPTION_NO_LOOP_INV "-noinvariant"
95 #define OPTION_NO_LOOP_IND "-noinduction"
96 #define OPTION_NO_JTBOUND "-nojtbound"
97 #define OPTION_NO_LOOPREV "-noloopreverse"
98 #define OPTION_XREGS "-regextend"
99 #define OPTION_COMP_ONLY "-compile-only"
100 #define OPTION_DUMP_RAW "-dumpraw"
101 #define OPTION_DUMP_GCSE "-dumpgcse"
102 #define OPTION_DUMP_LOOP "-dumploop"
103 #define OPTION_DUMP_KILL "-dumpdeadcode"
104 #define OPTION_DUMP_RANGE "-dumpliverange"
105 #define OPTION_DUMP_PACK "-dumpregpack"
106 #define OPTION_DUMP_RASSGN "-dumpregassign"
107 #define OPTION_DUMP_ALL "-dumpall"
108 #define OPTION_XRAM_LOC "-xram-loc"
109 #define OPTION_IRAM_SIZE "-iram-size"
110 #define OPTION_XSTACK_LOC "-xstack-loc"
111 #define OPTION_CODE_LOC "-code-loc"
112 #define OPTION_STACK_LOC "-stack-loc"
113 #define OPTION_DATA_LOC "-data-loc"
114 #define OPTION_IDATA_LOC "-idata-loc"
115 #define OPTION_PEEP_FILE "-peep-file"
116 #define OPTION_LIB_PATH "-lib-path"
117 #define OPTION_INTLONG_RENT "-int-long-reent"
118 #define OPTION_FLOAT_RENT "-float-reent"
119 #define OPTION_OUT_FMT_IHX "-out-fmt-ihx"
120 #define OPTION_OUT_FMT_S19 "-out-fmt-s19"
121 #define OPTION_CYCLOMATIC "-cyclomatic"
122 #define OPTION_NOOVERLAY "-nooverlay"
123 #define OPTION_MAINRETURN "-main-return"
124 #define OPTION_NOPEEP "-no-peep"
125 #define OPTION_ASMPEEP "-peep-asm"
126 #define OPTION_DEBUG "-debug"
127 #define OPTION_NODEBUG "-nodebug"
128 #define OPTION_VERSION "-version"
129 #define OPTION_STKAFTRDATA "-stack-after-data"
130 #define OPTION_PREPROC_ONLY "-preprocessonly"
131 #define OPTION_C1_MODE "-c1mode"
132 #define OPTION_HELP "-help"
133 #define OPTION_CALLEE_SAVES "-callee-saves"
134 #define OPTION_NOSTDLIB "-nostdlib"
135 #define OPTION_NOSTDINC "-nostdinc"
136 #define OPTION_VERBOSE "-verbose"
137 #define OPTION_LESS_PEDANTIC "-lesspedantic"
138 #define OPTION_SHORT_IS_CHAR "-short-is-char"
139 #define OPTION_SHORT_IS_INT "-short-is-int"
141 static const char *_preCmd[] =
143 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
144 "$l", "$1", "$2", NULL
149 static PORT *_ports[] =
151 #if !OPT_DISABLE_MCS51
154 #if !OPT_DISABLE_GBZ80
163 #if !OPT_DISABLE_DS390
169 #if !OPT_DISABLE_I186
172 #if !OPT_DISABLE_TLCS900H
177 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
180 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
182 extern void picglue ();
184 /** Sets the port to the one given by the command line option.
185 @param The name minus the option (eg 'mcs51')
186 @return 0 on success.
189 _setPort (const char *name)
192 for (i = 0; i < NUM_PORTS; i++)
194 if (!strcmp (_ports[i]->target, name))
200 /* Error - didnt find */
201 werror (E_UNKNOWN_TARGET, name);
206 _validatePorts (void)
209 for (i = 0; i < NUM_PORTS; i++)
211 if (_ports[i]->magic != PORT_MAGIC)
213 printf ("Error: port %s is incomplete.\n", _ports[i]->target);
218 /*-----------------------------------------------------------------*/
219 /* printVersionInfo - prints the version info */
220 /*-----------------------------------------------------------------*/
228 for (i = 0; i < NUM_PORTS; i++)
229 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
231 fprintf (stderr, " %s"
232 #ifdef SDCC_SUB_VERSION_STR
233 "/" SDCC_SUB_VERSION_STR
241 #if defined(_MSC_VER)
253 /*-----------------------------------------------------------------*/
254 /* printUsage - prints command line syntax */
255 /*-----------------------------------------------------------------*/
261 "Usage : [options] filename\n"
263 "\t-m<proc> - Target processor <proc>. Default %s\n"
264 "\t Try --version for supported values of <proc>\n"
265 "\t--model-large - Large Model\n"
266 "\t--model-small - Small Model (default)\n"
267 "\t--stack-auto - Stack automatic variables\n"
268 "\t--xstack - Use external stack\n"
269 "\t--xram-loc <nnnn> - External Ram start location\n"
270 "\t--xstack-loc <nnnn> - Xternal Stack Location\n"
271 "\t--code-loc <nnnn> - Code Segment Location\n"
272 "\t--stack-loc <nnnn> - Stack pointer initial value\n"
273 "\t--data-loc <nnnn> - Direct data start location\n"
274 "\t--idata-loc <nnnn> - Indirect data start location\n"
275 "\t--iram-size <nnnn> - Internal Ram size\n"
276 "\t--nojtbound - Don't generate boundary check for jump tables\n"
277 "\t--generic - All unqualified ptrs converted to '_generic'\n"
278 "PreProcessor Options :-\n"
279 "\t-Dmacro - Define Macro\n"
280 "\t-Ipath - Include \"*.h\" path\n"
281 "Note: this is NOT a complete list of options see docs for details\n",
287 /*-----------------------------------------------------------------*/
288 /* parseWithComma - separates string with comma */
289 /*-----------------------------------------------------------------*/
291 parseWithComma (char **dest, char *src)
295 strtok (src, "\n \t");
296 /* skip the initial white spaces */
297 while (isspace (*src))
314 /*-----------------------------------------------------------------*/
315 /* setDefaultOptions - sets the default options */
316 /*-----------------------------------------------------------------*/
322 for (i = 0; i < 128; i++)
323 preArgv[i] = asmOptions[i] =
324 linkOptions[i] = relFiles[i] = libFiles[i] =
327 /* first the options part */
328 options.stack_loc = 0; /* stack pointer initialised to 0 */
329 options.xstack_loc = 0; /* xternal stack starts at 0 */
330 options.code_loc = 0; /* code starts at 0 */
331 options.data_loc = 0x0030; /* data starts at 0x0030 */
332 options.xdata_loc = 0;
333 options.idata_loc = 0x80;
334 options.genericPtr = 1; /* default on */
336 options.model = port->general.default_model;
337 options.nostdlib = 0;
338 options.nostdinc = 0;
340 options.shortisint = 0;
342 options.stack10bit=0;
344 /* now for the optimizations */
345 /* turn on the everything */
346 optimize.global_cse = 1;
351 optimize.loopInvariant = 1;
352 optimize.loopInduction = 1;
354 /* now for the ports */
355 port->setDefaultOptions ();
358 /*-----------------------------------------------------------------*/
359 /* processFile - determines the type of file from the extension */
360 /*-----------------------------------------------------------------*/
362 processFile (char *s)
366 /* get the file extension */
367 fext = s + strlen (s);
368 while ((fext != s) && *fext != '.')
371 /* now if no '.' then we don't know what the file type is
372 so give a warning and return */
375 werror (W_UNKNOWN_FEXT, s);
379 /* otherwise depending on the file type */
380 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
382 /* source file name : not if we already have a
386 werror (W_TOO_MANY_SRC, s);
390 /* the only source file */
391 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
393 werror (E_FILE_OPEN_ERR, s);
397 /* copy the file name into the buffer */
400 /* get rid of the "." */
401 strtok (buffer, ".");
402 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
403 strcpy (srcFileName, buffer);
405 /* get rid of any path information
406 for the module name; do this by going
407 backwards till we get to either '/' or '\' or ':'
408 or start of buffer */
409 fext = buffer + strlen (buffer);
410 while (fext != buffer &&
411 *(fext - 1) != '\\' &&
412 *(fext - 1) != '/' &&
415 moduleName = Safe_calloc (1, strlen (fext) + 1);
416 strcpy (moduleName, fext);
421 /* if the extention is type .rel or .r or .REL or .R
422 addtional object file will be passed to the linker */
423 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
424 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
425 strcmp (fext, port->linker.rel_ext) == 0)
427 relFiles[nrelFiles++] = s;
431 /* if .lib or .LIB */
432 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
434 libFiles[nlibFiles++] = s;
438 werror (W_UNKNOWN_FEXT, s);
443 _processC1Arg (char *s)
447 if (options.out_name)
449 werror (W_TOO_MANY_SRC, s);
452 options.out_name = strdup (s);
461 _addToList (const char **list, const char *str)
463 /* This is the bad way to do things :) */
466 *list = strdup (str);
469 werror (E_OUT_OF_MEM, __FILE__, 0);
476 _setModel (int model, const char *sz)
478 if (port->general.supported_models & model)
479 options.model = model;
481 werror (W_UNSUPPORTED_MODEL, sz, port->target);
484 /*-----------------------------------------------------------------*/
485 /* parseCmdLine - parses the command line and sets the options */
486 /*-----------------------------------------------------------------*/
488 parseCmdLine (int argc, char **argv)
493 /* go thru all whole command line */
494 for (i = 1; i < argc; i++)
500 if (argv[i][0] == '-' && argv[i][1] == '-')
503 if (strcmp (&argv[i][1], OPTION_HELP) == 0)
509 if (strcmp (&argv[i][1], OPTION_XREGS) == 0)
511 options.regExtend = 1;
515 if (strcmp (&argv[i][1], OPTION_LARGE_MODEL) == 0)
517 _setModel (MODEL_LARGE, argv[i]);
521 if (strcmp (&argv[i][1], OPTION_MEDIUM_MODEL) == 0)
523 _setModel (MODEL_MEDIUM, argv[i]);
527 if (strcmp (&argv[i][1], OPTION_SMALL_MODEL) == 0)
529 _setModel (MODEL_SMALL, argv[i]);
533 if (strcmp (&argv[i][1], OPTION_FLAT24_MODEL) == 0)
535 _setModel (MODEL_FLAT24, argv[i]);
539 if (strcmp (&argv[i][1], OPTION_STACK_10BIT) == 0)
541 options.stack10bit = 1;
545 if (strcmp (&argv[i][1], OPTION_STACK_8BIT) == 0)
547 options.stack10bit = 0;
551 if (strcmp (&argv[i][1], OPTION_STACK_AUTO) == 0)
553 options.stackAuto = 1;
557 if (strcmp (&argv[i][1], OPTION_DUMP_RAW) == 0)
559 options.dump_raw = 1;
563 if (strcmp (&argv[i][1], OPTION_CYCLOMATIC) == 0)
565 options.cyclomatic = 1;
569 if (strcmp (&argv[i][1], OPTION_DUMP_GCSE) == 0)
571 options.dump_gcse = 1;
575 if (strcmp (&argv[i][1], OPTION_DUMP_LOOP) == 0)
577 options.dump_loop = 1;
581 if (strcmp (&argv[i][1], OPTION_DUMP_KILL) == 0)
583 options.dump_kill = 1;
587 if (strcmp (&argv[i][1], OPTION_INTLONG_RENT) == 0)
589 options.intlong_rent = 1;
593 if (strcmp (&argv[i][1], OPTION_FLOAT_RENT) == 0)
595 options.float_rent = 1;
599 if (strcmp (&argv[i][1], OPTION_DUMP_RANGE) == 0)
601 options.dump_range = 1;
605 if (strcmp (&argv[i][1], OPTION_DUMP_PACK) == 0)
607 options.dump_pack = 1;
611 if (strcmp (&argv[i][1], OPTION_DUMP_RASSGN) == 0)
613 options.dump_rassgn = 1;
617 if (strcmp (&argv[i][1], OPTION_OUT_FMT_IHX) == 0)
623 if (strcmp (&argv[i][1], OPTION_OUT_FMT_S19) == 0)
629 if (strcmp (&argv[i][1], OPTION_NOOVERLAY) == 0)
631 options.noOverlay = 1;
635 if (strcmp (&argv[i][1], OPTION_STKAFTRDATA) == 0)
637 options.stackOnData = 1;
641 if (strcmp (&argv[i][1], OPTION_PREPROC_ONLY) == 0)
647 if (strcmp (&argv[i][1], OPTION_C1_MODE) == 0)
654 if (strcmp (&argv[i][1], OPTION_DUMP_ALL) == 0)
656 options.dump_rassgn =
662 options.dump_raw = 1;
666 if (strcmp (&argv[i][1], OPTION_COMP_ONLY) == 0)
672 if (strcmp (&argv[i][1], OPTION_GENERIC) == 0)
674 options.genericPtr = 1;
678 if (strcmp (&argv[i][1], OPTION_NOPEEP) == 0)
684 if (strcmp (&argv[i][1], OPTION_ASMPEEP) == 0)
690 if (strcmp (&argv[i][1], OPTION_DEBUG) == 0)
696 if (strcmp (&argv[i][1], OPTION_NODEBUG) == 0)
702 if (strcmp (&argv[i][1], OPTION_PEEP_FILE) == 0)
704 if (argv[i][1 + strlen (OPTION_PEEP_FILE)])
706 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
708 options.peep_file = argv[++i];
712 if (strcmp (&argv[i][1], OPTION_LIB_PATH) == 0)
714 if (argv[i][1 + strlen (OPTION_LIB_PATH)])
715 libPaths[nlibPaths++] =
716 &argv[i][1 + strlen (OPTION_PEEP_FILE)];
718 libPaths[nlibPaths++] = argv[++i];
722 if (strcmp (&argv[i][1], OPTION_XSTACK_LOC) == 0)
725 if (argv[i][1 + strlen (OPTION_XSTACK_LOC)])
727 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XSTACK_LOC)]));
730 (int) floatFromVal (constVal (argv[++i]));
734 if (strcmp (&argv[i][1], OPTION_XSTACK) == 0)
736 options.useXstack = 1;
740 if (strcmp (&argv[i][1], OPTION_MAINRETURN) == 0)
742 options.mainreturn = 1;
746 if (strcmp (&argv[i][1], OPTION_CALLEE_SAVES) == 0)
748 if (argv[i][1 + strlen (OPTION_CALLEE_SAVES)])
749 parseWithComma (options.calleeSaves
750 ,&argv[i][1 + strlen (OPTION_CALLEE_SAVES)]);
752 parseWithComma (options.calleeSaves, argv[++i]);
756 if (strcmp (&argv[i][1], OPTION_STACK_LOC) == 0)
759 if (argv[i][1 + strlen (OPTION_STACK_LOC)])
761 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_STACK_LOC)]));
764 (int) floatFromVal (constVal (argv[++i]));
768 if (strcmp (&argv[i][1], OPTION_XRAM_LOC) == 0)
771 if (argv[i][1 + strlen (OPTION_XRAM_LOC)])
773 (unsigned int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_XRAM_LOC)]));
776 (unsigned int) floatFromVal (constVal (argv[++i]));
780 if (strcmp (&argv[i][1], OPTION_IRAM_SIZE) == 0)
783 if (argv[i][1 + strlen (OPTION_IRAM_SIZE)])
785 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IRAM_SIZE)]));
788 (int) floatFromVal (constVal (argv[++i]));
792 if (strcmp (&argv[i][1], OPTION_VERSION) == 0)
799 if (strcmp (&argv[i][1], OPTION_DATA_LOC) == 0)
802 if (argv[i][1 + strlen (OPTION_DATA_LOC)])
804 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_DATA_LOC)]));
807 (int) floatFromVal (constVal (argv[++i]));
811 if (strcmp (&argv[i][1], OPTION_IDATA_LOC) == 0)
814 if (argv[i][1 + strlen (OPTION_IDATA_LOC)])
816 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_IDATA_LOC)]));
819 (int) floatFromVal (constVal (argv[++i]));
823 if (strcmp (&argv[i][1], OPTION_CODE_LOC) == 0)
826 if (argv[i][1 + strlen (OPTION_CODE_LOC)])
828 (int) floatFromVal (constVal (&argv[i][1 + strlen (OPTION_CODE_LOC)]));
831 (int) floatFromVal (constVal (argv[++i]));
836 if (strcmp (&argv[i][1], OPTION_NO_JTBOUND) == 0)
838 optimize.noJTabBoundary = 1;
842 if (strcmp (&argv[i][1], OPTION_NO_GCSE) == 0)
844 optimize.global_cse = 0;
848 if (strcmp (&argv[i][1], OPTION_NO_LOOP_INV) == 0)
850 optimize.loopInvariant = 0;
854 if (strcmp (&argv[i][1], OPTION_NO_LOOP_IND) == 0)
856 optimize.loopInduction = 0;
860 if (strcmp (&argv[i][1], OPTION_NO_LOOPREV) == 0)
862 optimize.noLoopReverse = 1;
866 if (strcmp (&argv[i][1], OPTION_NOSTDLIB) == 0)
868 options.nostdlib = 1;
872 if (strcmp (&argv[i][1], OPTION_NOSTDINC) == 0)
874 options.nostdinc = 1;
878 if (strcmp (&argv[i][1], OPTION_VERBOSE) == 0)
884 if (strcmp (&argv[i][1], OPTION_SHORT_IS_INT) == 0) {
885 options.shortisint=1;
889 if (strcmp (&argv[i][1], OPTION_SHORT_IS_CHAR) == 0) {
890 options.shortisint=0;
894 if (strcmp (argv[i] +1, OPTION_LESS_PEDANTIC) == 0)
896 setErrorLogLevel(ERROR_LEVEL_WARNING);
900 if (!port->parseOption (&argc, argv, &i))
902 werror (W_UNKNOWN_OPTION, argv[i]);
911 /* if preceded by '-' then option */
926 /* Used to select the port */
927 _setPort (argv[i] + 2);
931 werror (W_UNSUPP_OPTION, "-a", "use --stack-auto instead");
935 werror (W_UNSUPP_OPTION, "-g", "use --generic instead");
938 case 'X': /* use external stack */
939 werror (W_UNSUPP_OPTION, "-X", "use --xstack-loc instead");
943 werror (W_UNSUPP_OPTION, "-x", "use --xstack instead");
946 case 'p': /* stack pointer intial value */
948 werror (W_UNSUPP_OPTION, "-p", "use --stack-loc instead");
952 werror (W_UNSUPP_OPTION, "-i", "use --idata-loc instead");
956 werror (W_UNSUPP_OPTION, "-r", "use --xdata-loc instead");
960 werror (W_UNSUPP_OPTION, "-s", "use --code-loc instead");
968 werror (W_UNSUPP_OPTION, "-Y", "use -I instead");
973 libPaths[nlibPaths++] = &argv[i][2];
975 libPaths[nlibPaths++] = argv[++i];
980 if (argv[i][2] == 'l')
983 parseWithComma (linkOptions, &argv[i][3]);
985 parseWithComma (linkOptions, argv[++i]);
989 /* assembler options */
990 if (argv[i][2] == 'a')
993 parseWithComma ((char **) asmOptions, &argv[i][3]);
995 parseWithComma ((char **) asmOptions, argv[++i]);
1000 werror (W_UNKNOWN_OPTION, argv[i]);
1013 printVersionInfo ();
1017 /* preprocessor options */
1021 _addToList (preArgv, "-M");
1026 _addToList (preArgv, "-C");
1035 char sOpt = argv[i][1];
1038 if (argv[i][2] == ' ' || argv[i][2] == '\0')
1046 if (argv[i][1] == 'Y')
1049 sprintf (buffer, "-%c%s", sOpt, rest);
1050 _addToList (preArgv, buffer);
1055 if (!port->parseOption (&argc, argv, &i))
1056 werror (W_UNKNOWN_OPTION, argv[i]);
1061 if (!port->parseOption (&argc, argv, &i))
1063 /* no option must be a filename */
1065 _processC1Arg (argv[i]);
1067 processFile (argv[i]);
1071 /* set up external stack location if not explicitly specified */
1072 if (!options.xstack_loc)
1073 options.xstack_loc = options.xdata_loc;
1075 /* if debug option is set the open the cdbFile */
1076 if (!options.nodebug && srcFileName)
1078 sprintf (cdbfnbuf, "%s.cdb", srcFileName);
1079 if ((cdbFile = fopen (cdbfnbuf, "w")) == NULL)
1080 werror (E_FILE_OPEN_ERR, cdbfnbuf);
1083 /* add a module record */
1084 fprintf (cdbFile, "M:%s\n", moduleName);
1090 /*-----------------------------------------------------------------*/
1091 /* linkEdit : - calls the linkage editor with options */
1092 /*-----------------------------------------------------------------*/
1094 linkEdit (char **envp)
1101 srcFileName = "temp";
1103 /* first we need to create the <filename>.lnk file */
1104 sprintf (buffer, "%s.lnk", srcFileName);
1105 if (!(lnkfile = fopen (buffer, "w")))
1107 werror (E_FILE_OPEN_ERR, buffer);
1111 /* now write the options */
1112 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1114 /* if iram size specified */
1115 if (options.iram_size)
1116 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1118 /*if (options.debug) */
1119 fprintf (lnkfile, "-z\n");
1121 #define WRITE_SEG_LOC(N, L) \
1122 segName = strdup(N); \
1123 c = strtok(segName, " \t"); \
1124 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1125 if (segName) { free(segName); }
1127 /* code segment start */
1128 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1130 /* data segment start */
1131 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1134 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1137 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1139 /* bit segment start */
1140 WRITE_SEG_LOC (BIT_NAME, 0);
1142 /* add the extra linker options */
1143 for (i = 0; linkOptions[i]; i++)
1144 fprintf (lnkfile, "%s\n", linkOptions[i]);
1146 /* other library paths if specified */
1147 for (i = 0; i < nlibPaths; i++)
1148 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1150 /* standard library path */
1151 if (!options.nostdlib)
1153 if (TARGET_IS_DS390)
1159 switch (options.model)
1171 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1176 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1178 /* standard library files */
1179 if (strcmp (port->target, "ds390") == 0)
1181 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1183 fprintf (lnkfile, "-l %s\n", STD_LIB);
1184 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1185 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1186 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1189 /* additional libraries if any */
1190 for (i = 0; i < nlibFiles; i++)
1191 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1193 /* put in the object files */
1194 if (strcmp (srcFileName, "temp"))
1195 fprintf (lnkfile, "%s ", srcFileName);
1197 for (i = 0; i < nrelFiles; i++)
1198 fprintf (lnkfile, "%s\n", relFiles[i]);
1200 fprintf (lnkfile, "\n-e\n");
1203 if (options.verbose)
1204 printf ("sdcc: Calling linker...\n");
1206 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1207 if (my_system (buffer))
1212 if (strcmp (srcFileName, "temp") == 0)
1214 /* rename "temp.cdb" to "firstRelFile.cdb" */
1215 char *f = strtok (strdup (relFiles[0]), ".");
1216 f = strcat (f, ".cdb");
1217 rename ("temp.cdb", f);
1222 /*-----------------------------------------------------------------*/
1223 /* assemble - spawns the assembler with arguments */
1224 /*-----------------------------------------------------------------*/
1226 assemble (char **envp)
1228 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1229 if (my_system (buffer))
1231 /* either system() or the assembler itself has reported an error
1232 perror ("Cannot exec assembler");
1240 /*-----------------------------------------------------------------*/
1241 /* preProcess - spawns the preprocessor with arguments */
1242 /*-----------------------------------------------------------------*/
1244 preProcess (char **envp)
1250 if (!options.c1mode)
1252 /* if using external stack define the macro */
1253 if (options.useXstack)
1254 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1256 /* set the macro for stack autos */
1257 if (options.stackAuto)
1258 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1260 /* set the macro for stack autos */
1261 if (options.stack10bit)
1262 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1264 /* set the macro for large model */
1265 switch (options.model)
1268 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1271 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1274 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1277 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1280 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1283 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1287 /* standard include path */
1288 if (!options.nostdinc) {
1289 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1292 /* add port (processor information to processor */
1293 sprintf (procDef, "-DSDCC_%s", port->target);
1294 _addToList (preArgv, procDef);
1295 sprintf (procDef, "-D__%s", port->target);
1296 _addToList (preArgv, procDef);
1299 preOutName = strdup (tmpnam (NULL));
1301 if (options.verbose)
1302 printf ("sdcc: Calling preprocessor...\n");
1304 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1305 preOutName, srcFileName, preArgv);
1306 if (my_system (buffer))
1308 // @FIX: Dario Vecchio 03-05-2001
1311 unlink (preOutName);
1323 preOutName = fullSrcFileName;
1326 yyin = fopen (preOutName, "r");
1329 perror ("Preproc file not found\n");
1337 _findPort (int argc, char **argv)
1344 if (!strncmp (*argv, "-m", 2))
1346 _setPort (*argv + 2);
1352 /* Use the first in the list */
1358 * initialises and calls the parser
1362 main (int argc, char **argv, char **envp)
1364 /* turn all optimizations off by default */
1365 memset (&optimize, 0, sizeof (struct optimize));
1367 /*printVersionInfo (); */
1370 fprintf (stderr, "Build error: no ports are enabled.\n");
1374 _findPort (argc, argv);
1375 /* Initalise the port. */
1379 // Create a default exe search path from the path to the sdcc command
1383 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1385 strcpy (DefaultExePath, argv[0]);
1386 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1387 ExePathList[0] = DefaultExePath;
1391 setDefaultOptions ();
1392 parseCmdLine (argc, argv);
1396 port->finaliseOptions ();
1398 /* if no input then printUsage & exit */
1399 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1400 (options.c1mode && !srcFileName && !options.out_name))
1415 if (options.verbose)
1416 printf ("sdcc: Generating code...\n");
1422 if (TARGET_IS_PIC) {
1423 /* TSD PIC port hack - if the PIC port option is enabled
1424 and SDCC is used to generate PIC code, then we will
1425 generate .asm files in gpasm's format instead of SDCC's
1428 #if !OPT_DISABLE_PIC
1437 // @FIX: Dario Vecchio 03-05-2001
1440 if (yyin && yyin != stdin)
1442 unlink (preOutName);
1448 if (!options.c1mode)
1450 if (options.verbose)
1451 printf ("sdcc: Calling assembler...\n");
1457 // @FIX: Dario Vecchio 03-05-2001
1460 if (yyin && yyin != stdin)
1462 unlink (preOutName);
1476 if (!options.cc_only &&
1480 (srcFileName || nrelFiles))
1482 if (port->linker.do_link)
1483 port->linker.do_link ();
1488 if (yyin && yyin != stdin)
1491 if (preOutName && !options.c1mode)
1493 unlink (preOutName);