source: MondoRescue/branches/3.3/mindi-busybox/scripts/trylink@ 3909

Last change on this file since 3909 was 3621, checked in by Bruno Cornec, 10 years ago

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

  • Property svn:executable set to *
File size: 10.1 KB
Line 
1#!/bin/sh
2
3debug=false
4
5# Linker flags used:
6#
7# Informational:
8# --warn-common
9# -Map $EXE.map
10# --verbose
11#
12# Optimizations:
13# --sort-common reduces padding
14# --sort-section alignment reduces padding
15# --gc-sections throws out unused sections,
16# does not work for shared libs
17# -On Not used, maybe useful?
18#
19# List of files to link:
20# $l_list == --start-group -llib1 -llib2 --end-group
21# --start-group $O_FILES $A_FILES --end-group
22#
23# Shared library link:
24# -shared self-explanatory
25# -fPIC position-independent code
26# --enable-new-dtags ?
27# -z,combreloc ?
28# -soname="libbusybox.so.$BB_VER"
29# --undefined=lbb_main Seed name to start pulling from
30# (otherwise we'll need --whole-archive)
31# -static Not used, but may be useful! manpage:
32# "... This option can be used with -shared.
33# Doing so means that a shared library
34# is being created but that all of the library's
35# external references must be resolved by pulling
36# in entries from static libraries."
37
38
39try() {
40 printf "%s\n" "Output of:" >$EXE.out
41 printf "%s\n" "$*" >>$EXE.out
42 printf "%s\n" "==========" >>$EXE.out
43 $debug && echo "Trying: $*"
44 $@ >>$EXE.out 2>&1
45 return $?
46}
47
48check_cc() {
49 local tempname="$(mktemp)"
50 local r
51 echo "int main(int argc,char**argv){return argv?argc:0;}" >"$tempname".c
52 # Can use "-o /dev/null", but older gcc tend to *unlink it* on failure! :(
53 # Was using "-xc /dev/null", but we need a valid C program.
54 # "eval" may be needed if CFLAGS can contain
55 # '... -D"BB_VER=KBUILD_STR(1.N.M)" ...'
56 # and we need shell to process quotes!
57 $CC $CFLAGS $LDFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1
58 r=$?
59 rm -f "$tempname" "$tempname".c "$tempname".o
60 return $r
61}
62
63check_libc_is_glibc() {
64 local tempname="$(mktemp)"
65 local r
66 echo "\
67 #include <stdlib.h>
68 /* Apparently uclibc defines __GLIBC__ (compat trick?). Oh well. */
69 #if defined(__GLIBC__) && !defined(__UCLIBC__)
70 syntax error here
71 #endif
72 " >"$tempname".c
73 ! $CC $CFLAGS "$tempname".c -c -o "$tempname".o >/dev/null 2>&1
74 r=$?
75 rm -f "$tempname" "$tempname".c "$tempname".o
76 return $r
77}
78
79EXE="$1"
80CC="$2"
81CFLAGS="$3"
82LDFLAGS="$4"
83O_FILES="$5"
84A_FILES="$6"
85LDLIBS="$7"
86
87# The --sort-section option is not supported by older versions of ld
88SORT_SECTION="-Wl,--sort-section,alignment"
89if ! check_cc "-Wl,--sort-section,alignment"; then
90 echo "Your linker does not support --sort-section,alignment"
91 SORT_SECTION=""
92fi
93
94START_GROUP="-Wl,--start-group"
95END_GROUP="-Wl,--end-group"
96INFO_OPTS="-Wl,--warn-common -Wl,-Map,$EXE.map -Wl,--verbose"
97
98# gold may not support --sort-common (yet)
99SORT_COMMON="-Wl,--sort-common"
100if ! check_cc "-Wl,--sort-common"; then
101 echo "Your linker does not support --sort-common"
102 SORT_COMMON=""
103fi
104
105# Static linking against glibc produces buggy executables
106# (glibc does not cope well with ld --gc-sections).
107# See sources.redhat.com/bugzilla/show_bug.cgi?id=3400
108# Note that glibc is unsuitable for static linking anyway.
109# We are removing -Wl,--gc-sections from link command line.
110GC_SECTIONS="-Wl,--gc-sections"
111if (. ./.config && test x"$CONFIG_STATIC" = x"y") then
112 if check_libc_is_glibc; then
113 echo "Static linking against glibc, can't use --gc-sections"
114 GC_SECTIONS=""
115 fi
116fi
117# The --gc-sections option is not supported by older versions of ld
118if test -n "$GC_SECTIONS"; then
119 if ! check_cc "$GC_SECTIONS"; then
120 echo "Your linker does not support $GC_SECTIONS"
121 GC_SECTIONS=""
122 fi
123fi
124
125# Sanitize lib list (dups, extra spaces etc)
126LDLIBS=`echo "$LDLIBS" | xargs -n1 | sort | uniq | xargs`
127
128# First link with all libs. If it fails, bail out
129echo "Trying libraries: $LDLIBS"
130# "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3"
131l_list=`echo " $LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g'`
132test "x$l_list" != "x" && l_list="$START_GROUP $l_list $END_GROUP"
133try $CC $CFLAGS $LDFLAGS \
134 -o $EXE \
135 $SORT_COMMON \
136 $SORT_SECTION \
137 $GC_SECTIONS \
138 $START_GROUP $O_FILES $A_FILES $END_GROUP \
139 $l_list \
140|| {
141 echo "Failed: $l_list"
142 cat $EXE.out
143 echo 'Note: if build needs additional libraries, put them in CONFIG_EXTRA_LDLIBS.'
144 echo 'Example: CONFIG_EXTRA_LDLIBS="pthread dl tirpc audit pam"'
145 exit 1
146}
147
148# Now try to remove each lib and build without it.
149# Stop when no lib can be removed.
150while test "$LDLIBS"; do
151 $debug && echo "Trying libraries: $LDLIBS"
152 all_needed=true
153 last_needed=false
154 for one in $LDLIBS; do
155 without_one=`echo " $LDLIBS " | sed "s/ $one / /g" | xargs`
156 # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3"
157 l_list=`echo " $without_one " | sed -e 's: \([^- ][^ ]*\): -l\1:g'`
158 test x"$l_list" != x"" && l_list="$START_GROUP $l_list $END_GROUP"
159 $debug && echo "Trying -l options: '$l_list'"
160 try $CC $CFLAGS $LDFLAGS \
161 -o $EXE \
162 $SORT_COMMON \
163 $SORT_SECTION \
164 $GC_SECTIONS \
165 $START_GROUP $O_FILES $A_FILES $END_GROUP \
166 $l_list
167 if test $? = 0; then
168 echo " Library $one is not needed, excluding it"
169 LDLIBS="$without_one"
170 all_needed=false
171 last_needed=false
172 else
173 echo " Library $one is needed, can't exclude it (yet)"
174 last_needed=true
175 fi
176 done
177 # All libs were needed, can't remove any
178 $all_needed && break
179 # Optimization: was the last tried lib needed?
180 if $last_needed; then
181 # Was it the only one lib left? Don't test again then.
182 { echo "$LDLIBS" | grep -q ' '; } || break
183 fi
184done
185
186# Make the binary with final, minimal list of libs
187echo "Final link with: ${LDLIBS:-<none>}"
188l_list=`echo " $LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g'`
189test "x$l_list" != "x" && l_list="$START_GROUP $l_list $END_GROUP"
190# --verbose gives us gobs of info to stdout (e.g. linker script used)
191if ! test -f busybox_ldscript; then
192 try $CC $CFLAGS $LDFLAGS \
193 -o $EXE \
194 $SORT_COMMON \
195 $SORT_SECTION \
196 $GC_SECTIONS \
197 $START_GROUP $O_FILES $A_FILES $END_GROUP \
198 $l_list \
199 $INFO_OPTS \
200 || {
201 cat $EXE.out
202 exit 1
203 }
204else
205 echo "Custom linker script 'busybox_ldscript' found, using it"
206 # Add SORT_BY_ALIGNMENT to linker script (found in $EXE.out):
207 # .rodata : { *(.rodata SORT_BY_ALIGNMENT(.rodata.*) .gnu.linkonce.r.*) }
208 # *(.data SORT_BY_ALIGNMENT(.data.*) .gnu.linkonce.d.*)
209 # *(.bss SORT_BY_ALIGNMENT(.bss.*) .gnu.linkonce.b.*)
210 # This will eliminate most of the padding (~3kb).
211 # Hmm, "ld --sort-section alignment" should do it too.
212 #
213 # There is a ld hack which is meant to decrease disk usage
214 # at the cost of more RAM usage (??!!) in standard ld script:
215 # /* Adjust the address for the data segment. We want to adjust up to
216 # the same address within the page on the next page up. */
217 # . = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1)); . = DATA_SEGMENT_ALIGN (0x1000, 0x1000);
218 # Replace it with:
219 # . = ALIGN (0x1000); . = DATA_SEGMENT_ALIGN (0x1000, 0x1000);
220 # to unconditionally align .data to the next page boundary,
221 # instead of "next page, plus current offset in this page"
222 try $CC $CFLAGS $LDFLAGS \
223 -o $EXE \
224 $SORT_COMMON \
225 $SORT_SECTION \
226 $GC_SECTIONS \
227 -Wl,-T,busybox_ldscript \
228 $START_GROUP $O_FILES $A_FILES $END_GROUP \
229 $l_list \
230 $INFO_OPTS \
231 || {
232 cat $EXE.out
233 exit 1
234 }
235fi
236
237. ./.config
238
239sharedlib_dir="0_lib"
240
241if test "$CONFIG_BUILD_LIBBUSYBOX" = y; then
242 mkdir "$sharedlib_dir" 2>/dev/null
243 test -d "$sharedlib_dir" || {
244 echo "Cannot make directory $sharedlib_dir"
245 exit 1
246 }
247 ln -s "libbusybox.so.$BB_VER" "$sharedlib_dir"/libbusybox.so 2>/dev/null
248
249 EXE="$sharedlib_dir/libbusybox.so.${BB_VER}_unstripped"
250 try $CC $CFLAGS $LDFLAGS \
251 -o $EXE \
252 -shared -fPIC \
253 -Wl,--enable-new-dtags \
254 -Wl,-z,combreloc \
255 -Wl,-soname="libbusybox.so.$BB_VER" \
256 -Wl,--undefined=lbb_main \
257 $SORT_COMMON \
258 $SORT_SECTION \
259 $START_GROUP $A_FILES $END_GROUP \
260 $l_list \
261 $INFO_OPTS \
262 || {
263 echo "Linking $EXE failed"
264 cat $EXE.out
265 exit 1
266 }
267 $STRIP -s --remove-section=.note --remove-section=.comment $EXE -o "$sharedlib_dir/libbusybox.so.$BB_VER"
268 chmod a+x "$sharedlib_dir/libbusybox.so.$BB_VER"
269 echo "libbusybox: $sharedlib_dir/libbusybox.so.$BB_VER"
270fi
271
272if test "$CONFIG_FEATURE_SHARED_BUSYBOX" = y; then
273 EXE="$sharedlib_dir/busybox_unstripped"
274 try $CC $CFLAGS $LDFLAGS \
275 -o $EXE \
276 $SORT_COMMON \
277 $SORT_SECTION \
278 $GC_SECTIONS \
279 $START_GROUP $O_FILES $END_GROUP \
280 -L"$sharedlib_dir" -lbusybox \
281 $l_list \
282 $INFO_OPTS \
283 || {
284 echo "Linking $EXE failed"
285 cat $EXE.out
286 exit 1
287 }
288 $STRIP -s --remove-section=.note --remove-section=.comment $EXE -o "$sharedlib_dir/busybox"
289 echo "busybox linked against libbusybox: $sharedlib_dir/busybox"
290fi
291
292if test "$CONFIG_FEATURE_INDIVIDUAL" = y; then
293 echo "Linking individual applets against libbusybox (see $sharedlib_dir/*)"
294 gcc -DNAME_MAIN -E -include include/autoconf.h include/applets.h \
295 | grep -v "^#" \
296 | grep -v "^ *$" \
297 > applet_lst.tmp
298 while read name main junk; do
299
300 echo "\
301void lbb_prepare(const char *applet, char **argv);
302int $main(int argc, char **argv);
303
304int main(int argc, char **argv)
305{
306 lbb_prepare(\"$name\", argv);
307 return $main(argc, argv);
308}
309" >"$sharedlib_dir/applet.c"
310
311 EXE="$sharedlib_dir/$name"
312 try $CC $CFLAGS $LDFLAGS "$sharedlib_dir/applet.c" \
313 -o $EXE \
314 $SORT_COMMON \
315 $SORT_SECTION \
316 $GC_SECTIONS \
317 -L"$sharedlib_dir" -lbusybox \
318 -Wl,--warn-common \
319 || {
320 echo "Linking $EXE failed"
321 cat $EXE.out
322 exit 1
323 }
324 rm -- "$sharedlib_dir/applet.c" $EXE.out
325 $STRIP -s --remove-section=.note --remove-section=.comment $EXE
326 # Let user see that we do something - list the names of created binaries:
327 echo "$EXE"
328
329 done <applet_lst.tmp
330fi
331
332# libbusybox.so is needed only for -lbusybox at link time,
333# it is not needed at runtime. Deleting to reduce confusion.
334rm "$sharedlib_dir"/libbusybox.so 2>/dev/null
335exit 0 # or else we may confuse make
Note: See TracBrowser for help on using the repository browser.