* src/pic16/ralloc.c (packRegsForAccUse): disabled functions with #if to eliminate...
[fw/sdcc] / src / SDCCmain.c
index 84310c15d46b8aa9ae540869779e2fbee58a219c..5c6bddaf72f9a6d895edd85ae069b1b434c2eef9 100644 (file)
@@ -123,7 +123,9 @@ char buffer[PATH_MAX * 2];
 #define OPTION_ICODE_IN_ASM    "--i-code-in-asm"
 #define OPTION_PRINT_SEARCH_DIRS "--print-search-dirs"
 #define OPTION_MSVC_ERROR_STYLE "--vc"
-#define OPTION_USE_STDOUT "--use-stdout"
+#define OPTION_USE_STDOUT       "--use-stdout"
+#define OPTION_STACK_SIZE      "--stack-size"
+#define OPTION_PACK_IRAM       "--pack-iram"
 
 static const OPTION
 optionsTable[] = {
@@ -182,7 +184,7 @@ optionsTable[] = {
     { 0,    OPTION_PEEP_FILE,       NULL, "<file> use this extra peep-hole file" },
     { 0,    OPTION_LIB_PATH,        NULL, "<path> use this path to search for libraries" },
     { 0,    "--int-long-reent",     &options.intlong_rent, "Use reenterant calls on the int and long support functions" },
-    { 0,    "--float-reent",        &options.float_rent, "Use reenterant calls on the floar support functions" },
+    { 0,    "--float-reent",        &options.float_rent, "Use reenterant calls on the float support functions" },
     { 0,    OPTION_OUT_FMT_IHX,     NULL, NULL },
     { 0,    "--out-fmt-s19",        &options.out_fmt, NULL },
     { 0,    "--cyclomatic",         &options.cyclomatic, NULL },
@@ -218,6 +220,8 @@ optionsTable[] = {
 #endif
 #if !OPT_DISABLE_DS390 || !OPT_DISABLE_MCS51
     { 0,    "--parms-in-bank1",            &options.parms_in_bank1,"MCS51/DS390 - use Bank1 for parameter passing"},
+    { 0,    OPTION_STACK_SIZE,     NULL,"MCS51/DS390 - Tells the linker to allocate this space for stack"},
+    { 0,    OPTION_PACK_IRAM,      &options.pack_iram,"MCS51/DS390 - Tells the linker to pack variables in internal ram"},
 #endif
     { 0,    OPTION_NO_XINIT_OPT,    &options.noXinitOpt, "don't memcpy initialized xram from code"},
     { 0,    OPTION_NO_CCODE_IN_ASM, &options.noCcodeInAsm, "don't include c-code as comments in the asm file"},
@@ -225,11 +229,10 @@ optionsTable[] = {
     { 0,    OPTION_PRINT_SEARCH_DIRS, &options.printSearchDirs, "display the directories in the compiler's search path"},
     { 0,    OPTION_MSVC_ERROR_STYLE, &options.vc_err_style, "messages are compatible with Micro$oft visual studio"},
     { 0,    OPTION_USE_STDOUT, &options.use_stdout, "send errors to stdout instead of stderr"},
-    /* End of options */
-#if 0 /* 10jun03 !OPT_DISABLE_PIC16 */
-    { 0,    "--no-movff",          &options.no_movff, "disable generating MOVFF opcode in PIC16 port"},
-    { 0,    "--gen-banksel",       &options.gen_banksel, "enable the generation of banksel assembler directives in PIC16 port"},
+#if !OPT_DISABLE_Z80 || !OPT_DISABLE_GBZ80
+    { 0,    "--no-std-crt0", &options.no_std_crt0, "For the z80/gbz80 do not link default crt0.o"},
 #endif
+    /* End of options */
     { 0,    NULL }
 };
 
@@ -287,12 +290,12 @@ static PORT *_ports[] =
 #if !OPT_DISABLE_DS390
   &ds390_port,
 #endif
-#if !OPT_DISABLE_PIC
-  &pic_port,
-#endif
 #if !OPT_DISABLE_PIC16
   &pic16_port,
 #endif
+#if !OPT_DISABLE_PIC
+  &pic_port,
+#endif
 #if !OPT_DISABLE_TININative
   &tininative_port,
 #endif
@@ -301,7 +304,10 @@ static PORT *_ports[] =
 #endif
 #if !OPT_DISABLE_DS400
   &ds400_port, 
-#endif 
+#endif
+#if !OPT_DISABLE_HC08
+  &hc08_port,
+#endif
 };
 
 #define NUM_PORTS (sizeof(_ports)/sizeof(_ports[0]))
@@ -370,13 +376,7 @@ _findPort (int argc, char **argv)
     }
 
   /* Use the first in the list */
-#if defined(DEFAULT_PORT)
-       /* VR - 13/5/2003 DEFAULT_PORT is defined in port.h */
-       port = &DEFAULT_PORT;
-#else
        port = _ports[0];
-#endif
-
 }
 
 /* search through the command line options for the processor */
