Skip to content
  • Moritz Angermann's avatar
    Always allow -staticlib · b8f33bc6
    Moritz Angermann authored and Ben Gamari's avatar Ben Gamari committed
    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
    b8f33bc6