1#!/usr/local/bin/bash
2# ===========================================================================
3#
4#                            PUBLIC DOMAIN NOTICE
5#               National Center for Biotechnology Information
6#
7#  This software/database is a "United States Government Work" under the
8#  terms of the United States Copyright Act.  It was written as part of
9#  the author's official duties as a United States Government employee and
10#  thus cannot be copyrighted.  This software/database is freely available
11#  to the public for use. The National Library of Medicine and the U.S.
12#  Government have not placed any restriction on its use or reproduction.
13#
14#  Although all reasonable efforts have been taken to ensure the accuracy
15#  and reliability of the software and data, the NLM and the U.S.
16#  Government do not and cannot warrant the performance or results that
17#  may be obtained by using this software or data. The NLM and the U.S.
18#  Government disclaim all warranties, express or implied, including
19#  warranties of performance, merchantability or fitness for any particular
20#  purpose.
21#
22#  Please cite the author in any work or product based on this material.
23#
24# ===========================================================================
25if [ "$VERBOSE" != "" ] ; then echo "$0 $*"; fi
26
27# ===========================================================================
28# input library types, and their handling
29#
30#  normal linkage
31#   -l : find shared or static
32#   -s : require static
33#   -d : ignore - will be dynamically loaded
34#
35#  static linkage
36#   -l : require static
37#   -s : require static
38#   -d : require static
39# ===========================================================================
40
41# script name
42SELF_NAME="$(basename $0)"
43
44# parameters and common functions
45source "${0%rwin.exe.sh}win.cmn.sh"
46
47# discover tool chain
48case "$LD" in
49link)
50    source "${0%exe.sh}vc++.sh"
51    ;;
52*)
53    echo "$SELF_NAME: unrecognized ld tool - '$LD'"
54    exit 5
55esac
56
57#echo "EXE_CMD=${EXE_CMD}"
58
59# EXE_CMD was started in tool-specific source
60CMD="$EXE_CMD $LDFLAGS OLE32.lib Ws2_32.lib Shell32.lib"
61
62# if building a static executable against dynamic libraries
63# the main application will substitute for name lookup
64if [ $STATIC -eq 1 ] && [ $DYLD -eq 1 ]
65then
66    CMD="$CMD $LD_EXPORT_GLOBAL $LD_MULTIPLE_DEFS"
67fi
68
69# function to convert static libraries to individual COFF files
70convert-static ()
71{
72    # list members
73    local path="$1"
74    local mbrs="$(ar -t $path)"
75
76    # create sub directory
77    rm -rf "$2" && mkdir "$2"
78    if ! cd "$2"
79    then
80        echo "$SELF_NAME: failed to cd to $2"
81        exit 5
82    fi
83    ar -x "$path"
84
85    # add source files to link
86    local m=
87    for m in $mbrs
88    do
89        CMD="$CMD $2/$m"
90    done
91
92    # return to prior location
93    cd - > /dev/null
94}
95
96# tack on object files
97CMD="$CMD $OBJS"
98
99# initial dependency upon Makefile - no vers file on Windows
100DEPS="$SRCDIR/Makefile"
101if [ "$LIBS" != "" ]
102then
103    # tack on paths
104    DIRS="$LDIRS:$XDIRS"
105
106    while [ "$DIRS" != "" ]
107    do
108        DIR="${DIRS%%:*}"
109        CURDIR="$RHOME/${DIR#$LHOME}"
110        CURDIR="$(echo $CURDIR | tr '/' '\\')"
111        [ "$CURDIR" != "" ] && CMD="$CMD /LIBPATH:$CURDIR"
112        DIRS="${DIRS#$DIR}"
113        DIRS="${DIRS#:}"
114    done
115
116    HAVE_KERNEL32=0
117    HAVE_WS2=1
118    HAVE_CLIB=0
119
120    # tack on libraries, finding as we go
121    for xLIB in $LIBS
122    do
123
124        # strip off switch
125        xLIBNAME="${xLIB#-[lsd]}"
126
127        # map xLIBNAME
128        case "$xLIBNAME" in
129        dl)
130            if [ $HAVE_KERNEL32 -ne 1 ]
131            then
132                load-ref-symbols
133                load-dynamic
134                CMD="$CMD Kernel32.lib"
135                HAVE_KERNEL32=1
136            fi
137            continue
138            ;;
139
140        ws2)
141            if [ $HAVE_WS2 -ne 1 ]
142            then
143                load-ref-symbols
144                load-dynamic
145                CMD="$CMD ws2_32.lib"
146                HAVE_WS2=1
147            fi
148            continue
149            ;;
150
151        # redirect libm to link against libc.lib in case of windows
152        # omitting the lib defaults to linking against libc.lib
153        m)
154            if [ $HAVE_CLIB -ne 1 ]
155            then
156                load-ref-symbols
157                load-dynamic
158                HAVE_CLIB=1
159            fi
160            continue
161            ;;
162
163##### TEMPORARY #####
164# use ksproc for kproc
165#    kproc)
166#        xLIBNAME=ksproc
167#        ;;
168#####################
169        esac
170
171        # look at linkage
172        case "$xLIB" in
173        -l*)
174
175            # normal or dynamic linkage
176            FOUND=0
177            if [ $STATIC -eq 0 ]
178            then
179                find-lib $xLIBNAME.lib $LDIRS
180                if [ "$xLIBPATH" != "" ]
181                then
182
183                    # found it
184                    FOUND=1
185
186                    # load dynamic
187                    load-dynamic
188                    CMD="$CMD lib$xLIBNAME.lib"
189
190                fi
191            fi
192
193            # try static only
194            if [ $FOUND -eq 0 ]
195            then
196                find-lib $xLIBNAME.a $LDIRS
197                if [ "$xLIBPATH" != "" ]
198                then
199
200                    # found it
201                    FOUND=1
202
203                    # add it to dependencies
204                    DEPS="$DEPS $xLIBPATH"
205
206                    # load static
207                    load-static
208                    [ $STATIC -eq 1 ] && load-all-symbols
209                    convert-static "$xLIBPATH" "lib$xLIBNAME"
210
211                fi
212            fi
213
214            # not found within our directories
215            if [ $FOUND -eq 0 ]
216            then
217                [ $STATIC -eq 1 ] && load-ref-symbols
218                load-dynamic
219                CMD="$CMD lib$xLIBNAME.lib"
220            fi
221            ;;
222
223        -s*)
224
225            # force static load
226            FOUND=0
227            find-lib $xLIBNAME.a $LDIRS
228            if [ "$xLIBPATH" != "" ]
229            then
230
231                # found it
232                FOUND=1
233
234                # add it to dependencies
235                DEPS="$DEPS $xLIBPATH"
236
237                # load static
238                load-static
239                [ $STATIC -eq 1 ] && load-all-symbols
240                convert-static "$xLIBPATH" "lib$xLIBNAME"
241
242            fi
243
244            # not found within our directories
245            if [ $FOUND -eq 0 ]
246            then
247                # set load to static
248                load-static
249                [ $STATIC -eq 1 ] && load-all-symbols
250                CMD="$CMD lib$xLIBNAME.lib"
251            fi
252            ;;
253
254        -d*)
255
256            FOUND=0
257            if [ $STATIC -eq 1 ]
258            then
259                find-lib $xLIBNAME.a $LDIRS
260                if [ "$xLIBPATH" != "" ]
261                then
262
263                    # found it
264                    FOUND=1
265
266                    # add it to dependencies
267                    DEPS="$DEPS $xLIBPATH"
268
269                    # load static
270                    load-static
271                    load-all-symbols
272                    convert-static "$xLIBPATH" "lib$xLIBNAME"
273
274                fi
275
276                # not found within our directories
277                if [ $FOUND -eq 0 ]
278                then
279                    load-static
280                    load-all-symbols
281
282                    CMD="$CMD lib$xLIBNAME"
283                fi
284            fi
285            ;;
286
287
288        esac
289
290    done
291fi
292
293# return to normal
294load-ref-symbols
295load-dynamic
296
297# determine current directory
298CURDIR="$(pwd)"
299
300# produce executable
301rm -f ${TARG%exe}*
302
303echo $CMD
304
305# Windows linker crashes randomly on bigger files with rc=1000, so we will loop until it completes differently
306while [ 1 ]
307do
308    ${TOP}/build/run_remotely.sh $PROXY_TOOL $RHOST $RPORT $RHOME $LHOME $CURDIR $ROUTDIR $LOUTDIR $CMD >${TARG}.out
309    STATUS=$?
310    cat ${TARG}.out
311    if [ "$STATUS" != "0" ]
312    then
313        grep "fatal error LNK1000" ${TARG}.out >/dev/null
314        if [ "$?" != "0" ]
315        then
316            exit $STATUS
317        fi
318    else
319        rm ${TARG}.out
320        break
321    fi
322    sleep 30s
323done
324
325# wait for the result file to appear (there may be a network delay)
326${TOP}/build/wait_for_file.sh ${TARG}.exe
327STATUS=$?
328if [ "$STATUS" = "1" ]
329then
330    echo "timed out, TARG='$TARG'"
331    exit $STATUS
332fi
333
334# create a link without .exe which represents make's target
335test -e ${TARG} || ln -s ${TARG}.exe ${TARG}
336
337# produce dependencies
338if [ "$DEPFILE" != "" ]
339then
340    echo "$TARG: $DEPS" > "$DEPFILE"
341fi
342
343# cleanup temporary files
344rm -f $TARG.lib $TARG.exp
345
346
347# wait for the result file to appear (there may be a network delay)
348${TOP}/build/wait_for_file.sh ${TARG}.exe
349STATUS=$?
350if [ "$STATUS" = "1" ]
351then
352    echo "timed out, TARG='$TARG'"
353    exit $STATUS
354fi
355
356# create a link without .exe which represents make's target
357test -e ${TARG} || ln -s ${TARG}.exe ${TARG}
358
359# produce dependencies
360if [ "$DEPFILE" != "" ]
361then
362    echo "$TARG: $DEPS" > "$DEPFILE"
363fi
364
365# cleanup temporary files
366rm -f $TARG.lib $TARG.exp
367