Changeset 523
- Timestamp:
- Aug 4, 2003, 7:16:27 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/emx/src/emxomf/emxomfld.c
-
Property cvs2svn:cvs-rev
changed from
1.16
to1.17
r522 r523 1 /* emxomfld.c -- Provide an ld-like interface to LINK3861 /* emxomfld.c -- Provide an ld-like interface to the IBM and M$ linkers 2 2 Copyright (c) 1992-1998 Eberhard Mattes 3 3 … … 49 49 50 50 51 /* Whether or not linker tracing is enabled. */ 52 static int opt_t; 53 51 54 /* The output file name, specified by the -o option. */ 52 55 static const char *output_fname = NULL; … … 88 91 static name_list **add_lib_fnames = &lib_fnames; 89 92 90 /* List of LINK386 options. LINK386options can be specified with the93 /* List of linker options. Linker options can be specified with the 91 94 -O option. add_options is used to add another entry at the end of 92 95 the list. */ … … 94 97 static name_list **add_options = &options; 95 98 96 /* The command line passed to LINK386. */99 /* The command line passed to the linker. */ 97 100 static char command_line[260]; 98 101 … … 129 132 static long stack_size = 0; 130 133 131 /* The name of the linker to use. By default, LINK386 is used. This 132 can be overriden with the EMXOMFLD_LINKER environment variable. */ 133 static const char *linker_name = "link386"; 134 /* The name of the linker to use. By default, ilink is used. This 135 can be overridden with the EMXOMFLD_LINKER environment variable. */ 136 static const char *linker_name = "ilink.exe"; 137 138 /* The type of linker to use. By default we assume it's VAC365 or later 139 version of ilink. This can be overridden with the EMXOMFLD_TYPE env. 140 var. using any of the value VAC365, VAC308 and LINK386. */ 141 static const char *linker_type = "VAC365"; 134 142 135 143 /* Prototypes. */ … … 166 174 167 175 fprintf (stderr, 168 "Usage: emxomfld -o <file> [-l <lib>] [-L <libdir>] [-T <base>] [- sS]\n"176 "Usage: emxomfld -o <file> [-l <lib>] [-L <libdir>] [-T <base>] [-igtsS]\n" 169 177 " [-Zexe] [-Zdll] [-Zstack <size>] [-Zmap[=<map_file>]]\n" 170 " [-O <option>] <file>...\n"); 178 " [-O <option>] <file>...\n" 179 "\n" 180 "Environment variables:\n" 181 " EMXOMFLD_TYPE:\n" 182 " The type of linker we're using. Values: VAC365, VAC308, LINK386.\n" 183 " VAC365 ilink.exe from IBM C and C++ Compilers for OS/2 v3.6 or later.\n" 184 " VAC308 ilink.exe from Visual Age for C++ v3.08.\n" 185 " LINK386 link386 form OS/2 install or DDK.\n" 186 " EMXOMFLD_LINKER:\n" 187 " Name of the linker to use and optionally extra parameters. Spaces in the\n" 188 " linker name or path is not supported. Quotes are not supported either.\n" 189 "The default values for these two variables are VAC365 and ilink.exe.\n"); 171 190 exit (1); 172 191 } … … 239 258 240 259 241 /* Replace forward slashes `/' in NAME with backslashes `\'. LINK386242 needs backslashes in path names. */260 /* Replace forward slashes `/' in NAME with backslashes `\'. The linkers 261 requires backslashes in path names. */ 243 262 244 263 static void conv_path (char *name) … … 312 331 /* If SRC is a single comma or a single semicolon, copy it 313 332 to the output, ignoring the maximum line length. This is 314 to meet the LINK386command syntax. The maximum line333 to meet the IBM/M$ linker command syntax. The maximum line 315 334 length allows for enough commas and semicolons added this 316 335 way. */ … … 413 432 414 433 415 /* Build the environment for LINK386: define the LIB environment416 variable. */434 /* Build the environment for the IBM/M$ Linkers: define the LIB 435 environment variable. */ 417 436 418 437 static void make_env (void) … … 453 472 454 473 putenv (tmp); 474 475 if (opt_t) 476 fprintf(stderr, "*** LIB=%s\n", tmp); 455 477 } 456 478 … … 605 627 606 628 /* look for ilinker options. */ 629 if (opt_t) 630 fFlags |= WLDC_VERBOSE; 607 631 for (pOpt = options; pOpt; pOpt = pOpt->next) 608 632 if ( !strnicmp(pOpt->name, "/NOE", 4) … … 631 655 632 656 /* create the linker and to the linking. */ 657 if (opt_t) 658 fprintf(stderr, "*** Invoking weak prelinker with flags %x.\n", fFlags); 633 659 pwld = wldCreate (fFlags); 634 660 if (pwld) … … 665 691 /* complete pass 1 */ 666 692 if (!rc) 667 {693 { 668 694 rc = wldPass1 (pwld); 669 695 /* ignore unresolved externals for now. */ 670 696 if (rc == 42) 697 { 671 698 rc = 0; 672 } 699 fprintf(stderr, "Ignoring unresolved externals reported from weak prelinker."); 700 } 701 } 673 702 674 703 /* generate weak aliases. */ … … 680 709 /* cleanup the linker */ 681 710 wldDestroy (pwld); 711 712 /* last words */ 713 if (rc) 714 fprintf (stderr, "emxomfld: weak prelinker failed. (rc=%d)\n", rc); 682 715 } 683 716 else 684 717 { 685 718 rc = 8; 686 fprintf (stderr, "emxomfld: failed to create weak linker.\n"); 687 } 688 719 fprintf (stderr, "emxomfld: failed to create weak prelinker.\n"); 720 } 721 722 /* die on error. */ 689 723 if (rc) 690 724 exit(rc); 725 726 /* verbose */ 727 if (opt_t) 728 fprintf(stderr, "*** Weak prelinker done\n"); 691 729 } 692 730 … … 697 735 static void arg_init (int rsp) 698 736 { 699 command_line[0] = 0; 737 response_fname[0] = '\0'; 738 command_line[0] = '\0'; 700 739 line_len = 0; 701 740 response_flag = rsp; … … 721 760 722 761 762 /* -t output. We dump the commandline and responsefile. */ 763 static void show_spawn(const char *pszwhat) 764 { 765 if (!opt_t) 766 return; 767 fprintf(stderr, "*** Invoking %s\n %s\n", pszwhat, command_line); 768 if (response_fname[0]) 769 { /* display the responsfile content. */ 770 char sz[4096]; 771 FILE *phfile = fopen(response_fname, "r"); 772 fprintf(stderr, "--- Response file %s:\n", response_fname); 773 sz[0] = '\0'; 774 while (fgets(sz, sizeof(sz), phfile)) 775 fprintf(stderr, "%s", sz); 776 fclose(phfile); 777 if (sz[strlen(sz) - 1] != '\n') 778 fprintf(stderr, "\n"); 779 fprintf(stderr, "--- End of Response File\n"); 780 } 781 } 782 783 784 /* Execute commandline and returns the result. 785 pszwhat is used for opt_t trace information. */ 786 787 static int emxomfld_spawn(char *pszcmd, const char *pszwhat) 788 { 789 int argi; 790 char ** argv; 791 char * psz; 792 int rc; 793 794 if (opt_t) 795 show_spawn(pszwhat); 796 797 /* construct spawnvp() argument array */ 798 argi = 0; 799 argv = NULL; 800 psz = pszcmd; 801 while (psz && *psz) 802 { 803 char *psz2 = psz; 804 805 /* skip blanks. */ 806 while (*psz2 == '\t' || *psz2 == ' ') 807 psz2++; 808 809 /* find end of argument taking in account in arg quoting. */ 810 while (*psz2 && *psz2 != '\t' && *psz2 != ' ') 811 { 812 if (*psz2 == '"' || *psz2 == '\'') 813 { 814 char chQuote = *psz2++; 815 while (*psz2 && *psz2 != chQuote) 816 psz2++; 817 } 818 else 819 psz2++; 820 } 821 /* terminate and set psz2 to point to next */ 822 if (*psz2) 823 *psz2++ = '\0'; 824 825 /* add argument to argument vector. */ 826 if (!(argi % 32)) 827 argv = xrealloc(argv, argi + 32); 828 argv[argi++] = xstrdup(psz); 829 830 /* next */ 831 psz = psz2; 832 } 833 834 /* Spawn process. */ 835 rc = spawnvp(P_WAIT, argv[0], argv); 836 if (opt_t) 837 fprintf(stderr, "*** Return from %s is %d\n", pszwhat, rc); 838 839 return rc; 840 } 841 842 723 843 /* Cleanup by closing (if open) and deleting (if pressent) the 724 844 response file. This function is used with atexit(). */ … … 744 864 745 865 746 /* Main function of emxomf. Parse the command line and call LINK386747 (and optionally RC). */866 /* Main function of emxomf. Parse the command line and call the IBM/M$ 867 linker (and optionally RC). */ 748 868 749 869 int main (int argc, char *argv[]) 750 870 { 751 871 int c, rc, files; 752 int opt_i;753 872 const char *ext; 754 873 char tmp[512], *t; 755 static char emxshell [200];874 char execname[512]; 756 875 757 876 /* Get options from response files (@filename) and wildcard (*.o) on the command. */ 877 758 878 _response (&argc, &argv); 759 879 _wildcard (&argc, &argv); 760 880 761 /* Drop EMXSHELL since it can point to a Unix shell which is bad for us */762 sprintf (emxshell, "EMXSHELL=%s", getenv ("OS2_SHELL"));763 putenv (emxshell);764 765 881 /* Close and delete the response file on exit. */ 766 882 … … 769 885 /* Prepare parsing of the command line. */ 770 886 771 opt_i = FALSE;files = 0;887 files = 0; 772 888 opterr = FALSE; optmode = GETOPT_KEEP; 773 889 if (argc < 2) … … 776 892 /* Parse the command line options and other arguments. */ 777 893 778 while ((c = getopt (argc, argv, "o:O:i l:vL:T:sSxXZ:")) != EOF)894 while ((c = getopt (argc, argv, "o:O:itl:vL:T:sSxXZ:")) != EOF) 779 895 switch (c) 780 896 { 781 case 'i': /* Use /INFORMATION option of LINK386 */ 782 opt_i = TRUE; 897 case 't': 898 case 'i': /* Trace the linking process, sending /INFO to the IBM/M$ linker. */ 899 opt_t = TRUE; 783 900 break; 784 901 … … 811 928 break; 812 929 813 case 'O': /* Specify L INK386option */930 case 'O': /* Specify Linker option */ 814 931 add_name_list (&add_options, optarg); 815 932 break; … … 846 963 else 847 964 { 848 fprintf (stderr, "emxomfld: invalid option \n");965 fprintf (stderr, "emxomfld: invalid option (%s)\n", optarg); 849 966 usage (); 850 967 } … … 861 978 { 862 979 /* GCC's temporary files don't have an extension. Add a 863 dot to the end of the name to prevent LINK386from980 dot to the end of the name to prevent the linker from 864 981 adding `.obj'. */ 865 982 … … 911 1028 912 1029 default: 913 fprintf (stderr, "emxomfld: invalid option \n");1030 fprintf (stderr, "emxomfld: invalid option (%s)\n", argv[optind - 1]); 914 1031 usage (); 915 1032 } … … 937 1054 remove (output_fname); 938 1055 939 /* If neither -Zmap nor -Zmap=file is used, pass "nul" to LINK386in1056 /* If neither -Zmap nor -Zmap=file is used, pass "nul" to the linker in 940 1057 the map file field. If -Zmap is used, construct the name of the 941 1058 .map file. If -Zmap=file is used, use `file' as the name of the … … 973 1090 free(pcur->name); 974 1091 pcur->name = xstrdup(szname); 975 } 976 977 } 978 979 980 /* Start building the LINK386 command line. We can use a response 1092 fclose(phfile); 1093 } 1094 1095 } 1096 1097 /* EMXOMFLD_TYPE contains VAC365, VAC308 or LINK386 if set. If non of these 1098 we assume VAC365. 1099 EMXOMFLD_LINKER contains the linker name and perhaps extra arguments. If 1100 not set we'll use the default linker, ilink. */ 1101 1102 t = getenv ("EMXOMFLD_TYPE"); 1103 if ( t 1104 && stricmp(t, "VAC365") 1105 && stricmp(t, "VAC308") 1106 && stricmp(t, "LINK386") 1107 ) 1108 fprintf (stderr, "emxomfld: warning: '%s' is an invalid value for EMXOMFLD_TYPE.\n", t); 1109 else if (t) 1110 linker_type = t; 1111 1112 t = getenv ("EMXOMFLD_LINKER"); 1113 if (t) 1114 linker_name = t; 1115 if (opt_t) 1116 fprintf(stderr, "*** Linker : %s\n" 1117 "*** Linker type: %s\n", linker_name, linker_type); 1118 1119 1120 1121 /* Start building the linker command line. We can use a response 981 1122 file if the command line gets too long. */ 982 1123 983 1124 arg_init (TRUE); 984 1125 985 /* Default options are: 986 1126 /* 1127 For VAC365 and VAC308 the default options is: 1128 1129 /NOFR[EEFORMAT] Use /NOFREEFORMAT to allow a LINK386-compatible 1130 command line syntax, in which different types of file 1131 are grouped and separated by commas. 1132 1133 /DBGPACK If !strip_symbols then we'll add this option, which 1134 will cause type tables to be merged into one global 1135 table and so eliminating a lot of duplicate info. 1136 1137 For VAC365 additional default option is: 1138 1139 /STUB:<emxomfld-path>\os2stub.bin 1140 Causes this MZ stub to be used when linking the 1141 executables instead of the default on for the linker. 1142 1143 For LINK386 the default options is: 1144 987 1145 /BATCH Run in batch mode (disable prompting, don't 988 1146 echo response file) 1147 1148 The default options for all linkers are: 989 1149 990 1150 /NOLOGO Don't display sign-on banner … … 1000 1160 'CODE'). Not grouping neighboring code 1001 1161 segments would break sets 1002 1003 For ILINK the following option is passed: 1004 1005 /NOFR[EEFORMAT] Use /NOFREEFORMAT to allow a LINK386-compatible 1006 command line syntax, in which different types of file 1007 are grouped and separated by commas. 1162 1163 For non DLLs targets: 1164 1165 /BASE:0x10000 Base the executable an so removing extra fixups. 1166 1008 1167 */ 1009 1168 1010 t = getenv ("EMXOMFLD_LINKER"); 1011 if (t != NULL) 1012 linker_name = t; 1169 /* issue commandline */ 1013 1170 put_arg (linker_name, TRUE, FALSE); 1014 1171 1015 /* If the linker is ILINK, don't use the /BAT{CH} option */ 1016 t = _getname (linker_name); /* TODO: this assumes that the env var is a filename only. 1017 * It should be possible to add options as well. Therefore the 2nd check. */ 1018 if (strnicmp (t, "ILINK", 5) && strnicmp(linker_name, "ILINK", 5)) 1019 put_arg ("/bat", FALSE, FALSE); 1020 else 1021 put_arg ("/nofree", FALSE, FALSE); 1172 /* the next part depends on the linker type. */ 1173 if (!stricmp (linker_type, "LINK386")) 1174 put_arg ("/bat", FALSE, FALSE); 1175 else /* vac3xx: */ 1176 { 1177 put_arg ("/nofree", FALSE, FALSE); 1178 if (!strip_symbols) 1179 put_arg ("/db", FALSE, FALSE); 1180 if (map_flag) 1181 put_arg ("/map", FALSE, FALSE); 1182 1183 /* VAC365: check if we have os2stub.bin. */ 1184 if (!stricmp (linker_type, "VAC365")) 1185 { 1186 struct stat s; 1187 _execname(&execname[0], sizeof(execname)); 1188 strcpy(_getname(&execname[0]), "os2stub.bin"); 1189 1190 if (!stat (execname, &s)) 1191 { 1192 sprintf (tmp, "/STUB:%s", &execname[0]); 1193 put_arg (tmp, FALSE, FALSE); 1194 } 1195 } 1196 } 1022 1197 put_arg ("/nol", FALSE, FALSE); 1023 1198 put_arg ("/noe", FALSE, FALSE); … … 1025 1200 put_arg ("/packc", FALSE, FALSE); 1026 1201 1027 /* Add the /INFORMATION option if the -i o ption was given. This is1202 /* Add the /INFORMATION option if the -i or -t option was given. This is 1028 1203 for debugging. */ 1029 1204 1030 if (opt_ i)1205 if (opt_t) 1031 1206 put_arg ("/i", FALSE, FALSE); 1032 1207 1033 1208 /* Add the /DEBUG option if the -s option was not given. Without 1034 this, LINK386throws away debugging information. */1209 this, the linker throws away debugging information. */ 1035 1210 1036 1211 if (!strip_symbols) … … 1048 1223 if (def_fname != NULL) 1049 1224 { 1225 int token; 1050 1226 md = _md_open (def_fname); 1051 1227 if (md == NULL) … … 1054 1230 exit (2); 1055 1231 } 1056 if (_md_next_token (md) == _MD_LIBRARY) 1232 token = _md_next_token (md); 1233 if (token == _MD_LIBRARY || token == _MD_PHYSICAL || token == _MD_VIRTUAL) 1057 1234 dll_flag = TRUE; 1058 1235 _md_close (md); … … 1061 1238 if (base == NULL && !dll_flag) 1062 1239 base = "0x10000"; 1063 if (base != NULL && str cmp (base, "no") != 0)1240 if (base != NULL && stricmp (base, "no") != 0) 1064 1241 { 1065 1242 sprintf (tmp, "/bas:%s", base); … … 1069 1246 /* Add the /STACK:n option if the -Zstack option was given. */ 1070 1247 1071 if (stack_size != 0 )1248 if (stack_size != 0 && !dll_flag) 1072 1249 { 1073 1250 sprintf (tmp, "/st:0x%lx", stack_size * 1024); … … 1075 1252 } 1076 1253 1077 /* Add the LINK386options specified with -O. */1254 /* Add the linker options specified with -O. */ 1078 1255 1079 1256 put_args (options, FALSE); … … 1105 1282 arg_end (); 1106 1283 1107 /* Call LINK386 via CMD.EXE (what a waste -- but I'm lazy) and abort 1108 on failure. */ 1109 1110 rc = system (command_line); 1111 /* ILINK returns 4 on warnings: consider this as success */ 1112 if (rc == 4) rc = 0; 1113 1284 /* Call Linker and abort on failure. */ 1285 1286 rc = emxomfld_spawn (command_line, "Linker"); 1287 if (rc == 4 && !strnicmp(linker_type, "VAC3", 4)) /* Ignore iLink warnings. */ 1288 rc = 0; 1114 1289 if (rc < 0) 1115 1290 { … … 1118 1293 } 1119 1294 1120 /* Run RC if L INK386completed successfully and a binary resource1295 /* Run RC if Linker completed successfully and a binary resource 1121 1296 file was given on the command line. */ 1122 1297 … … 1124 1299 { 1125 1300 arg_init (TRUE); 1126 put_arg ("rc ", TRUE, FALSE);1301 put_arg ("rc.exe", TRUE, FALSE); 1127 1302 put_arg ("-n", FALSE, FALSE); 1128 1303 put_arg (res_fname, TRUE, TRUE); 1129 1304 put_arg (output_fname, TRUE, TRUE); 1130 1305 arg_end (); 1131 rc = system (command_line);1306 rc = emxomfld_spawn (command_line, "Resource Linker"); 1132 1307 if (rc < 0) 1133 1308 { … … 1137 1312 } 1138 1313 1139 /* If both L INK386 and RC competed successfully and the -Zexe option1314 /* If both Linker and RC completed successfully and the -Zexe option 1140 1315 was given, touch the output file (without .exe) to keep `make' 1141 1316 happy. */ … … 1143 1318 if (rc == 0 && exe_flag) 1144 1319 { 1145 char execname[512]; 1146 1320 /* find target and source filenames. */ 1147 1321 t = xstrdup (output_fname); 1148 1322 _remext (t); 1149 1150 _execname((char *)&execname, sizeof(execname));1151 strcpy(_getname((char *)&execname), "ldstub.bin");1323 _execname(&execname[0], sizeof(execname)); 1324 strcpy(_getname(&execname[0]), "ldstub.bin"); 1325 1152 1326 /* Copy stub into file */ 1153 DosCopy((char *)&execname, t, 4); 1327 if (opt_t) 1328 fprintf(stderr, "*** copy %s to %s (-Zexe)", execname, t); 1329 DosCopy(&execname[0], t, 4); 1330 1154 1331 /* Now touch it */ 1155 1332 if (utime(t, NULL)) … … 1161 1338 } 1162 1339 1163 /* Return the return code of L INK386 (or RC). */1340 /* Return the return code of Linker or RC. */ 1164 1341 1165 1342 return rc; -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.