|
|
1.1 root 1: /* Call Windows NT 3.x linker. 1.1.1.2 ! root 2: Copyright (C) 1994, 1995 Free Software Foundation, Inc. 1.1 root 3: Contributed by Douglas B. Rupp ([email protected]). 4: 5: This file is part of GNU CC. 6: 7: GNU CC is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU CC is distributed in the hope that it will be useful, 13: but WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15: GNU General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU CC; see the file COPYING. If not, write to 1.1.1.2 ! root 19: the Free Software Foundation, 59 Temple Place - Suite 330, ! 20: Boston, MA 02111-1307, USA. */ 1.1 root 21: 22: #include "config.h" 23: #include <stdio.h> 24: #include <sys/types.h> 25: #include <sys/stat.h> 26: #include <stdlib.h> 27: #include <string.h> 28: #include <process.h> 29: 1.1.1.2 ! root 30: static char *concat (); ! 31: static char *concat3 (); ! 32: 1.1 root 33: /* These can be set by command line arguments */ 34: char *linker_path = 0; 35: int verbose = 0; 1.1.1.2 ! root 36: int subsystem = 0; ! 37: int entry = 0; 1.1 root 38: 39: int link_arg_max = -1; 40: char **link_args = (char **) 0; 41: int link_arg_index = -1; 42: 43: char *search_dirs = "."; 44: 45: static int is_regular_file (char *name); 46: 1.1.1.2 ! root 47: /* Add the argument contained in STR to the list of arguments to pass to the ! 48: linker */ ! 49: 1.1 root 50: static void 51: addarg (str) 52: char *str; 53: { 54: int i; 55: 56: if (++link_arg_index >= link_arg_max) 57: { 58: char **new_link_args 59: = (char **) calloc (link_arg_max + 1000, sizeof (char *)); 60: 61: for (i = 0; i <= link_arg_max; i++) 62: new_link_args [i] = link_args [i]; 63: 64: if (link_args) 65: free (link_args); 66: 67: link_arg_max += 1000; 68: link_args = new_link_args; 69: } 70: 71: link_args [link_arg_index] = str; 72: } 73: 1.1.1.2 ! root 74: /* Locate the file named in FILE_NAME in the set of paths contained in ! 75: PATH_VAL */ ! 76: 1.1 root 77: static char * 78: locate_file (file_name, path_val) 79: char *file_name; 80: char *path_val; 81: { 82: char buf [1000]; 83: int file_len = strlen (file_name); 84: char *end_path = path_val + strlen (path_val); 85: char *ptr; 86: 87: /* Handle absolute pathnames */ 88: if (file_name [0] == '/' || file_name [0] == DIR_SEPARATOR 89: || isalpha (file_name [0]) && file_name [1] == ':') 90: { 91: strncpy (buf, file_name, sizeof buf); 92: buf[sizeof buf - 1] = '\0'; 93: if (is_regular_file (buf)) 94: return strdup (buf); 95: else 96: return 0; 97: } 98: 99: if (! path_val) 100: return 0; 101: 102: for (;;) 103: { 104: for (; *path_val == PATH_SEPARATOR ; path_val++) 105: ; 106: if (! *path_val) 107: return 0; 108: 109: for (ptr = buf; *path_val && *path_val != PATH_SEPARATOR; ) 110: *ptr++ = *path_val++; 111: 112: ptr--; 113: if (*ptr != '/' && *ptr != DIR_SEPARATOR) 114: *++ptr = DIR_SEPARATOR; 115: 116: strcpy (++ptr, file_name); 117: 118: if (is_regular_file (buf)) 119: return strdup (buf); 120: } 121: 122: return 0; 123: } 124: 1.1.1.2 ! root 125: /* Given a library name in NAME, i.e. foo. Look first for libfoo.lib and then ! 126: libfoo.a in the set of directories we are allowed to search in */ ! 127: 1.1 root 128: static char * 129: expand_lib (name) 130: char *name; 131: { 132: char *lib, *lib_path; 133: 1.1.1.2 ! root 134: lib = malloc (strlen (name) + 8); 1.1 root 135: strcpy (lib, "lib"); 136: strcat (lib, name); 1.1.1.2 ! root 137: strcat (lib, ".lib"); 1.1 root 138: lib_path = locate_file (lib, search_dirs); 139: if (!lib_path) 140: { 1.1.1.2 ! root 141: strcpy (lib, "lib"); ! 142: strcat (lib, name); ! 143: strcat (lib, ".a"); ! 144: lib_path = locate_file (lib, search_dirs); ! 145: if (!lib_path) ! 146: { ! 147: fprintf ! 148: (stderr, ! 149: "Couldn't locate library: lib%s.a or lib%s.lib\n", name, name); ! 150: exit (1); ! 151: } 1.1 root 152: } 153: 154: return lib_path; 155: } 156: 1.1.1.2 ! root 157: /* Check to see if the file named in NAME is a regular file, i.e. not a ! 158: directory */ ! 159: 1.1 root 160: static int 161: is_regular_file (name) 162: char *name; 163: { 164: int ret; 165: struct stat statbuf; 166: 167: ret = stat(name, &statbuf); 168: return !ret && S_ISREG (statbuf.st_mode); 169: } 170: 1.1.1.2 ! root 171: /* Process the number of args in P_ARGC and contained in ARGV. Look for ! 172: special flags, etc. that must be handled for the Microsoft linker */ ! 173: 1.1 root 174: static void 175: process_args (p_argc, argv) 176: int *p_argc; 177: char *argv[]; 178: { 179: int i, j; 180: 181: for (i = 1; i < *p_argc; i++) 182: { 183: /* -v turns on verbose option here and is passed on to gcc */ 184: if (! strcmp (argv [i], "-v")) 185: verbose = 1; 1.1.1.2 ! root 186: else if (! strncmp (argv [i], "-g", 2)) ! 187: { ! 188: addarg ("-debugtype:coff -debug:full"); ! 189: } ! 190: else if (! strncmp (argv [i], "-stack", 6)) ! 191: { ! 192: i++; ! 193: addarg (concat ("-stack:",argv[i])); ! 194: } ! 195: else if (! strncmp (argv [i], "-subsystem", 10)) ! 196: { ! 197: subsystem = 1; ! 198: i++; ! 199: addarg (concat ("-subsystem:",argv[i])); ! 200: } ! 201: else if (! strncmp (argv [i], "-e", 2)) ! 202: { ! 203: entry = 1; ! 204: i++; ! 205: addarg (concat ("-entry:",&argv[i][1])); ! 206: } 1.1 root 207: } 208: } 209: 1.1.1.2 ! root 210: /* The main program. Spawn the Microsoft linker after fixing up the ! 211: Unix-like flags and args to be what the Microsoft linker wants */ ! 212: 1.1 root 213: main (argc, argv) 214: int argc; 215: char *argv[]; 216: { 217: int i; 218: int done_an_ali = 0; 219: int file_name_index; 220: char *pathval = getenv ("PATH"); 221: char *spawn_args [5]; 222: char *tmppathval = malloc (strlen (pathval) + 3); 223: 224: strcpy (tmppathval, ".;"); 225: pathval = strcat (tmppathval, pathval); 226: 227: linker_path = locate_file ("link32.exe", pathval); 228: if (!linker_path) 229: { 230: linker_path = locate_file ("link.exe", pathval); 231: if (!linker_path) 232: { 233: fprintf (stderr, "Couldn't locate link32 or link\n"); 234: exit (1); 235: } 236: } 237: 238: addarg (linker_path); 239: 1.1.1.2 ! root 240: process_args (&argc , argv); ! 241: if (! subsystem) addarg ("-subsystem:console"); ! 242: if (! entry) addarg ("-entry:mainCRTStartup"); ! 243: 1.1 root 244: for (i = 1; i < argc; i++) 245: { 246: int arg_len = strlen (argv [i]); 247: 248: if (!strcmp (argv [i], "-o")) 249: { 250: char *buff, *ptr; 251: int out_len; 252: 253: i++; 254: out_len = strlen (argv[i]) + 10; 255: buff = malloc (out_len); 256: strcpy (buff, "-out:"); 257: strcat (buff, argv[i]); 258: ptr = strstr (buff, ".exe"); 259: if (ptr == NULL || strlen (ptr) != 4) 260: strcat (buff, ".exe"); 261: addarg (buff); 262: } 263: else if (arg_len > 2 && !strncmp (argv [i], "-L", 2)) 264: { 265: char *nbuff, *sdbuff; 266: int j, new_len, search_dirs_len; 267: 268: new_len = strlen (&argv[i][2]); 269: search_dirs_len = strlen (search_dirs); 270: 271: nbuff = malloc (new_len + 1); 272: strcpy (nbuff, &argv[i][2]); 273: 274: for (j = 0; j < new_len; j++) 275: if (nbuff[j] == '/') nbuff[j] = DIR_SEPARATOR; 276: 277: sdbuff = malloc (search_dirs_len + new_len + 2); 278: strcpy (sdbuff, search_dirs); 279: sdbuff[search_dirs_len] = PATH_SEPARATOR; 280: sdbuff[search_dirs_len+1] = 0; 281: strcat (sdbuff, nbuff); 282: 283: search_dirs = sdbuff; 284: } 285: 286: else if (arg_len > 2 && !strncmp (argv [i], "-l", 2)) 1.1.1.2 ! root 287: { ! 288: addarg (expand_lib (&argv[i][2])); ! 289: } ! 290: else if (!strcmp (argv [i], "-v") ! 291: || !strcmp (argv [i], "-g") ! 292: || !strcmp (argv [i], "-noinhibit-exec")) ! 293: { ! 294: ; ! 295: } ! 296: else if (!strcmp (argv [i], "-stack") ! 297: || !strcmp (argv [i], "-subsystem") ! 298: || !strcmp (argv [i], "-e")) ! 299: { ! 300: i++; ! 301: } ! 302: else ! 303: { ! 304: addarg (argv [i]); ! 305: } 1.1 root 306: } 307: 308: addarg (NULL); 309: 310: if (verbose) 311: { 312: int i; 313: 314: for (i = 0; i < link_arg_index; i++) 315: printf ("%s ", link_args [i]); 316: putchar ('\n'); 317: } 318: 319: if (spawnvp (P_WAIT, linker_path, (const char * const *)link_args) != 0) 320: { 321: fprintf (stderr, "Error executing %s\n", link_args[0]); 322: exit (1); 323: } 324: 325: exit (0); 326: } 1.1.1.2 ! root 327: ! 328: static char * ! 329: concat (s1, s2) ! 330: char *s1, *s2; ! 331: { ! 332: int len1 = strlen (s1); ! 333: int len2 = strlen (s2); ! 334: char *result = malloc (len1 + len2 + 1); ! 335: ! 336: strcpy (result, s1); ! 337: strcpy (result + len1, s2); ! 338: *(result + len1 + len2) = 0; ! 339: ! 340: return result; ! 341: } ! 342: ! 343: static char * ! 344: concat3 (s1, s2, s3) ! 345: char *s1, *s2, *s3; ! 346: { ! 347: return concat (concat (s1, s2), s3); ! 348: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.