@@ -406,12 +406,8 @@ printVersionInfo (void)
 
   fprintf (stderr,
           "SDCC : ");
-  for (i = 0; i < NUM_PORTS; i++) {
+  for (i = 0; i < NUM_PORTS; i++)
     fprintf (stderr, "%s%s", i == 0 ? "" : "/", _ports[i]->target);
-#ifdef DEFAULT_PORT
-       fprintf(stderr, "%s", (&DEFAULT_PORT == _ports[i])?"*":"");
-#endif
-  }
   
   fprintf (stderr, " " SDCC_VERSION_STR
 #ifdef SDCC_SUB_VERSION_STR
@@ -483,10 +479,16 @@ void
 setParseWithComma (set **dest, char *src)
 {
   char *p;
+  int length;
 
   /* skip the initial white spaces */
   while (isspace(*src))
     src++;
+  
+  /* skip the trailing white spaces */
+  length = strlen(src);
+  while (length && isspace(src[length-1]))
+    src[--length] = '\0';
 
   for (p = strtok(src, ","); p != NULL; p = strtok(NULL, ","))
     addSet(dest, Safe_strdup(p));
@@ -639,7 +641,7 @@ _setModel (int model, const char *sz)
 /** Gets the string argument to this option.  If the option is '--opt'
     then for input of '--optxyz' or '--opt xyz' returns xyz.
 */
-static char *
+char *
 getStringArg(const char *szStart, char **argv, int *pi, int argc)
 {
   if (argv[*pi][strlen(szStart)])
@@ -665,7 +667,7 @@ getStringArg(const char *szStart, char **argv, int *pi, int argc)
 /** Gets the integer argument to this option using the same rules as
     getStringArg.
 */
-static int
+int
 getIntArg(const char *szStart, char **argv, int *pi, int argc)
 {
     return (int)floatFromVal(constVal(getStringArg(szStart, argv, pi, argc)));
@@ -910,6 +912,12 @@ parseCmdLine (int argc, char **argv)
                 options.stack_loc = getIntArg(OPTION_STACK_LOC, argv, &i, argc);
                 continue;
            }
+         
+      if (strcmp (argv[i], OPTION_STACK_SIZE) == 0)
+           {
+                options.stack_size = getIntArg(OPTION_STACK_SIZE, argv, &i, argc);
+                continue;
+           }
 
          if (strcmp (argv[i], OPTION_XRAM_LOC) == 0)
            {
@@ -1116,8 +1124,11 @@ parseCmdLine (int argc, char **argv)
            case 'M':
              {
                preProcOnly = 1;
-               addSet(&preArgvSet, Safe_strdup("-M"));
-               break;
+                if (argv[i][2] == 'M')
+                 addSet(&preArgvSet, Safe_strdup("-MM"));
+                else
+                 addSet(&preArgvSet, Safe_strdup("-M"));
+               break;
              }
            case 'C':
              {
@@ -1286,239 +1297,262 @@ linkEdit (char **envp)
   int system_ret;
   const char *s;
 
-  /* first we need to create the <filename>.lnk file */
-  SNPRINTF (scratchFileName, sizeof(scratchFileName),
-           "%s.lnk", dstFileName);
-  if (!(lnkfile = fopen (scratchFileName, "w")))
+
+  if(port->linker.needLinkerScript)
     {
-      werror (E_FILE_OPEN_ERR, scratchFileName);
-      exit (1);
-    }
+      /* first we need to create the <filename>.lnk file */
+      SNPRINTF (scratchFileName, sizeof(scratchFileName),
+        "%s.lnk", dstFileName);
+      if (!(lnkfile = fopen (scratchFileName, "w")))
+        {
+          werror (E_FILE_OPEN_ERR, scratchFileName);
+          exit (1);
+        }
 
-   if (TARGET_IS_Z80 || TARGET_IS_GBZ80)
-   {
-         fprintf (lnkfile, "--\n-m\n-j\n-x\n-%c %s\n",
-          (options.out_fmt ? 's' : 'i'), dstFileName);
-   }
-   else /*For all the other ports.  Including pics???*/
-   {
-         fprintf (lnkfile, "-myux%c\n", (options.out_fmt ? 's' : 'i'));
-   }
-
-   if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
-   {
-         /* if iram size specified */
-         if (options.iram_size)
-               fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
-
-         /* if xram size specified */
-         if (options.xram_size_set)
-               fprintf (lnkfile, "-v 0x%04x\n", options.xram_size);
-
-         /* if code size specified */
-         if (options.code_size)
-               fprintf (lnkfile, "-w 0x%04x\n", options.code_size);
-
-         if (options.debug)
-               fprintf (lnkfile, "-z\n");
-   }
+      if (TARGET_IS_Z80 || TARGET_IS_GBZ80)
+        {
+          fprintf (lnkfile, "--\n-m\n-j\n-x\n-%c %s\n",
+            (options.out_fmt ? 's' : 'i'), dstFileName);
+        }
+      else /*For all the other ports.  Including pics???*/
+        {
+          fprintf (lnkfile, "-myux%c\n", (options.out_fmt ? 's' : 'i'));
+          if(options.pack_iram)
+              fprintf (lnkfile, "-Y\n");
+        }
+
+      if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
+        {
+          /* if iram size specified */
+          if (options.iram_size)
+            fprintf (lnkfile, "-a 0x%04x\n", options.iram_size);
+
+          /* if stack size specified*/
+          if(options.stack_size)
+              fprintf (lnkfile, "-A 0x%02x\n", options.stack_size);
+
+          /* if xram size specified */
+          if (options.xram_size_set)
+            fprintf (lnkfile, "-v 0x%04x\n", options.xram_size);
+
+          /* if code size specified */
+          if (options.code_size)
+            fprintf (lnkfile, "-w 0x%04x\n", options.code_size);
+
+          if (options.debug)
+            fprintf (lnkfile, "-z\n");
+        }
 
 #define WRITE_SEG_LOC(N, L) \
-    segName = Safe_strdup(N); \
-    c = strtok(segName, " \t"); \
-    fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
-    if (segName) { Safe_free(segName); }
+  segName = Safe_strdup(N); \
+  c = strtok(segName, " \t"); \
+  fprintf (lnkfile,"-b %s = 0x%04x\n", c, L); \
+  if (segName) { Safe_free(segName); }
 
-   if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
-   {
+      if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
+        {
 
-         /* code segment start */
-         WRITE_SEG_LOC (CODE_NAME, options.code_loc);
+          /* code segment start */
+          WRITE_SEG_LOC (CODE_NAME, options.code_loc);
 
-         /* data segment start. If zero, the linker chooses
-      the best place for data*/
-         if(options.data_loc){
-                 WRITE_SEG_LOC (DATA_NAME, options.data_loc);
-         }
+          /* data segment start. If zero, the linker chooses
+             the best place for data */
+          if(options.data_loc)
+            {
+              WRITE_SEG_LOC (DATA_NAME, options.data_loc);
+            }
 
-         /* xdata start */
-         WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
+          /* xdata start */
+          WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc);
 
-         /* indirect data */
-         if (IDATA_NAME) {
-               WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
-         }
+          /* indirect data */
+          if (IDATA_NAME)
+            {
+              WRITE_SEG_LOC (IDATA_NAME, options.idata_loc);
+            }
 
-         /* bit segment start */
-         WRITE_SEG_LOC (BIT_NAME, 0);
+            /* bit segment start */
+            WRITE_SEG_LOC (BIT_NAME, 0);
 
-         /* stack start */
-         if ( (options.stack_loc) && (options.stack_loc<0x100) ) {
-               WRITE_SEG_LOC ("SSEG", options.stack_loc);
-         }
-   }
-   else /*For the z80, gbz80*/
-   {
-       WRITE_SEG_LOC ("_CODE", options.code_loc);
-       WRITE_SEG_LOC ("_DATA", options.data_loc);
-   }
+            /* stack start */
+            if ( (options.stack_loc) && (options.stack_loc<0x100) )
+              {
+                WRITE_SEG_LOC ("SSEG", options.stack_loc);
+              }
+        }
+      else /*For the z80, gbz80*/
+        {
+          WRITE_SEG_LOC ("_CODE", options.code_loc);
+          WRITE_SEG_LOC ("_DATA", options.data_loc);
+        }
   
-  /* If the port has any special linker area declarations, get 'em */
-  if (port->extraAreas.genExtraAreaLinkOptions)
-  {
-       port->extraAreas.genExtraAreaLinkOptions(lnkfile);
-  }
+      /* If the port has any special linker area declarations, get 'em */
+      if (port->extraAreas.genExtraAreaLinkOptions)
+        {
+          port->extraAreas.genExtraAreaLinkOptions(lnkfile);
+        }
 
-  /* add the extra linker options */
-  fputStrSet(lnkfile, linkOptionsSet);
+      /* add the extra linker options */
+      fputStrSet(lnkfile, linkOptionsSet);
 
-  /* other library paths if specified */
-  for (s = setFirstItem(libPathsSet); s != NULL; s = setNextItem(libPathsSet))
-    fprintf (lnkfile, "-k %s\n", s);
-  
-  /* standard library path */
-    if (!options.nostdlib)
-    {
-        if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
+      /* command line defined library paths if specified */
+      for (s = setFirstItem(libPathsSet); s != NULL; s = setNextItem(libPathsSet))
+        fprintf (lnkfile, "-k %s\n", s);
+
+      /* standard library path */
+      if (!options.nostdlib)
         {
-            switch (options.model)
+          if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80 || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
             {
-                case MODEL_SMALL:
-                    c = "small";
-                    break;
+              switch (options.model)
+                {
+                  case MODEL_SMALL:
+                  c = "small";
+                  break;
                 case MODEL_LARGE:
-                    c = "large";
-                    break;
+                  c = "large";
+                  break;
                 case MODEL_FLAT24:
-                    /* c = "flat24"; */
-                    if (TARGET_IS_DS390)
+                  /* c = "flat24"; */
+                  if (TARGET_IS_DS390)
                     {
-                        c = "ds390";
+                      c = "ds390";
                     }
-                    else if (TARGET_IS_DS400)
+                  else if (TARGET_IS_DS400)
                     {
-                        c = "ds400";
+                      c = "ds400";
                     }
-                    else
+                  else
                     {
-                        fprintf(stderr, 
-                               "Add support for your FLAT24 target in %s @ line %d\n",
-                               __FILE__, __LINE__);
-                        exit(-1);
+                      fprintf(stderr, 
+                        "Add support for your FLAT24 target in %s @ line %d\n",
+                        __FILE__, __LINE__);
+                      exit(-1);
                     }
-                       break;
-                   case MODEL_PAGE0:
-                       c = "xa51";
-                       break;
-                   default:
-                       werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
-                       c = "unknown";
-                       break;
-               }
-        }
-        else /*for the z80, gbz80*/
-        {
-            if (TARGET_IS_Z80)
+                  break;
+                case MODEL_PAGE0:
+                  c = "xa51";
+                  break;
+                default:
+                  werror (W_UNKNOWN_MODEL, __FILE__, __LINE__);
+                  c = "unknown";
+                  break;
+                }
+            }
+          else /*for the z80, gbz80*/
+            {
+              if (TARGET_IS_HC08)
+                c = "hc08";
+              else if (TARGET_IS_Z80)
                 c = "z80";
-            else
+              else
                 c = "gbz80";
-        }
-        for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
+            }
+          for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
             mfprintf (lnkfile, getRuntimeVariables(), "-k %s{sep}%s\n", s, c);
+        }
 
+      /* command line defined library files if specified */
+      for (s = setFirstItem(libFilesSet); s != NULL; s = setNextItem(libFilesSet))
+        fprintf (lnkfile, "-l %s\n", s);
 
       /* standard library files */
-#if !OPT_DISABLE_DS390
-        if (options.model == MODEL_FLAT24)
+      if (!options.nostdlib)
         {
-            if (TARGET_IS_DS390)
-            {
-                fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
-            }
-            else if (TARGET_IS_DS400)
-            {
-                fprintf (lnkfile, "-l %s\n", STD_DS400_LIB);
-            }
-            else
+#if !OPT_DISABLE_DS390
+          if (options.model == MODEL_FLAT24)
             {
-                fprintf(stderr, 
+              if (TARGET_IS_DS390)
+                {
+                  fprintf (lnkfile, "-l %s\n", STD_DS390_LIB);
+                }
+              else if (TARGET_IS_DS400)
+                {
+                  fprintf (lnkfile, "-l %s\n", STD_DS400_LIB);
+                }
+              else
+                {
+                  fprintf(stderr, 
                     "Add support for your FLAT24 target in %s @ line %d\n",
                     __FILE__, __LINE__);
-                exit(-1);
-            }
-        }
+                  exit(-1);
+                }
+              }
 #endif
 
 #if !OPT_DISABLE_XA51 
 #ifdef STD_XA51_LIB
-        if (options.model == MODEL_PAGE0)
-        {
-            fprintf (lnkfile, "-l %s\n", STD_XA51_LIB);
-        }
+          if (options.model == MODEL_PAGE0)
+            {
+              fprintf (lnkfile, "-l %s\n", STD_XA51_LIB);
+            }
 #endif
 #endif
-        if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80)) /*Not for the z80, gbz80*/
-        { /*Why the z80 port is not using the standard libraries?*/
-            fprintf (lnkfile, "-l %s\n", STD_LIB);
-            fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
-            fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
-            fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
-        }
-        else if (TARGET_IS_Z80)
-        {
-            fprintf (lnkfile, "-l z80\n");
+          if (!(TARGET_IS_Z80 || TARGET_IS_GBZ80
+            || TARGET_IS_HC08)) /*Not for the z80, gbz80*/
+            { /*Why the z80 port is not using the standard libraries?*/
+              fprintf (lnkfile, "-l %s\n", STD_LIB);
+              fprintf (lnkfile, "-l %s\n", STD_INT_LIB);
+              fprintf (lnkfile, "-l %s\n", STD_LONG_LIB);
+              fprintf (lnkfile, "-l %s\n", STD_FP_LIB);
+            }
+          else if (TARGET_IS_HC08)
+            {
+              fprintf (lnkfile, "-l hc08\n");
+            }
+          else if (TARGET_IS_Z80)
+            {
+              fprintf (lnkfile, "-l z80\n");
+            }
+          else if (TARGET_IS_GBZ80)
+            {
+              fprintf (lnkfile, "-l gbz80\n");
+            }
         }
-        else if (TARGET_IS_GBZ80)
+
+      /*For the z80 and gbz80 ports, try to find where crt0.o is...
+      It is very important for this file to be first on the linking proccess
+      so the areas are set in the correct order, expecially _GSINIT*/
+      if ((TARGET_IS_Z80 || TARGET_IS_GBZ80) &&
+        !options.no_std_crt0 && !options.nostdlib) /*For the z80, gbz80*/
         {
-            fprintf (lnkfile, "-l gbz80\n");
-        }
-    }
+          char crt0path[PATH_MAX];
+          FILE * crt0fp;
+          for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
+            {
+              sprintf (crt0path, "%s%s%s%scrt0.o",
+                s, DIR_SEPARATOR_STRING, c, DIR_SEPARATOR_STRING);
 
-  /* additional libraries if any */
-  for (s = setFirstItem(libFilesSet); s != NULL; s = setNextItem(libFilesSet))
-    fprintf (lnkfile, "-l %s\n", s);
-
-  /*For the z80 and gbz80 ports, try to find where crt0.o is...
-  It is very important for this file to be first on the linking proccess
-  so the areas are set in the correct order, expecially _GSINIT*/
-  if (TARGET_IS_Z80 || TARGET_IS_GBZ80) /*For the z80, gbz80*/
-  {
-      char crt0path[PATH_MAX];
-      FILE * crt0fp;
-      for (s = setFirstItem(libDirsSet); s != NULL; s = setNextItem(libDirsSet))
-      {
-          sprintf (crt0path, "%s%s%s%scrt0.o",
-             s, DIR_SEPARATOR_STRING, c, DIR_SEPARATOR_STRING);
-          
-          crt0fp=fopen(crt0path, "r");
-          if(crt0fp!=NULL)/*Found it!*/
-          {
-              fclose(crt0fp);
-              #ifdef __CYGWIN__
-              {
-                 /*The CYGWIN version of the z80-gbz80 linker is getting confused with
-                 windows paths, so convert them to the CYGWIN format*/
-                 char posix_path[PATH_MAX];
-                 void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
-                 cygwin_conv_to_full_posix_path(crt0path, posix_path);
-                 strcpy(crt0path, posix_path);
-              }
-              #endif
-              fprintf (lnkfile, "%s\n", crt0path);
-              break;
-          }
-      }
-      if(s==NULL) fprintf (stderr, "Warning: couldn't find crt0.o\n");
-  }
+              crt0fp=fopen(crt0path, "r");
+              if(crt0fp!=NULL)/*Found it!*/
+                {
+                  fclose(crt0fp);
+                  #ifdef __CYGWIN__
+                  {
+                    /*The CYGWIN version of the z80-gbz80 linker is getting confused with
+                    windows paths, so convert them to the CYGWIN format*/
+                    char posix_path[PATH_MAX];
+                    void cygwin_conv_to_full_posix_path(char * win_path, char * posix_path);
+                    cygwin_conv_to_full_posix_path(crt0path, posix_path);
+                    strcpy(crt0path, posix_path);
+                  }
+                  #endif
+                  fprintf (lnkfile, "%s\n", crt0path);
+                  break;
+                }
+            }
+          if(s==NULL) fprintf (stderr, "Warning: couldn't find crt0.o\n");
+        }
 
