Changeset 33


Ignore:
Timestamp:
Apr 23, 2003, 5:17:57 AM (22 years ago)
Author:
bird
Message:

bugfix.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/misc/dllar.cmd

    • Property cvs2svn:cvs-rev changed from 1.1 to 1.2
    r32 r33  
    4646 */
    4747
    48  flag_USE_LXLITE = 1;
    49 
    50  call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs'
    51  call SysLoadFuncs
    52 
    53  parse arg cmdLine;
    54  cmdLine = cmdLine||value('DLLAR_CMDLINE',,'OS2ENVIRONMENT');
    55  outFile = '';
    56  inputFiles.0 = 0;
    57  description = '';
    58  CCFLAGS = '-s -Zcrtdll';
    59  EXTRA_CCFLAGS = '';
    60  EXPORT_BY_ORDINALS = 0;
    61  exclude_symbols = '';
    62  library_flags = '';
    63  curDir = directory();
    64  curDirS = curDir;
    65  if (right(curDirS, 1) \= '\')
    66   then curDirS = curDirS||'\';
    67 
    68  do I = 1 to words(cmdLine)
    69   tmp = word(cmdLine, I);
    70   if left(tmp, 1) = '-'
    71    then select
    72          when abbrev('output', substr(tmp, 2), 1)
    73           then do
     48    flag_USE_LXLITE = 1;
     49
     50    /*
     51     * Load REXX Util Functions.
     52     */
     53    if (RxFuncQuery('SysLoadFuncs') = 1) then
     54    do
     55        call RxFuncAdd 'SysLoadFuncs', 'RexxUtil', 'SysLoadFuncs';
     56        call SysLoadFuncs;
     57    end
     58
     59    /*
     60     * Parse commandline / setup globals.
     61     */
     62    parse arg cmdLine;
     63    cmdLine = cmdLine||value('DLLAR_CMDLINE',,'OS2ENVIRONMENT');
     64    outFile = '';
     65    inputFiles.0 = 0;
     66    description = '';
     67    CCFLAGS = '-s -Zcrtdll';
     68    EXTRA_CCFLAGS = '';
     69    EXPORT_BY_ORDINALS = 0;
     70    exclude_symbols = '';
     71    library_flags = '';
     72    curDir = directory();
     73    curDirS = curDir;
     74    if (right(curDirS, 1) \= '\') then
     75        curDirS = curDirS||'\';
     76
     77    do I = 1 to words(cmdLine)
     78        tmp = word(cmdLine, I);
     79        if left(tmp, 1) = '-' then
     80        do
     81            select
     82            when abbrev('output', substr(tmp, 2), 1) then
     83            do
    7484                i = i + 1;
    7585                outFile = word(cmdLine, i);
    76                end;
    77          when abbrev('description', substr(tmp, 2), 1)
    78           then description = GetLongArg();
    79          when abbrev('flags', substr(tmp, 2), 1)
    80           then CCFLAGS = GetLongArg();
    81          when abbrev('help', substr(tmp, 2), 1)
    82           then call PrintHelp;
    83          when abbrev('ordinals', substr(tmp, 2), 3)
    84           then EXPORT_BY_ORDINALS = 1;
    85          when abbrev('exclude', substr(tmp, 2), 2)
    86           then exclude_symbols = exclude_symbols||GetLongArg()' ';
    87          when abbrev('libflags', substr(tmp, 2), 4)
    88           then library_flags = library_flags||GetLongArg()' ';
    89          when abbrev('nocrtdll', substr(tmp, 2), 5)
    90           then CCFLAGS = '-s';
    91          otherwise
    92           EXTRA_CCFLAGS = EXTRA_CCFLAGS' 'tmp;
     86            end;
     87            when abbrev('description', substr(tmp, 2), 1) then
     88                description = GetLongArg();
     89            when abbrev('flags', substr(tmp, 2), 1) then
     90                CCFLAGS = GetLongArg();
     91            when abbrev('help', substr(tmp, 2), 1) then
     92                call PrintHelp;
     93            when abbrev('ordinals', substr(tmp, 2), 3) then
     94                EXPORT_BY_ORDINALS = 1;
     95            when abbrev('exclude', substr(tmp, 2), 2) then
     96                exclude_symbols = exclude_symbols||GetLongArg()' ';
     97            when abbrev('libflags', substr(tmp, 2), 4) then
     98                library_flags = library_flags||GetLongArg()' ';
     99            when abbrev('nocrtdll', substr(tmp, 2), 5) then
     100                CCFLAGS = '-s';
     101            otherwise
     102                EXTRA_CCFLAGS = EXTRA_CCFLAGS' 'tmp;
     103            end /*select*/
    93104        end
    94    else do
    95          rc = SysFileTree(tmp, "files", "FO");
    96          if (rc = 0)
    97           then do J = 1 to files.0
     105        else
     106        do
     107            rc = SysFileTree(tmp, "files", "FO");
     108            if (rc = 0) then
     109            do J = 1 to files.0
    98110                inputFiles.0 = inputFiles.0 + 1;
    99111                K = inputFiles.0;
    100112                inputFiles.K = files.J;
    101                end;
    102           else files.0 = 0;
    103           if (files.0 = 0)
    104            then do
    105                  say 'ERROR: No file(s) found: "'tmp'"';
    106                  exit 4;
    107                 end;
     113            end;
     114            else
     115                files.0 = 0;
     116            if (files.0 = 0) then
     117            do
     118                say 'ERROR: No file(s) found: "'tmp'"';
     119                exit 8;
     120            end;
     121            drop files.;
    108122        end;
    109  end;
    110  if (inputFiles.0 = 0)
    111   then do
     123    end; /* iterate cmdline words */
     124
     125    /* check arg sanity */
     126    if (inputFiles.0 = 0) then
     127    do
    112128        say 'dllar: no input files'
    113129        call PrintHelp;
    114        end;
    115 
    116 /* Now extract all .o files from .a files */
    117  do I = 1 to inputFiles.0
    118   if right(inputFiles.I, 2) = '.a'
    119    then do
    120          fullname = inputFiles.I;
    121          inputFiles.I = '$_'filespec('NAME', fullname);
    122          inputFiles.I = left(inputFiles.I, length(inputFiles.I) - 2);
    123          '@mkdir 'inputFiles.I;
    124          if (rc \= 0)
    125           then do
     130    end;
     131
     132    /*
     133     * Now extract all .o files from .a files
     134     */
     135    do I = 1 to inputFiles.0
     136        if (right(inputFiles.I, 2) = '.a') then
     137        do
     138            fullname = inputFiles.I;
     139            inputFiles.I = '$_'filespec('NAME', fullname);
     140            inputFiles.I = left(inputFiles.I, length(inputFiles.I) - 2);
     141            Address CMD '@mkdir 'inputFiles.I;
     142            if (rc \= 0) then
     143            do
    126144                say 'Failed to create subdirectory ./'inputFiles.I;
    127145                call CleanUp;
    128                 exit 3;
    129                end;
    130          /* Prefix with '!' to indicate archive */
    131          inputFiles.I = '!'inputFiles.I;
    132          call doCommand('cd 'substr(inputFiles.I, 2)' & ar x 'fullname);
    133          call directory(curDir);
    134          rc = SysFileTree(substr(inputFiles.I, 2)'\*.o', 'files', 'FO');
    135          if (rc = 0)
    136           then do
     146                exit 8;
     147            end;
     148
     149            /* Prefix with '!' to indicate archive */
     150            inputFiles.I = '!'inputFiles.I;
     151            call doCommand('cd 'substr(inputFiles.I, 2)' && ar x 'fullname);
     152            call directory(curDir);
     153            rc = SysFileTree(substr(inputFiles.I, 2)'\*.o', 'files', 'FO');
     154            if (rc = 0) then
     155            do
    137156                inputFiles.0 = inputFiles.0 + 1;
    138157                K = inputFiles.0;
     
    140159                /* Remove all empty files from archive since emxexp will barf */
    141160                do J = 1 to files.0
    142                   if (stream(files.J, 'C', 'QUERY SIZE') <= 32) then
    143                     call SysFileDelete(files.J);
     161                    if (stream(files.J, 'C', 'QUERY SIZE') <= 32) then
     162                        call SysFileDelete(files.J);
    144163                end;
    145                end;
    146           else say 'WARNING: there are no files in archive "'substr(inputFiles.I, 2)'"';
     164                drop files.;
     165            end
     166            else
     167                say 'WARNING: there are no files in archive "'substr(inputFiles.I, 2)'"';
    147168        end;
    148  end;
    149 
    150  /* Now remove extra directory prefixes */
    151  do I = 1 to inputFiles.0
    152   if left(inputFiles.I, length(curDirS)) = curDirS
    153    then inputFiles.I = substr(inputFiles.I, length(curDirS) + 1);
    154  end;
    155 
    156  do_backup = 0;
    157  if (outFile = '')
    158   then do
    159          do_backup = 1;
    160          outFile = inputFiles.1;
    161        end;
    162  /* If its an archive, remove the '!' and the '$_' prefixes */
    163  if (left(outFile, 3) = '!$_')
    164   then outFile = substr(outFile, 4);
    165  dotpos = lastpos('.', outFile);
    166  if dotpos > 0
    167   then do
     169    end;
     170
     171    /*
     172     * Now remove extra directory prefixes
     173     */
     174    do I = 1 to inputFiles.0
     175        if (left(inputFiles.I, length(curDirS)) = curDirS) then
     176            inputFiles.I = substr(inputFiles.I, length(curDirS) + 1);
     177    end;
     178
     179    /*
     180     * Output filename(s).
     181     */
     182    do_backup = 0;
     183    if (outFile = '') then
     184    do
     185        do_backup = 1;
     186        outFile = inputFiles.1;
     187    end;
     188
     189    /* If its an archive, remove the '!' and the '$_' prefixes */
     190    if (left(outFile, 3) = '!$_') then
     191        outFile = substr(outFile, 4);
     192    dotpos = lastpos('.', outFile);
     193    if (dotpos > 0) then
     194    do
    168195        ext = translate(substr(outFile, dotpos + 1));
    169         if (ext = 'DLL') | (ext = 'O') | (ext = 'A')
    170          then outFile = substr(outFile, 1, dotpos - 1);
    171        end;
    172 
    173  EXTRA_CCFLAGS = substr(EXTRA_CCFLAGS, 2);
    174 
    175  defFile = outFile'.def';
    176  dllFile = outFile'.dll';
    177  arcFile = outFile'.a';
    178 
    179  if (do_backup & stream(arcFile, 'C', 'query exists') \= '')
    180   then call doCommand('ren 'arcFile' 'outFile'_s.a');
    181 
    182  tmpdefFile = '$_'filespec('NAME', defFile);
    183  call SysFileDelete(tmpdefFile);
    184  gccCmdl = '';
    185  do I = 1 to inputFiles.0
    186   if (left(inputFiles.I, 1) \= '!')
    187    then do
    188          call doCommand('emxexp -u' inputFiles.I' >>'tmpdefFile);
    189          gccCmdl = gccCmdl' 'inputFiles.I;
     196        if ((ext = 'DLL') | (ext = 'O') | (ext = 'A')) then
     197            outFile = substr(outFile, 1, dotpos - 1);
     198    end;
     199
     200    EXTRA_CCFLAGS = substr(EXTRA_CCFLAGS, 2);
     201
     202    defFile = outFile'.def';
     203    dllFile = outFile'.dll';
     204    arcFile = outFile'.a';
     205
     206    if (do_backup & stream(arcFile, 'C', 'query exists') \= '') then
     207        call doCommand('ren 'arcFile' 'outFile'_s.a');
     208
     209    /*
     210     * Extract public symbols from all the object files.
     211     */
     212    tmpdefFile = '$_'filespec('NAME', defFile);
     213    call SysFileDelete(tmpdefFile);
     214    do I = 1 to inputFiles.0
     215        if (left(inputFiles.I, 1) \= '!') then
     216            call doCommand('emxexp -u' inputFiles.I' >>'tmpdefFile);
     217    end;
     218
     219    /*
     220     * Create the def file.
     221     */                                                                         
     222    call SysFileDelete(defFile);
     223    call stream defFile, 'c', 'open write';
     224    call lineOut defFile, 'LIBRARY 'filespec('NAME', outFile)' 'library_flags;
     225    if (length(description) > 0) then
     226        call lineOut defFile, 'DESCRIPTION "'description'"';
     227    call lineOut defFile, 'EXPORTS';
     228
     229    queTmp = RxQueue('Create');
     230    queOld = RxQueue('Set', queTmp);
     231    call doCommand('cat 'tmpdefFile' | sort.exe | uniq.exe | rxqueue.exe' queTmp);
     232
     233    ordinal = 1;
     234    do while queued() > 0
     235        parse pull line;
     236        if (length(line) > 0) & (word(line, 1) \= ';') & (export_ok(line)) then
     237        do
     238            if (EXPORT_BY_ORDINALS) then
     239            do
     240                line = line||copies('   ',(71-length(line))%8)'@'ordinal' NONAME';
     241                ordinal = ordinal + 1;
     242            end;
     243            call lineOut defFile, line;
    190244        end;
    191  end;
    192 
    193  call SysFileDelete(defFile);
    194  call lineOut defFile, 'LIBRARY 'filespec('NAME', outFile)' 'library_flags;
    195  if (length(description) > 0)
    196   then call lineOut defFile, 'DESCRIPTION "'description'"';
    197  call lineOut defFile, 'EXPORTS';
    198  call doCommand('cat 'tmpdefFile' | sort | uniq | rxqueue');
    199  ordinal = 1;
    200  do while queued() > 0
    201   parse pull line;
    202   if (length(line) > 0) & (word(line, 1) \= ';') & (export_ok(line))
    203    then do
    204          if EXPORT_BY_ORDINALS
    205           then do
    206                 line = line||copies('   ',(71-length(line))%8)'@'ordinal' NONAME';
    207                 ordinal = ordinal + 1;
    208                end;
    209          call lineOut defFile, line;
    210         end;
    211  end;
    212  call stream defFile, 'C', 'CLOSE';
    213  call doCommand('rm -f 'tmpdefFile);
    214 
    215  call doCommand('gcc 'CCFLAGS' -Zdll -o 'dllFile defFile||gccCmdl' 'EXTRA_CCFLAGS);
    216  call doCommand('emximp -o 'arcFile defFile);
    217  if (flag_USE_LXLITE)
    218   then do
    219         if (EXPORT_BY_ORDINALS)
    220          then add_flags = '-ynd';
    221          else add_flags = '';
     245    end;
     246    call RxQueue 'Delete', RxQueue('Set', queOld);
     247    call stream defFile, 'C', 'CLOSE';
     248    call SysFileDelete(tmpdefFile);
     249    drop line ordinal tmpdefFile;          /* try prevent running out of memory... */
     250
     251
     252    /*
     253     * Do linking, create implib, and apply lxlite.
     254     *  We just apply long cmdline hack here to save us trouble with slashes and such.
     255     *  The hack is to make a shell script for we execute using sh.exe. (.exe is of vital importance!)
     256     *  OLD: call doCommand('gcc 'CCFLAGS' -Zdll -o 'dllFile defFile||gccCmdl' 'EXTRA_CCFLAGS);
     257     */
     258    sTmpFile = SysTempFileName('.\dllar-??.???');
     259    call lineout sTmpFile, '#!/bin/sh'
     260    call charout sTmpFile, 'gcc 'CCFLAGS' -Zdll -o 'translate(dllFile defFile, '/', '\');
     261    do I = 1 to inputFiles.0
     262        if (left(inputFiles.I, 1) \= '!') then
     263            call charout sTmpFile, ' 'translate(inputFiles.I, '/', '\');;
     264    end;
     265    call lineout sTmpFile, ' 'EXTRA_CCFLAGS
     266    call stream dsTmpFile, 'c', 'close'
     267    call doCommand 'sh.exe 'sTmpFile;
     268    call SysFileDelete sTmpFile;
     269    drop sTmpFile;
     270
     271    call doCommand('emximp -o 'arcFile defFile);
     272    if (flag_USE_LXLITE) then
     273    do
     274        add_flags = '';
     275        if (EXPORT_BY_ORDINALS) then
     276            add_flags = '-ynd';
    222277        call doCommand('lxlite -cs -t: -mrn -mln 'add_flags' 'dllFile);
    223        end;
    224  call CleanUp;
    225 exit;
    226 
     278    end;
     279
     280    /*
     281     * Successful exit.
     282     */
     283    call CleanUp 1;
     284exit 0;
     285
     286/**
     287 * Print usage and exit script with rc=1.
     288 */
    227289PrintHelp:
    228290 say 'Usage: dllar [-o[utput] output_file] [-d[escription] "dll descrption"]'
     
    258320exit 1;
    259321
     322
     323/**
     324 * Get long arg i + 1 from cmdline taking quoting into account.
     325 * @returns     Long argument.
     326 * @Uses        i, cmdline
     327 * @Modifies    i
     328 */
    260329GetLongArg:
    261  i = i + 1;
    262  _tmp_ = word(cmdLine, i);
    263  if (left(_tmp_, 1) = '"') | (left(_tmp_, 1) = "'")
    264   then do
    265         do while (i < words(cmdLine) &,
    266                   right(_tmp_, 1) \= left(_tmp_, 1))
    267          i = i + 1;
    268          if (_tmp_ = '')
    269            then _tmp_ = word(cmdLine, i);
    270            else _tmp_ = _tmp_' 'word(cmdLine, i);
     330    i = i + 1;
     331    _tmp_ = word(cmdLine, i);
     332    if (left(_tmp_, 1) = '"') | (left(_tmp_, 1) = "'") then
     333    do
     334        do while (i < words(cmdLine) & right(_tmp_, 1) \= left(_tmp_, 1))
     335            i = i + 1;
     336            if (_tmp_ = '') then
     337                _tmp_ = word(cmdLine, i);
     338            else
     339               _tmp_ = _tmp_' 'word(cmdLine, i);
    271340        end;
    272         if (right(_tmp_, 1) = left(_tmp_, 1))
    273          then _tmp_ = substr(_tmp_, 2, length(_tmp_) - 2);
    274        end;
     341        if (right(_tmp_, 1) = left(_tmp_, 1)) then
     342           _tmp_ = substr(_tmp_, 2, length(_tmp_) - 2);
     343    end;
    275344return _tmp_;
    276345
    277 export_ok:
    278  procedure expose exclude_symbols;
    279  parse arg line;
    280  do i = 1 to words(exclude_symbols)
    281   noexport = '"'word(exclude_symbols, i);
    282   if right(noexport, 1) = '*'
    283    then noexport = left(noexport, length(noexport) - 1)
    284    else noexport = noexport'"';
    285   if pos(noexport, line) > 0
    286    then return 0;
    287  end;
     346/**
     347 * Checks if the export is ok or not.
     348 * @returns 1 if ok.
     349 * @returns 0 if not ok.
     350 */
     351export_ok: procedure expose exclude_symbols;
     352    parse arg line;
     353    cWords = words(exclude_symbols)
     354    do i = 1 to cWords
     355        noexport = '"'word(exclude_symbols, i);
     356        if (right(noexport, 1) = '*') then
     357            noexport = left(noexport, length(noexport) - 1)
     358        else
     359            noexport = noexport'"';
     360        if (pos(noexport, line) > 0) then
     361            return 0;
     362    end;
    288363return 1;
    289364
    290 doCommand:
    291  parse arg _cmd_;
    292  say _cmd_;
    293  if (length(_cmd_) > 1023)
    294   then do
     365/**
     366 * Execute a command.
     367 * If exit code of the commnad <> 0 CleanUp() is called and we'll exit the script.
     368 * @Uses    Whatever CleanUp() uses.
     369 */
     370doCommand: procedure expose inputFiles.
     371    parse arg _cmd_;
     372    say _cmd_;
     373        if (length(_cmd_) > 1023) then
     374        do
    295375        /* Trick: use a different shell to launch the command since CMD.EXE has a
    296            1024 byte limit on the length of the command line ... */
     376         *  1024 byte limit on the length of the command line ...
     377         * Note that .exe is important!
     378         */
     379        say 'INFO: doCommand: applying commandlength hack, cmdlen:' length(_cmd_) '. (1)'
    297380        call value '__TMP__',_cmd_,'OS2ENVIRONMENT';
    298         '@sh -c "$__TMP__"';
    299        end
    300   else
    301        '@'_cmd_;
    302  if (rc \= 0)
    303  then do
    304        say 'command failed, exit code='rc;
    305        call CleanUp;
    306        exit 2;
    307       end;
     381        Address CMD 'sh.exe -c "$__TMP__"';
     382        rcCmd = rc;
     383        call value '__TMP__','','OS2ENVIRONMENT';
     384    end
     385        else
     386    do
     387            Address CMD '@'_cmd_;
     388        rcCmd = rc;
     389    end
     390
     391        if (rcCmd \= 0) then
     392    do
     393            say 'command failed, exit code='rcCmd;
     394            call CleanUp;
     395            exit rcCmd;
     396        end;
     397        drop _cmd_;                            /* prevent running out of memory... */
    308398return;
    309399
    310 CleanUp:
    311  call directory(curDir);
    312  do i = inputFiles.0 to 1 by -1
    313   if left(inputFiles.I, 1) = '!'
    314    then call doCommand('rm -rf 'substr(inputFiles.I, 2));
    315  end;
     400/*
     401 * Cleanup temporary files and output
     402 * @Uses    inputFiles.
     403 * @Uses    out
     404 */
     405CleanUp: procedure expose inputFiles. outFile
     406    parse arg fSuccess
     407    call directory(curDir);
     408    do i = inputFiles.0 to 1 by -1
     409        if (left(inputFiles.I, 1) = '!') then
     410            Address CMD 'rm -rf' substr(inputFiles.I, 2);
     411    end;
     412
     413    /*
     414     * Kill result in case of failure as there is just to many stupid make/nmake
     415     * things out there which doesn't do this.
     416     */
     417    if (fSuccess = '') then
     418        Address CMD 'rm -f' outFile||'.a' outFile||'.def' outFile||'.dll'
    316419return;
Note: See TracChangeset for help on using the changeset viewer.