Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | #! /usr/bin/env bash |
2 | ||
3 | # This script creates a static library (archive). | |
4 | # It is invoked as: static-library TARGET OS OUTPUT objects* libraries* | |
5 | # eg: static-library self mingw foo.a /tmp/obj1.o /tmp/obj2.o /lib/libmlton.a | |
6 | ||
7 | # A safe fallback for unsupported platforms is: | |
8 | # rm -f foo.a | |
9 | # ar rc foo.a /tmp/obj1.o /tmp/obj2.o | |
10 | # ranlib foo.a | |
11 | ||
12 | # However, this script tries to mimic the behaviour of shared libraries as | |
13 | # closely as possible. It links in the required bits of dependent libraries, | |
14 | # links together the given objects, and then hides all non-public symbols. | |
15 | # | |
16 | # The end result of this process is that two MLton produced static libraries | |
17 | # can safely be used at the same time since their symbols don't overlap. It | |
18 | # is even possible to use libraries produced using different versions of the | |
19 | # runtime. | |
20 | ||
21 | set -e | |
22 | ||
23 | target="$1" | |
24 | shift | |
25 | os="$1" | |
26 | shift | |
27 | output="$1" | |
28 | shift | |
29 | ||
30 | if [ "$target" = "self" ]; then target=""; else target="$target-"; fi | |
31 | ||
32 | # Change this to false is partial linking does not work on your platform | |
33 | partialLink='true' | |
34 | ||
35 | rm -f "${output}" | |
36 | ||
37 | if "$partialLink"; then | |
38 | # Localize all but export symbols. Platform dependent. | |
39 | if [ "$os" = "darwin" ]; then | |
40 | "${target}ld" -r -o "$output.o" "$@" | |
41 | # The osx linker already makes hidden symbols local | |
42 | elif [ "$os" = "mingw" -o "$os" = "cygwin" ]; then | |
43 | # Link allowing _address of stdcall function fixups | |
44 | # Preserve the export list (.drectve section) | |
45 | "${target}ld" -r --unique=.drectve --enable-stdcall-fixup -o "$output.o" "$@" | |
46 | # Extract the list of exports to make only them global | |
47 | "${target}dlltool" --output-def "$output.def" "$output.o" | |
48 | grep '@' "$output.def" \ | |
49 | | sed 's/^[[:space:]]*\([^[:space:]]*\).*$/_\1/' \ | |
50 | > "$output.globals" | |
51 | "${target}objcopy" --keep-global-symbols "$output.globals" "$output.o" | |
52 | rm "$output.def" "$output.globals" | |
53 | else | |
54 | "${target}ld" -r -o "$output.o" "$@" | |
55 | # ELF systems are all the same... localize hidden symbols | |
56 | # Be careful not to localize gcc PIC's common section thunks | |
57 | "${target}objdump" -t "$output.o" \ | |
58 | | grep ' \.hidden ' \ | |
59 | | grep -v get_pc_thunk \ | |
60 | | sed 's/^.* \.hidden //' \ | |
61 | > "$output.locals" | |
62 | "${target}objcopy" --localize-symbols "$output.locals" "$output.o" | |
63 | rm "$output.locals" | |
64 | fi | |
65 | ||
66 | # Create the final archive | |
67 | "${target}ar" rc "$output" "$output.o" | |
68 | "${target}ranlib" "$output" | |
69 | rm "$output.o" | |
70 | else | |
71 | "${target}ar" rc "$output" "$@" | |
72 | "${target}ranlib" "$output" | |
73 | fi |