-  /* put in the object files */
-  if (fullSrcFileName)
-    fprintf (lnkfile, "%s%s\n", dstFileName, port->linker.rel_ext);
+      /* put in the object files */
+      if (fullSrcFileName)
+        fprintf (lnkfile, "%s%s\n", dstFileName, port->linker.rel_ext);
 
-  fputStrSet(lnkfile, relFilesSet);
+      fputStrSet(lnkfile, relFilesSet);
 
-  fprintf (lnkfile, "\n-e\n");
-  fclose (lnkfile);
+      fprintf (lnkfile, "\n-e\n");
+      fclose (lnkfile);
+    } /* if(port->linker.needLinkerScript) */
 
   if (options.verbose)
     printf ("sdcc: Calling linker...\n");
@@ -1548,25 +1582,34 @@ linkEdit (char **envp)
           *strrchr (scratchFileName, '.') = '\0';
         }
       strncatz (scratchFileName, 
-               options.out_fmt ? ".S19" : ".ihx",
-               sizeof(scratchFileName));
+        options.out_fmt ? ".S19" : ".ihx",
+        sizeof(scratchFileName));
     }
 
   if (port->linker.cmd)
     {
       char buffer2[PATH_MAX];
+      set *libSet=NULL;
 
-       /* VR 030517 - gplink needs linker options to set the linker script,*/
-       buildCmdLine (buffer2, port->linker.cmd, dstFileName, scratchFileName, NULL, linkOptionsSet);
+      if(TARGET_IS_PIC16) {
+         /* use $3 to set the linker include directories */
+         libSet = appendStrSet(libDirsSet, "-I\"", "\"");
 
-       buildCmdLine2 (buffer, sizeof(buffer), buffer2);
+         /* now add the libraries from command line */
+         mergeSets(&libSet, libFilesSet);
+      }
+      
+      buildCmdLine (buffer2, port->linker.cmd, dstFileName, scratchFileName, (libSet?joinStrSet(libSet):NULL), linkOptionsSet);
+      if(libSet)deleteSet(&libSet);
+
+      buildCmdLine2 (buffer, sizeof(buffer), buffer2);
     }
   else
     {
       buildCmdLine2 (buffer, sizeof(buffer), port->linker.mcmd);
     }
 
