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 #if !defined(__BORLANDC__) && !defined(_MSC_VER)
43 extern int yyparse ();
45 FILE *srcFile; /* source file */
46 FILE *cdbFile = NULL; /* debugger information output file */
47 char *fullSrcFileName; /* full name for the source file */
48 char *srcFileName; /* source file name with the .c stripped */
49 char *moduleName; /* module name is srcFilename stripped of any path */
50 const char *preArgv[128]; /* pre-processor arguments */
52 struct optimize optimize;
53 struct options options;
54 char *VersionString = SDCC_VERSION_STR /*"Version 2.1.8a" */ ;
57 char *linkOptions[128];
58 const char *asmOptions[128];
65 bool verboseExec = FALSE;
68 // Globally accessible scratch buffer for file names.
69 char scratchFileName[FILENAME_MAX];
71 // In MSC VC6 default search path for exe's to path for this
73 char DefaultExePath[128];
75 #define OPTION_HELP "-help"
77 #define LENGTH(_a) (sizeof(_a)/sizeof(*(_a)))
79 #define OPTION_STACK_8BIT "--stack-8bit"
80 #define OPTION_OUT_FMT_IHX "--out-fmt-ihx"
81 #define OPTION_LARGE_MODEL "--model-large"
82 #define OPTION_MEDIUM_MODEL "--model-medium"
83 #define OPTION_SMALL_MODEL "--model-small"
84 #define OPTION_FLAT24_MODEL "--model-flat24"
85 #define OPTION_DUMP_ALL "--dumpall"
86 #define OPTION_PEEP_FILE "--peep-file"
87 #define OPTION_LIB_PATH "--lib-path"
88 #define OPTION_XSTACK_LOC "--xstack-loc"
89 #define OPTION_CALLEE_SAVES "--callee-saves"
90 #define OPTION_STACK_LOC "--stack-loc"
91 #define OPTION_XRAM_LOC "--xram-loc"
92 #define OPTION_IRAM_SIZE "--iram-size"
93 #define OPTION_VERSION "--version"
94 #define OPTION_DATA_LOC "--data-loc"
95 #define OPTION_CODE_LOC "--code-loc"
96 #define OPTION_IDATA_LOC "--idata-loc"
97 #define OPTION_NO_LOOP_INV "--noinvariant"
98 #define OPTION_NO_LOOP_IND "--noinduction"
99 #define OPTION_LESS_PEDANTIC "--lesspedantic"
100 #define OPTION_NO_GCSE "--nogcse"
101 #define OPTION_SHORT_IS_8BITS "--short-is-8bits"
103 /** Table of all options supported by all ports.
105 * A reference for all options.
106 * An easy way to maintain help for the options.
107 * Automatic support for setting flags on simple options.
110 /** The short option character e.g. 'h' for -h. 0 for none. */
112 /** Long option e.g. "--help". Includes the -- prefix. NULL for
115 /** Pointer to an int that will be incremented every time the
116 option is encountered. May be NULL.
119 /** Help text to go with this option. May be NULL. */
125 { 'm', NULL, NULL, "Set the port to use e.g. -mz80." },
126 { 'd', NULL, NULL, NULL },
127 { 'D', NULL, NULL, "Define macro as in -Dmacro" },
128 { 'I', NULL, NULL, "Add to the include (*.h) path, as in -Ipath" },
129 { 'A', NULL, NULL, NULL },
130 { 'U', NULL, NULL, NULL },
131 { 'C', NULL, NULL, "Preprocessor option" },
132 { 'M', NULL, NULL, "Preprocessor option" },
133 { 'V', NULL, &verboseExec, "Execute verbosely. Show sub commands as they are run" },
134 { 'S', NULL, &noAssemble, "Assemble only" },
135 { 'W', NULL, NULL, "Pass through options to the assembler (a) or linker (l)" },
136 { 'L', NULL, NULL, "Add the next field to the library search path" },
137 { 'l', NULL, NULL, "Include the given library in the link" },
138 { 0, OPTION_LARGE_MODEL, NULL, "Far functions, far data" },
139 { 0, OPTION_MEDIUM_MODEL, NULL, "Far functions, near data" },
140 { 0, OPTION_SMALL_MODEL, NULL, "Small model (default)" },
141 { 0, OPTION_FLAT24_MODEL, NULL, NULL },
142 { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" },
143 { 0, OPTION_STACK_8BIT, NULL, NULL },
144 { 0, "--stack-10bit", &options.stack10bit, NULL },
145 { 0, "--xstack", &options.useXstack, "Use external stack" },
146 { 0, "--generic", &options.genericPtr, "All unqualified ptrs converted to '_generic'" },
147 { 0, OPTION_NO_GCSE, NULL, "Disable the GCSE optimisation" },
148 { 0, OPTION_NO_LOOP_INV, NULL, "Disable optimisation of invariants" },
149 { 0, OPTION_NO_LOOP_IND, NULL, NULL },
150 { 0, "--nojtbound", &optimize.noJTabBoundary, "Don't generate boundary check for jump tables" },
151 { 0, "--noloopreverse", &optimize.noLoopReverse, "Disable the loop reverse optimisation" },
152 { 'c', "--compile-only", &options.cc_only, "Compile only, do not assemble or link" },
153 { 0, "--dumpraw", &options.dump_raw, "Dump the internal structure after the initial parse" },
154 { 0, "--dumpgcse", &options.dump_gcse, NULL },
155 { 0, "--dumploop", &options.dump_loop, NULL },
156 { 0, "--dumpdeadcode", &options.dump_kill, NULL },
157 { 0, "--dumpliverange", &options.dump_range, NULL },
158 { 0, "--dumpregpack", &options.dump_pack, NULL },
159 { 0, "--dumpregassign", &options.dump_rassgn, NULL },
160 { 0, OPTION_DUMP_ALL, NULL, "Dump the internal structure at all stages" },
161 { 0, OPTION_XRAM_LOC, NULL, NULL },
162 { 0, OPTION_IRAM_SIZE, NULL, "<nnnn> Internal Ram size" },
163 { 0, OPTION_XSTACK_LOC, NULL, "<nnnn> External Ram start location" },
164 { 0, OPTION_CODE_LOC, NULL, "<nnnn> Code Segment Location" },
165 { 0, OPTION_STACK_LOC, NULL, "<nnnn> Stack pointer initial value" },
166 { 0, OPTION_DATA_LOC, NULL, "<nnnn> Direct data start location" },
167 { 0, OPTION_IDATA_LOC, NULL, NULL },
168 { 0, OPTION_PEEP_FILE, NULL, NULL },
169 { 0, OPTION_LIB_PATH, NULL, NULL },
170 { 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
171 { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the floar support functions" },
172 { 0, OPTION_OUT_FMT_IHX, NULL, NULL },
173 { 0, "--out-fmt-s19", &options.out_fmt, NULL },
174 { 0, "--cyclomatic", &options.cyclomatic, NULL },
175 { 0, "--nooverlay", &options.noOverlay, NULL },
176 { 0, "--main-return", &options.mainreturn, "Issue a return after main()" },
177 { 0, "--no-peep", &options.nopeep, "Disable the peephole assembly file optimisation" },
178 { 0, "--no-reg-params", &options.noRegParams, "On some ports, disable passing some parameters in registers" },
179 { 0, "--peep-asm", &options.asmpeep, NULL },
180 { 0, "--debug", &options.debug, "Enable debugging symbol output" },
181 { 'v', OPTION_VERSION, NULL, "Display sdcc's version" },
182 { 0, "--stack-after-data", &options.stackOnData, NULL },
183 { 'E', "--preprocessonly", &preProcOnly, "Preprocess only, do not compile" },
184 { 0, "--c1mode", &options.c1mode, "Act in c1 mode. The input is preprocessed code, the output is assembly code." },
185 { 0, "--help", NULL, "Display this help" },
186 { 0, OPTION_CALLEE_SAVES, NULL, "Cause the called function to save registers insted of the caller" },
187 { 0, "--nostdlib", &options.nostdlib, "Do not include the standard library directory in the search path" },
188 { 0, "--nostdinc", &options.nostdinc, NULL },
189 { 0, "--verbose", &options.verbose, "Trace calls to the preprocessor, assembler, and linker" },
190 { 0, OPTION_LESS_PEDANTIC, NULL, "Disable some of the more pedantic warnings" },
191 { 0, OPTION_SHORT_IS_8BITS, NULL, "Make short 8bits (for old times sake)" }
194 /** Table of all unsupported options and help text to display when one
198 /** shortOpt as in OPTIONS. */
200 /** longOpt as in OPTIONS. */
202 /** Message to display inside W_UNSUPPORTED_OPT when this option
207 static const UNSUPPORTEDOPT
208 unsupportedOptTable[] = {
209 { 'a', NULL, "use --stack-auto instead." },
210 { 'g', NULL, "use --generic instead" },
211 { 'X', NULL, "use --xstack-loc instead" },
212 { 'x', NULL, "use --xstack instead" },
213 { 'p', NULL, "use --stack-loc instead" },
214 { 'P', NULL, "use --stack-loc instead" },
215 { 'i', NULL, "use --idata-loc instead" },
216 { 'r', NULL, "use --xdata-loc instead" },
217 { 's', NULL, "use --code-loc instead" },
218 { 'Y', NULL, "use -I instead" }
221 static const char *_preCmd[] =
223 "sdcpp", "-Wall", "-lang-c++", "-DSDCC=1",
224 "$l", "$1", "$2", NULL
229 static PORT *_ports[] =
231 #if !OPT_DISABLE_MCS51
234 #if !OPT_DISABLE_GBZ80
243 #if !OPT_DISABLE_DS390
249 #if !OPT_DISABLE_I186
252 #if !OPT_DISABLE_TLCS900H
257 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
260 remove me - TSD a hack to force sdcc to generate gpasm format .asm files.
262 extern void picglue ();
264 /** Sets the port to the one given by the command line option.
265 @param The name minus the option (eg 'mcs51')
266 @return 0 on success.
269 _setPort (const char *name)
272 for (i = 0; i < NUM_PORTS; i++)
274 if (!strcmp (_ports[i]->target, name))
280 /* Error - didnt find */
281 werror (E_UNKNOWN_TARGET, name);
286 _validatePorts (void)
289 for (i = 0; i < NUM_PORTS; i++)
291 if (_ports[i]->magic != PORT_MAGIC)
293 wassertl (0, "Port definition structure is incomplete");
297 /*-----------------------------------------------------------------*/
298 /* printVersionInfo - prints the version info */
299 /*-----------------------------------------------------------------*/
307 for (i = 0; i < NUM_PORTS; i++)
308 fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
310 fprintf (stderr, " %s"
311 #ifdef SDCC_SUB_VERSION_STR
312 "/" SDCC_SUB_VERSION_STR
320 #if defined(_MSC_VER)
332 /*-----------------------------------------------------------------*/
333 /* printUsage - prints command line syntax */
334 /*-----------------------------------------------------------------*/
341 "Usage : sdcc [options] filename\n"
345 for (i = 0; i < LENGTH(optionsTable); i++) {
346 fprintf(stdout, " %c%c %-20s %s\n",
347 optionsTable[i].shortOpt !=0 ? '-' : ' ',
348 optionsTable[i].shortOpt !=0 ? optionsTable[i].shortOpt : ' ',
349 optionsTable[i].longOpt != NULL ? optionsTable[i].longOpt : "",
350 optionsTable[i].help != NULL ? optionsTable[i].help : ""
356 /*-----------------------------------------------------------------*/
357 /* parseWithComma - separates string with comma */
358 /*-----------------------------------------------------------------*/
360 parseWithComma (char **dest, char *src)
364 strtok (src, "\n \t");
365 /* skip the initial white spaces */
366 while (isspace (*src))
383 /*-----------------------------------------------------------------*/
384 /* setDefaultOptions - sets the default options */
385 /*-----------------------------------------------------------------*/
391 for (i = 0; i < 128; i++)
392 preArgv[i] = asmOptions[i] =
393 linkOptions[i] = relFiles[i] = libFiles[i] =
396 /* first the options part */
397 options.stack_loc = 0; /* stack pointer initialised to 0 */
398 options.xstack_loc = 0; /* xternal stack starts at 0 */
399 options.code_loc = 0; /* code starts at 0 */
400 options.data_loc = 0x0030; /* data starts at 0x0030 */
401 options.xdata_loc = 0;
402 options.idata_loc = 0x80;
403 options.genericPtr = 1; /* default on */
405 options.model = port->general.default_model;
406 options.nostdlib = 0;
407 options.nostdinc = 0;
409 options.shortis8bits = 1;
411 options.stack10bit=0;
413 /* now for the optimizations */
414 /* turn on the everything */
415 optimize.global_cse = 1;
420 optimize.loopInvariant = 1;
421 optimize.loopInduction = 1;
423 /* now for the ports */
424 port->setDefaultOptions ();
427 /*-----------------------------------------------------------------*/
428 /* processFile - determines the type of file from the extension */
429 /*-----------------------------------------------------------------*/
431 processFile (char *s)
435 /* get the file extension */
436 fext = s + strlen (s);
437 while ((fext != s) && *fext != '.')
440 /* now if no '.' then we don't know what the file type is
441 so give a warning and return */
444 werror (W_UNKNOWN_FEXT, s);
448 /* otherwise depending on the file type */
449 if (strcmp (fext, ".c") == 0 || strcmp (fext, ".C") == 0 || options.c1mode)
451 /* source file name : not if we already have a
455 werror (W_TOO_MANY_SRC, s);
459 /* the only source file */
460 if (!(srcFile = fopen ((fullSrcFileName = s), "r")))
462 werror (E_FILE_OPEN_ERR, s);
466 /* copy the file name into the buffer */
469 /* get rid of the "." */
470 strtok (buffer, ".");
471 srcFileName = Safe_calloc (1, strlen (buffer) + 1);
472 strcpy (srcFileName, buffer);
474 /* get rid of any path information
475 for the module name; do this by going
476 backwards till we get to either '/' or '\' or ':'
477 or start of buffer */
478 fext = buffer + strlen (buffer);
479 while (fext != buffer &&
480 *(fext - 1) != '\\' &&
481 *(fext - 1) != '/' &&
484 moduleName = Safe_calloc (1, strlen (fext) + 1);
485 strcpy (moduleName, fext);
490 /* if the extention is type .rel or .r or .REL or .R
491 addtional object file will be passed to the linker */
492 if (strcmp (fext, ".r") == 0 || strcmp (fext, ".rel") == 0 ||
493 strcmp (fext, ".R") == 0 || strcmp (fext, ".REL") == 0 ||
494 strcmp (fext, port->linker.rel_ext) == 0)
496 relFiles[nrelFiles++] = s;
500 /* if .lib or .LIB */
501 if (strcmp (fext, ".lib") == 0 || strcmp (fext, ".LIB") == 0)
503 libFiles[nlibFiles++] = s;
507 werror (W_UNKNOWN_FEXT, s);
512 _processC1Arg (char *s)
516 if (options.out_name)
518 werror (W_TOO_MANY_SRC, s);
521 options.out_name = strdup (s);
530 _addToList (const char **list, const char *str)
532 /* This is the bad way to do things :) */
535 *list = strdup (str);
538 werror (E_OUT_OF_MEM, __FILE__, 0);
545 _setModel (int model, const char *sz)
547 if (port->general.supported_models & model)
548 options.model = model;
550 werror (W_UNSUPPORTED_MODEL, sz, port->target);
553 /** Gets the string argument to this option. If the option is '--opt'
554 then for input of '--optxyz' or '--opt xyz' returns xyz.
557 getStringArg(const char *szStart, char **argv, int *pi, int argc)
559 if (argv[*pi][strlen(szStart)])
561 return &argv[*pi][strlen(szStart)];
568 werror (E_ARGUMENT_MISSING, szStart);
569 /* Die here rather than checking for errors later. */
574 return argv[++(*pi)];
579 /** Gets the integer argument to this option using the same rules as
583 getIntArg(const char *szStart, char **argv, int *pi, int argc)
585 return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
589 tryHandleUnsupportedOpt(char **argv, int *pi)
591 if (argv[*pi][0] == '-')
593 const char *longOpt = "";
597 if (argv[*pi][1] == '-')
604 shortOpt = argv[*pi][1];
606 for (i = 0; i < LENGTH(unsupportedOptTable); i++)
608 if (unsupportedOptTable[i].shortOpt == shortOpt ||
609 (longOpt && unsupportedOptTable[i].longOpt && !strcmp(unsupportedOptTable[i].longOpt, longOpt))) {
610 // Found an unsupported opt.
612 sprintf(buffer, "%s%c%c", longOpt ? longOpt : "", shortOpt ? '-' : ' ', shortOpt ? shortOpt : ' ');
613 werror (W_UNSUPP_OPTION, buffer, unsupportedOptTable[i].message);
617 // Didn't find in the table
622 // Not an option, so can't be unsupported :)
628 tryHandleSimpleOpt(char **argv, int *pi)
630 if (argv[*pi][0] == '-')
632 const char *longOpt = "";
636 if (argv[*pi][1] == '-')
643 shortOpt = argv[*pi][1];
646 for (i = 0; i < LENGTH(optionsTable); i++)
648 if (optionsTable[i].shortOpt == shortOpt ||
649 (longOpt && optionsTable[i].longOpt && strcmp(optionsTable[i].longOpt, longOpt) == 0))
651 // If it is a flag then we can handle it here
652 if (optionsTable[i].pparameter != NULL)
654 (*optionsTable[i].pparameter)++;
658 // Not a flag. Handled manually later.
663 // Didn't find in the table
668 // Not an option, so can't be handled.
673 /*-----------------------------------------------------------------*/
674 /* parseCmdLine - parses the command line and sets the options */
675 /*-----------------------------------------------------------------*/
677 parseCmdLine (int argc, char **argv)
681 /* go thru all whole command line */
682 for (i = 1; i < argc; i++)
687 if (tryHandleUnsupportedOpt(argv, &i) == TRUE)
692 if (tryHandleSimpleOpt(argv, &i) == TRUE)
698 if (argv[i][0] == '-' && argv[i][1] == '-')
700 if (strcmp (argv[i], OPTION_HELP) == 0)
706 if (strcmp (argv[i], OPTION_STACK_8BIT) == 0)
708 options.stack10bit = 0;
712 if (strcmp (argv[i], OPTION_OUT_FMT_IHX) == 0)
718 if (strcmp (argv[i], OPTION_LARGE_MODEL) == 0)
720 _setModel (MODEL_LARGE, argv[i]);
724 if (strcmp (argv[i], OPTION_MEDIUM_MODEL) == 0)
726 _setModel (MODEL_MEDIUM, argv[i]);
730 if (strcmp (argv[i], OPTION_SMALL_MODEL) == 0)
732 _setModel (MODEL_SMALL, argv[i]);
736 if (strcmp (argv[i], OPTION_FLAT24_MODEL) == 0)
738 _setModel (MODEL_FLAT24, argv[i]);
742 if (strcmp (argv[i], OPTION_DUMP_ALL) == 0)
744 options.dump_rassgn =
750 options.dump_raw = 1;
754 if (strcmp (argv[i], OPTION_PEEP_FILE) == 0)
756 options.peep_file = getStringArg(OPTION_PEEP_FILE, argv, &i, argc);
760 if (strcmp (argv[i], OPTION_LIB_PATH) == 0)
762 libPaths[nlibPaths++] = getStringArg(OPTION_LIB_PATH, argv, &i, argc);
766 if (strcmp (argv[i], OPTION_VERSION) == 0)
773 if (strcmp (argv[i], OPTION_CALLEE_SAVES) == 0)
775 parseWithComma (options.calleeSaves, getStringArg(OPTION_CALLEE_SAVES, argv, &i, argc));
779 if (strcmp (argv[i], OPTION_XSTACK_LOC) == 0)
781 options.xstack_loc = getIntArg(OPTION_XSTACK_LOC, argv, &i, argc);
785 if (strcmp (argv[i], OPTION_STACK_LOC) == 0)
787 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i, argc);
791 if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
793 options.xdata_loc = getIntArg(OPTION_XRAM_LOC, argv, &i, argc);
797 if (strcmp (argv[i], OPTION_IRAM_SIZE) == 0)
799 options.iram_size = getIntArg(OPTION_IRAM_SIZE, argv, &i, argc);
803 if (strcmp (argv[i], OPTION_DATA_LOC) == 0)
805 options.data_loc = getIntArg(OPTION_DATA_LOC, argv, &i, argc);
809 if (strcmp (argv[i], OPTION_IDATA_LOC) == 0)
811 options.idata_loc = getIntArg(OPTION_IDATA_LOC, argv, &i, argc);
815 if (strcmp (argv[i], OPTION_CODE_LOC) == 0)
817 options.code_loc = getIntArg(OPTION_CODE_LOC, argv, &i, argc);
821 if (strcmp (argv[i], OPTION_NO_GCSE) == 0)
823 optimize.global_cse = 0;
827 if (strcmp (argv[i], OPTION_NO_LOOP_INV) == 0)
829 optimize.loopInvariant = 0;
833 if (strcmp (argv[i], OPTION_NO_LOOP_IND) == 0)
835 optimize.loopInduction = 0;
839 if (strcmp (argv[i], OPTION_LESS_PEDANTIC) == 0)
841 setErrorLogLevel(ERROR_LEVEL_WARNING);
845 if (strcmp (&argv[i][1], OPTION_SHORT_IS_8BITS) == 0)
847 options.shortis8bits=1;
851 if (!port->parseOption (&argc, argv, &i))
853 werror (W_UNKNOWN_OPTION, argv[i]);
861 /* if preceded by '-' then option */
872 /* Used to select the port */
873 _setPort (argv[i] + 2);
881 libPaths[nlibPaths++] = getStringArg("-L", argv, &i, argc);
885 libFiles[nlibFiles++] = getStringArg("-l", argv, &i, argc);
890 if (argv[i][2] == 'l')
892 parseWithComma(linkOptions, getStringArg("-Wl", argv, &i, argc));
896 /* assembler options */
897 if (argv[i][2] == 'a')
899 parseWithComma ((char **) asmOptions, getStringArg("-Wa", argv, &i, argc));
903 werror (W_UNKNOWN_OPTION, argv[i]);
913 /* preprocessor options */
917 _addToList (preArgv, "-M");
922 _addToList (preArgv, "-C");
931 char sOpt = argv[i][1];
934 if (argv[i][2] == ' ' || argv[i][2] == '\0')
940 werror(E_ARGUMENT_MISSING, argv[i-1]);
954 sprintf (buffer, "-%c%s", sOpt, rest);
955 _addToList (preArgv, buffer);
960 if (!port->parseOption (&argc, argv, &i))
961 werror (W_UNKNOWN_OPTION, argv[i]);
966 if (!port->parseOption (&argc, argv, &i))
968 /* no option must be a filename */
970 _processC1Arg (argv[i]);
972 processFile (argv[i]);
976 /* set up external stack location if not explicitly specified */
977 if (!options.xstack_loc)
978 options.xstack_loc = options.xdata_loc;
980 /* if debug option is set the open the cdbFile */
981 if (options.debug && srcFileName)
983 sprintf (scratchFileName, "%s.cdb", srcFileName);
984 if ((cdbFile = fopen (scratchFileName, "w")) == NULL)
985 werror (E_FILE_OPEN_ERR, scratchFileName);
988 /* add a module record */
989 fprintf (cdbFile, "M:%s\n", moduleName);
995 /*-----------------------------------------------------------------*/
996 /* linkEdit : - calls the linkage editor with options */
997 /*-----------------------------------------------------------------*/
999 linkEdit (char **envp)
1006 srcFileName = "temp";
1008 /* first we need to create the <filename>.lnk file */
1009 sprintf (scratchFileName, "%s.lnk", srcFileName);
1010 if (!(lnkfile = fopen (scratchFileName, "w")))
1012 werror (E_FILE_OPEN_ERR, scratchFileName);
1016 /* now write the options */
1017 fprintf (lnkfile, "-mux%c\n", (options.out_fmt ? 's' : 'i'));
1019 /* if iram size specified */
1020 if (options.iram_size)
1021 fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
1024 fprintf (lnkfile, "-z\n");
1026 #define WRITE_SEG_LOC(N, L) \
1027 segName = strdup(N); \
1028 c = strtok(segName, " \t"); \
1029 fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
1030 if (segName) { free(segName); }
1032 /* code segment start */
1033 WRITE_SEG_LOC (CODE_NAME, options.code_loc);
1035 /* data segment start */
1036 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
1039 WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
1042 WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
1044 /* bit segment start */
1045 WRITE_SEG_LOC (BIT_NAME, 0);
1047 /* add the extra linker options */
1048 for (i = 0; linkOptions[i]; i++)
1049 fprintf (lnkfile, "%s\n", linkOptions[i]);
1051 /* other library paths if specified */
1052 for (i = 0; i < nlibPaths; i++)
1053 fprintf (lnkfile, "-k %s\n", libPaths[i]);
1055 /* standard library path */
1056 if (!options.nostdlib)
1058 if (TARGET_IS_DS390)
1064 switch (options.model)
1076 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1081 fprintf (lnkfile, "-k %s/%s\n", SDCC_LIB_DIR /*STD_LIB_PATH */ , c);
1083 /* standard library files */
1084 if (strcmp (port->target, "ds390") == 0)
1086 fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
1088 fprintf (lnkfile, "-l %s\n", STD_LIB);
1089 fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
1090 fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
1091 fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
1094 /* additional libraries if any */
1095 for (i = 0; i < nlibFiles; i++)
1096 fprintf (lnkfile, "-l %s\n", libFiles[i]);
1098 /* put in the object files */
1099 if (strcmp (srcFileName, "temp"))
1100 fprintf (lnkfile, "%s ", srcFileName);
1102 for (i = 0; i < nrelFiles; i++)
1103 fprintf (lnkfile, "%s\n", relFiles[i]);
1105 fprintf (lnkfile, "\n-e\n");
1108 if (options.verbose)
1109 printf ("sdcc: Calling linker...\n");
1111 buildCmdLine (buffer, port->linker.cmd, srcFileName, NULL, NULL, NULL);
1112 if (my_system (buffer))
1117 if (strcmp (srcFileName, "temp") == 0)
1119 /* rename "temp.cdb" to "firstRelFile.cdb" */
1120 char *f = strtok (strdup (relFiles[0]), ".");
1121 f = strcat (f, ".cdb");
1122 rename ("temp.cdb", f);
1127 /*-----------------------------------------------------------------*/
1128 /* assemble - spawns the assembler with arguments */
1129 /*-----------------------------------------------------------------*/
1131 assemble (char **envp)
1133 buildCmdLine (buffer, port->assembler.cmd, srcFileName, NULL, NULL, asmOptions);
1134 if (my_system (buffer))
1136 /* either system() or the assembler itself has reported an error
1137 perror ("Cannot exec assembler");
1145 /*-----------------------------------------------------------------*/
1146 /* preProcess - spawns the preprocessor with arguments */
1147 /*-----------------------------------------------------------------*/
1149 preProcess (char **envp)
1155 if (!options.c1mode)
1157 /* if using external stack define the macro */
1158 if (options.useXstack)
1159 _addToList (preArgv, "-DSDCC_USE_XSTACK");
1161 /* set the macro for stack autos */
1162 if (options.stackAuto)
1163 _addToList (preArgv, "-DSDCC_STACK_AUTO");
1165 /* set the macro for stack autos */
1166 if (options.stack10bit)
1167 _addToList (preArgv, "-DSDCC_STACK_TENBIT");
1169 /* set the macro for large model */
1170 switch (options.model)
1173 _addToList (preArgv, "-DSDCC_MODEL_LARGE");
1176 _addToList (preArgv, "-DSDCC_MODEL_SMALL");
1179 _addToList (preArgv, "-DSDCC_MODEL_COMPACT");
1182 _addToList (preArgv, "-DSDCC_MODEL_MEDIUM");
1185 _addToList (preArgv, "-DSDCC_MODEL_FLAT24");
1188 werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
1192 /* standard include path */
1193 if (!options.nostdinc) {
1194 _addToList (preArgv, "-I" SDCC_INCLUDE_DIR);
1197 /* add port (processor information to processor */
1198 sprintf (procDef, "-DSDCC_%s", port->target);
1199 _addToList (preArgv, procDef);
1200 sprintf (procDef, "-D__%s", port->target);
1201 _addToList (preArgv, procDef);
1204 preOutName = strdup (tmpnam (NULL));
1206 if (options.verbose)
1207 printf ("sdcc: Calling preprocessor...\n");
1209 buildCmdLine (buffer, _preCmd, fullSrcFileName,
1210 preOutName, srcFileName, preArgv);
1211 if (my_system (buffer))
1213 // @FIX: Dario Vecchio 03-05-2001
1216 unlink (preOutName);
1230 preOutName = fullSrcFileName;
1233 yyin = fopen (preOutName, "r");
1236 perror ("Preproc file not found\n");
1244 _findPort (int argc, char **argv)
1250 if (!strncmp (*argv, "-m", 2))
1252 _setPort (*argv + 2);
1257 /* Use the first in the list */
1263 * initialises and calls the parser
1267 main (int argc, char **argv, char **envp)
1269 /* turn all optimizations off by default */
1270 memset (&optimize, 0, sizeof (struct optimize));
1272 /*printVersionInfo (); */
1275 fprintf (stderr, "Build error: no ports are enabled.\n");
1279 _findPort (argc, argv);
1280 /* Initalise the port. */
1284 // Create a default exe search path from the path to the sdcc command
1288 if (strchr (argv[0], DIR_SEPARATOR_CHAR))
1290 strcpy (DefaultExePath, argv[0]);
1291 *(strrchr (DefaultExePath, DIR_SEPARATOR_CHAR)) = 0;
1292 ExePathList[0] = DefaultExePath;
1296 setDefaultOptions ();
1297 parseCmdLine (argc, argv);
1301 port->finaliseOptions ();
1303 /* if no input then printUsage & exit */
1304 if ((!options.c1mode && !srcFileName && !nrelFiles) ||
1305 (options.c1mode && !srcFileName && !options.out_name))
1320 if (options.verbose)
1321 printf ("sdcc: Generating code...\n");
1327 if (TARGET_IS_PIC) {
1328 /* TSD PIC port hack - if the PIC port option is enabled
1329 and SDCC is used to generate PIC code, then we will
1330 generate .asm files in gpasm's format instead of SDCC's
1333 #if !OPT_DISABLE_PIC
1342 // @FIX: Dario Vecchio 03-05-2001
1345 if (yyin && yyin != stdin)
1347 unlink (preOutName);
1353 if (!options.c1mode && !noAssemble)
1355 if (options.verbose)
1356 printf ("sdcc: Calling assembler...\n");
1362 // @FIX: Dario Vecchio 03-05-2001
1365 if (yyin && yyin != stdin)
1367 unlink (preOutName);
1381 if (!options.cc_only &&
1385 (srcFileName || nrelFiles))
1387 if (port->linker.do_link)
1388 port->linker.do_link ();
1393 if (yyin && yyin != stdin)
1396 if (preOutName && !options.c1mode)
1398 unlink (preOutName);