Commit b8f33bc6 authored by Moritz Angermann's avatar Moritz Angermann Committed by Ben Gamari
Browse files

Always allow -staticlib

the `-staticlib` flag is currently only supported on apple platforms,
due to the avaiablity of libtool (the apple version, which is unlike the
gnu version).  This however prevents the use of -staticlib in cases
where it would be beneficial as well.  The functionality that
`-staticlib` uses from `libtool` can be stubbed with a small script like
the following:


# This script pretends to be libtool.  And supports
# only a limited set of flags.
# It is supposed to be a stand in for libtool -static, whic
# creates a static archive.  This is done by locating all -l<lib>
# libs in the provied -L<lib path> library paths, and building an
# MRI script to create the final archive from all the libraries, and
# other provided inputs.


set -e


# find_lib <name> path path path path
function find_lib () {
        lib=$1; shift 1;
        for dir in $@; do
                if [ -f "$dir/$lib" ]; then
                        echo "$dir/$lib"

while [ "$#" -gt 0 ]; do
        case "$1" in
                -v|--verbose) verbose=1; shift 1;;
                -o) output="$2"; shift 2;;
                -L*) ldflags_L+=("${1:2:${#1}-2}"); shift 1;;
                -l*) ldflags_l+=("lib${1:2:${#1}-2}.a"); shift 1;;
                -static) mode=$STATIC; shift 1;;
                -dynamic) mode=$DYNAMIC; shift 1;;
                -Wl,*) ldflags+=("${1#*,}"); shift 1;;
                -*) echo "unknown option: $1" >&2; exit 1;;
                *) inputs+=("$1"); shift 1;;

if [ ! $mode == $STATIC ]; then
        echo "-dynamic not supported!" >&2; exit 1;

MRI="create ${output}\n"
for input in "${ldflags_l[@]}"; do
        lib=$(find_lib $input ${ldflags_L[@]})
        if [ -z $lib ]; then
                echo "Failed to find lib $input" >&2
                exit 1
                MRI+="addlib $lib\n"
for input in "${inputs[@]}"; do
        MRI+="addmod $input\n"
echo -e "$MRI" | $target-ar -M
$target-ranlib $output

if `ar` supports MRI scripts.

Reviewers: austin, bgamari

Reviewed By: bgamari

Subscribers: rwbarton, thomie

Differential Revision:
parent cb8db9bc
......@@ -2082,10 +2082,7 @@ linkDynLibCheck dflags o_files dep_packages
linkStaticLibCheck :: DynFlags -> [String] -> [InstalledUnitId] -> IO ()
linkStaticLibCheck dflags o_files dep_packages
= do
when (platformOS (targetPlatform dflags) `notElem` [OSiOS, OSDarwin]) $
throwGhcExceptionIO (ProgramError "Static archive creation only supported on Darwin/OS X/iOS")
linkBinary' True dflags o_files dep_packages
= linkBinary' True dflags o_files dep_packages
-- -----------------------------------------------------------------------------
-- Running CPP
......@@ -539,11 +539,9 @@ for example).
.. ghc-flag:: -staticlib
On Darwin/OS X/iOS only, link all passed files into a static library
suitable for linking into an iOS (when using a cross-compiler) or
Mac Xcode project. To control the name, use the :ghc-flag:`-o` ⟨name⟩ option
as usual. The default name is ``liba.a``. This should nearly always
be passed when compiling for iOS with a cross-compiler.
Link all passed files into a static library suitable for linking.
To control the name, use the :ghc-flag:`-o` ⟨name⟩ option
as usual. The default name is ``liba.a``.
.. ghc-flag:: -L ⟨dir⟩
......@@ -11,9 +11,10 @@ linkingOptions =
, flag { flagName = "-staticlib"
, flagDescription =
"On Darwin/OS X/iOS only, generate a standalone static library " ++
"(as opposed to an executable). This is the usual way to " ++
"compile for iOS."
"Generate a standalone static library (as opposed to an " ++
"executable). This is useful when cross compiling. The " ++
"library together with all its dependencies ends up in in a " ++
"single static library that can be linked against."
, flagType = DynamicFlag
, flag { flagName = "-fPIC"
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment