[Dune] problem with static linking

Jö Fahlke jorrit at jorrit.de
Fri Jun 5 16:15:15 CEST 2015


Am Fri,  5. Jun 2015, 16:01:06 +0200 schrieb Arya Fallahi:
> Date: Fri, 5 Jun 2015 16:01:06 +0200
> From: Arya Fallahi <arya.fallahi at gmail.com>
> To: Markus Blatt <markus at dr-blatt.de>, "dune at dune-project.org"
>  <dune at dune-project.org>
> Subject: Re: [Dune] problem with static linking
> X-No-Auth: unauthenticated sender
> X-No-Relay: not in my network
> X-Envelope-From: <arya.fallahi at gmail.com>
> 
> Thanks Markus and Christoph for the help.
> 
> I actually ended up installing all I needed on a developer toolset.
> 
> The problem is glibc on scientific linux is generally outdated and it is an
> issue when you see all the hpc machines use SL.
> 
> I think I need to think soon about a way to produce object files with all
> the libraries embedded in it. This makes a more flexiblity in running on
> different machines.

If you go down that route, I did something similar for Xeon Phi's.  I'm
attaching my script maybe it can serve you as a template.  You'll need to
replace uses of micnativeloadex with ldd to figure out the needed libraries
and their location on the local system.

Regards,
Jö.

-- 
Jorrit (Jö) Fahlke, Institute for Computational und Applied Mathematics,
University of Münster, Orleans-Ring 10, D-48149 Münster
Tel: +49 251 83 35146 Fax: +49 251 83 32729

If you receive something that says "Send this to everyone you know,"
pretend you don't know me.
-------------- next part --------------
#!/bin/sh

set -e