-/*  if (options.verbose)fprintf(stderr, "linker command line: %s\n", buffer); */
+  /*  if (options.verbose)fprintf(stderr, "linker command line: %s\n", buffer); */
 
   system_ret = my_system (buffer);
   /* TODO: most linker don't have a -o parameter */
@@ -1589,14 +1632,16 @@ linkEdit (char **envp)
           strncpyz (scratchFileName, s, sizeof(scratchFileName));
           /* strip ".rel" extension */
           p = strrchr (scratchFileName, '.');
-         if (p)
-           {
-             *p = 0;
-           }
+          if (p)
+            {
+              *p = 0;
+            }
         }
       strncatz (scratchFileName,
-               options.out_fmt ? ".S19" : ".ihx",
-               sizeof(scratchFileName));
+        options.out_fmt ? ".S19" : ".ihx",
+        sizeof(scratchFileName));
+      if (strcmp (fullDstFileName, scratchFileName))
+        unlink (fullDstFileName);
       rename (scratchFileName, fullDstFileName);
 
       strncpyz (buffer, fullDstFileName, sizeof(buffer));
@@ -1611,12 +1656,32 @@ linkEdit (char **envp)
       strncatz (scratchFileName, ".map", sizeof(scratchFileName));
       *q = 0;
       strncatz(buffer, ".map", sizeof(buffer));
