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:

```
#!/bin/bash

# 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.
#

name=${0##*/}
target=${name%-*}

set -e

ldflags_L=()
ldflags_l=()
output=""
inputs=()
STATIC=0
DYNAMIC=1
mode=$DYNAMIC
verbose=0

# 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"
                        break
                fi
        done
}

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;;
        esac
done

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

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
        else
                MRI+="addlib $lib\n"
                continue
        fi
done
for input in "${inputs[@]}"; do
        MRI+="addmod $input\n"
done
MRI+="save\nend\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: https://phabricator.haskell.org/D3706
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"
......
Markdown is supported
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