quotemeta() {
    qm_arg=$1
    qm_result=
    qm_sq=
    qm_nl="
"
    qm_space=" "
    qm_tab="	"
    while [ ${#qm_arg} -gt 0 ]
    do qm_tail=${qm_arg#?}
       qm_c=${qm_arg%"$qm_tail"}
       qm_arg=$qm_tail
       case $qm_c in
       "$qm_nl") qm_sq=$qm_sq$qm_c;;
       [\|\&\;\<\>\(\)\$\`\\\"\'$qm_tab$qm_space*?[\#\~=%])
           qm_result=$qm_result${qm_sq:+\'$qm_sq\'}\\$qm_c
           qm_sq=
           ;;
       *) qm_result=$qm_result${qm_sq:+\'$qm_sq\'}$qm_c
           qm_sq=
           ;;
       esac
    done
    printf %s "$qm_result"
}

# exe= uncompress= make_prefix
make_prefix() {
    name=${exe##*/}
    cat <<EOF
#!/bin/sh
set -e
name=$(quotemeta "$name")
dir=
trap 'rm -rf "\$dir"' 0
dir=\$(mktemp -d)
case \$dir in
"") echo >&2 "Can't create temporary dir"
    exit 2
    ;;
esac
(
  cd "\$dir"
  while read -r line
        [ ENDMARK != "\$line" ]
  do :
  done
  ${uncompress:+$uncompress |} tar -xf-
) <"\$0"
"\$dir/\$name" "\$@"
exit \$?
ENDMARK
EOF
}
get_libs()
{
    micnativeloadex "$1" -l | sed '
       /Dependencies Found:/,/^$/ ! d
       /Dependencies Found:/d
       /^$/d
       s/^[:space:]*//
       /(none found)/d
    '
}

get_missing_libs()
{
    micnativeloadex "$1" -l | sed '
       /Dependencies Not Found Locally/,$ ! d
       /Dependencies Not Found Locally/d
       s/^[:space:]*//
    '
}

# exe=
warn_missing_libs()
{
    get_missing_libs "$exe" | {
        do_head=true
        while read -r lib
        do ignore=false
           for ilib in $ignored_libs
           do [ "x$ilib" = "x$lib" ] && { ignore=true; break; }
           done
           $ignore && continue
           $do_head && {
               echo >&2 "Warning: pack-for-mic: the following libraries were missing:"
               do_head=false
           }
           echo >&2 "	$lib"
        done
    }
}

# exe= compress= make_tar
make_tar()
{
    warn_missing_libs
    base=${exe##*/}
    (
        dir=
        trap 'rm -rf "$dir"' 0
        dir=$(mktemp -d)
        [ -n "$dir" ] || error 2 "Can't create temporary dir"
        mkdir -p "$dir/$base.libs"
        ln -s "$(readlink -f "$exe")" "$dir/$base.libs/"
        get_libs "$exe" | \
            while read -r lib
            do ln -s "$lib" "$dir/$base.libs/"
            done
        cd "$dir"
        cat <<EOF >"$base"
#!/bin/sh
dir=\$0.libs
name=$(quotemeta "$base")
LD_LIBRARY_PATH=\$dir\${LD_LIBRARY_PATH:+:\$LD_LIBRARY_PATH}
export LD_LIBRARY_PATH
exec "\$dir/\$name" "\$@"
EOF
        chmod +x "$base"
        if [ -n "$compress" ]
        then tar_result=$(
                set +e
                {
                  { tar -chf- .; echo $? >&3; } | eval "$compress" >&4
                } 3>&1
             ) 4>&1
             exit $tar_result
        else tar -chf- .
        fi
    )
}

# exe= compress= uncompress= make_sfx
make_sfx() {
    make_prefix
    make_tar
}

help() {
    COLUMNS=${COLUMNS:-$(stty size 2>/dev/null | cut -d ' ' -f 2)}
    wopt=${COLUMNS:+-w $COLUMNS}
    cat <<EOF
pack-for-mic -- pack an executable and dependend libraries

SYNOPSIS:
    pack-for-mic [--stdout] {--sfx|--tar} [--] EXE [OUTFILE|-]
EOF
    fmt $wopt <<\EOF

Pack an executable and dependend libraries into a tarball.

In tar mode a tarball is created.  The tarball will contain the executable in
a subdirectory $(basename EXE).libs, along with any required shared libraries
that were found by micnativeloadex.  The tarball will contain a wrapper script
$(basename EXE), that will run the executable, setting LD_LIBRARY_PATH such
that the libraries can be found.

In sfx mode a tarball is generated as above.  A short shell script is
prepended that will automatically unpack the tarball into a temporary
directory and run the contained program.  The script will also take care of
cleaning the temporary directory when the program returns.

When OUTFILE is omitted, a name is automatically generated.  In tar mode this
is done by appending .tar, .tar.gz, or .tar.bz2, as appropriate.  In sfx mode
the suffix is always .sfx.  When - is given in place of OUTFILE the generated
tarball or sfx archive is written to stdout.

Giving -- inhibits any special interpretation of later parameters.  This means
filenames can safely start with -.  It also disables the special meaning of -
as OUTFILE.  If you still want to write the archive to stdout, use --stdout.

The option --stdout forces writing of the archive to stdout.  No OUTFILE
argument may be given if this option is used.

In tar mode the compression method is determined from the filename of OUTFILE,
if available, defaulting to uncompressed.  In sfx mode the compression method
defaults to gzip.  A particular compression method can be forced by giving
--plain, --gzip[=OPTS], or --bzip2[=OPTS].  OPTS may contain multiple space
seperated options, it is simply passed along to gzip or bzip2.

A custom compression method can be defined by giving --compress=COMMAND, and
optionally --uncompress=COMMAND or --ext=EXTENSION.  For sfx mode --uncompress
is mandatory when --compress was given, and --ext is mandatory when an
extension must be guessed for a tar archive.

EOF
}

error() {
    status=$1
    shift
    printf >&2 "%s\n" "$*"
    echo >&2 "Try \"pack-for-mic --help\""
    exit $status
}

mm_seen=false
stdout_mode=false
set_stdout_mode() {
    $outfile_seen && error 2 "Only one of OUTFILE and --stdout may be given"
    stdout_mode=true
}
exe=
exe_seen=false
set_exe() {
    exe=$1
    exe_seen=true
}
outfile=
outfile_seen=false
set_outfile() {
    $stdout_mode && error 2 "Only one of OUTFILE and --stdout may be given"
    case $1 in
    -) if ! $mm_seen
       then set_stdout_mode
            return
       fi;;
    esac
    outfile=$1
    outfile_seen=true
}
compress=
compress_seen=false
set_compress() {
    compress=$1
    compress_seen=true
}
uncompress=
uncompress_seen=false
set_uncompress() {
    uncompress=$1
    uncompress_seen=true
}
ext=
ext_seen=false
set_ext() {
    ext=$1
    ext_seen=true
}
set_compression() {
    set_compress "$1"
    set_uncompress "$2"
    set_ext "$3"
}
mode=

no_arg() {
    $optarg_given && error 2 "Option $opt does not take arguments"
    true
}
optional_arg() { true; }
required_arg() {
    if $optarg_given
    then return 0
    else optarg_required=true
         return 1
    fi
}

argnum=0
optarg_required=false
for arg
do if $mm_seen
   then opt=
        optarg=$arg
        optarg_given=true
   elif $optarg_required
   then optarg=$arg
        optarg_given=true
        optarg_required=false
   else case $arg in
        --*=*) opt=${arg%%=*}
               optarg=${arg#*=}
               optarg_given=true
               ;;
        --*)   opt=$arg
               optarg=
               optarg_given=false
               ;;
        -)     opt=
               optarg=$arg
               optarg_given=true
               ;;
        -?)    opt=$arg
               optarg=
               optarg_given=false
               ;;
        -*)    optarg=${arg#-?}
               opt=${arg%$optarg}
               optarg_given=true
               ;;
        *)     opt=
               optarg=$arg
               optarg_given=true
               ;;
        esac
   fi
   case $opt in
   --)             no_arg       && mm_seen=true;;
   --stdout)       no_arg       && set_stdout_mode;;
   --plain)        no_arg       && set_compression "" "" .tar;;
   --gzip)         optional_arg && set_compression "gzip $optarg" gunzip .tar.gz;;
   --bzip2)        optional_arg && set_compression "bzip2 $optarg" bunzip2 .tar.bz2;;
   --compress)     required_arg && set_compress "$optarg";;
   --uncompress)   required_arg && set_uncompress "$optarg";;
   --ext)          required_arg && set_ext "$optarg";;
   --sfx|--tar)    no_arg       && mode=${opt#--};;
   --help)         help; exit 0;;
   "")             argnum=$((argnum+1))
                   case $argnum in
                   1) set_exe "$optarg";;
                   2) set_outfile "$optarg";;
                   *) error 2 "Too many arguments";;
                   esac;;
   *)              error 2 "Unknown option: $opt";;
   esac
done
$optarg_required && error 2 "Option $opt requires an argument"
$exe_seen        || error 2 "Need an executable to pack"

case $mode in
"")  error 2 "Either --tar or --sfx is requied";;
sfx) case $compress_seen,$uncompress_seen in
     true,true) ;;
     true,false) error 2 "Uncompress command must be given if compress command is given in sfx mode";;
     false,true) ;; # OK, we won't compress, hope the uncompress command knows what it's doing
     false,false) set_compression gzip gunzip .tar.gz;;
     esac
     if $stdout_mode
     then make_sfx
     else $outfile_seen || outfile=$exe.sfx
          rm -f "$outfile"
          make_sfx >"$outfile"
          chmod +x "$outfile"
     fi
     ;;
tar) if ! { $compress_seen || $uncompress_seen || $ext_seen; }
     then if $outfile_seen
          then case $outfile in
               *.gz|*.tgz)         set_compression gzip gunzip .tar.gz;;
               *.bz2|*.tbz2|*.tbz) set_compression bzip2 bunzip2 .tar.bz2;;
               *)                  set_compression "" ""  .tar;;
               esac
          else set_compression "" ""  .tar
          fi
     fi
     if $stdout_mode
     then make_tar
     else if ! $outfile_seen
          then [ -z "$ext" ] && error 2 "Need --ext or a compression method for automatic generation of output file name"
               outfile=$exe$ext
          fi
          rm -f "$outfile"
          make_tar >"$outfile"
     fi
     ;;
esac
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 811 bytes
Desc: Digital signature
URL: <https://lists.dune-project.org/pipermail/dune/attachments/20150605/e3384cc1/attachment.sig>


More information about the Dune mailing list