+      if (strcmp (scratchFileName, buffer))
+        unlink (buffer);
       rename (scratchFileName, buffer);
       *p = 0;
       strncatz (scratchFileName, ".mem", sizeof(scratchFileName));
       *q = 0;
       strncatz(buffer, ".mem", sizeof(buffer));
+      if (strcmp (scratchFileName, buffer))
+        unlink (buffer);
       rename (scratchFileName, buffer);
+      if (options.debug)
+        {
+          *p = 0;
+          strncatz (scratchFileName, ".cdb", sizeof(scratchFileName));
+          *q = 0;
+          strncatz(buffer, ".cdb", sizeof(buffer));
+          if (strcmp (scratchFileName, buffer))
+            unlink (buffer);
+          rename (scratchFileName, buffer);
+          /* and the OMF file without extension: */
+          *p = 0;
+          *q = 0;
+          if (strcmp (scratchFileName, buffer))
+            unlink (buffer);
+          rename (scratchFileName, buffer);
+        }
     }
   if (system_ret)
     {
@@ -1666,6 +1731,8 @@ assemble (char **envp)
         strncatz (scratchFileName, 
                  port->linker.rel_ext,
                  sizeof(scratchFileName));
+        if (strcmp (scratchFileName, fullDstFileName))
+          unlink (fullDstFileName);
         rename (scratchFileName, fullDstFileName);
     }
 }
@@ -2076,6 +2143,10 @@ main (int argc, char **argv, char **envp)
           glue();
         }
 
+      if (fatalError) {
+        exit (1);
+      }
+
       if (!options.c1mode && !noAssemble)
         {
           if (options.verbose)