427 lines
11 KiB
Bash
Executable file
427 lines
11 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
CONFIG="config.mk"
|
|
PREFIX="/usr/local"
|
|
VERSION=$(grep LIQ_VERSION_STRING lib/libimagequant.h | grep -Eo "2\.[0-9.]+")
|
|
|
|
DEBUG=
|
|
SSE=auto
|
|
OPENMP=
|
|
if [[ "$OSTYPE" =~ "darwin" ]]; then
|
|
COCOA_READER=auto
|
|
LCMS2=0
|
|
else
|
|
COCOA_READER=0
|
|
LCMS2=auto
|
|
fi
|
|
EXTRA_CFLAGS=
|
|
EXTRA_LDFLAGS=
|
|
|
|
# make gcc default compiler unless CC is already set
|
|
CC=${CC:-gcc}
|
|
|
|
help() {
|
|
printf "%4s %s\n" "" "$1"
|
|
}
|
|
|
|
for i in "$@"; do
|
|
case $i in
|
|
--help)
|
|
echo
|
|
help "--prefix= installation directory [$PREFIX]"
|
|
help "--extra-cflags= append to CFLAGS"
|
|
help "--extra-ldflags= append to LDFLAGS"
|
|
echo
|
|
help "--enable-debug"
|
|
help "--enable-sse/--disable-sse enable/disable SSE instructions"
|
|
echo
|
|
help "--with-openmp compile with multicore support"
|
|
help "--with-lcms2/--without-lcms2 compile with color profile support"
|
|
if [[ "$OSTYPE" =~ "darwin" ]]; then
|
|
help "--with-cocoa/--without-cocoa use Cocoa framework to read images"
|
|
fi
|
|
echo
|
|
help "CC=<compiler> use given compiler command"
|
|
help "CFLAGS=<flags> pass options to the compiler"
|
|
help "LDFLAGS=<flags> pass options to the linker"
|
|
echo
|
|
exit 0
|
|
;;
|
|
# Can be set before or after configure. Latter overrides former.
|
|
CC=*)
|
|
CC=${i#*=}
|
|
;;
|
|
CFLAGS=*)
|
|
CFLAGS=${i#*=}
|
|
;;
|
|
LDFLAGS=*)
|
|
LDFLAGS=${i#*=}
|
|
;;
|
|
--enable-debug)
|
|
DEBUG=1
|
|
;;
|
|
--enable-sse)
|
|
SSE=1
|
|
;;
|
|
--disable-sse)
|
|
SSE=0
|
|
;;
|
|
--with-openmp)
|
|
OPENMP=1
|
|
;;
|
|
--with-lcms2)
|
|
LCMS2=1
|
|
COCOA_READER=0
|
|
;;
|
|
--without-lcms2)
|
|
LCMS2=0
|
|
;;
|
|
--with-cocoa)
|
|
COCOA_READER=1
|
|
LCMS2=0
|
|
;;
|
|
--without-cocoa)
|
|
COCOA_READER=0
|
|
;;
|
|
--prefix=*)
|
|
PREFIX=${i#*=}
|
|
;;
|
|
# can be used multiple times or in quotes to set multiple flags
|
|
--extra-cflags=*)
|
|
EXTRA_CFLAGS="$EXTRA_CFLAGS ${i#*=}"
|
|
;;
|
|
--extra-ldflags=*)
|
|
EXTRA_LDFLAGS="$EXTRA_LDFLAGS ${i#*=}"
|
|
;;
|
|
*)
|
|
echo "error: unknown switch ${i%%=*} (see $0 --help for the list)"
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# If someone runs sudo make install as very first command, and configure later,
|
|
# $CONFIG cannot be overwritten, and must be deleted before continuing.
|
|
if [[ -f "$CONFIG" && ! -w "$CONFIG" ]]; then
|
|
echo "Cannot overwrite file $CONFIG! Please delete it."
|
|
exit 1
|
|
fi
|
|
|
|
cflags() {
|
|
CFLAGS="$CFLAGS $1"
|
|
}
|
|
|
|
lflags() {
|
|
LDFLAGS="$LDFLAGS $1"
|
|
}
|
|
|
|
status() {
|
|
printf "%10s: %s\n" "$1" "$2"
|
|
}
|
|
|
|
# Append to CFLAGS if compiler supports flag, with optional prerequisite.
|
|
# Fails on errors and warnings.
|
|
conditional_cflags() {
|
|
if [ -z "echo | $("$CC" -xc -S -o /dev/null $2 $1 2>&1)" ]; then
|
|
cflags "$1"
|
|
fi
|
|
}
|
|
|
|
# returns first matching file in directory
|
|
find_f() {
|
|
echo $(find "$1" -not -type d -name "$2" -print -quit 2> /dev/null)
|
|
}
|
|
|
|
# returns first matching file in directory (no symlinks)
|
|
find_h() {
|
|
echo $(find "$1" -type f -name "$2" -print -quit 2> /dev/null)
|
|
}
|
|
|
|
find_pkgconfig() {
|
|
LIBNAME=$1
|
|
if pkg-config --exists "$LIBNAME" &> /dev/null; then
|
|
cflags "$(pkg-config --cflags "$LIBNAME")"
|
|
lflags "$(pkg-config --libs "$LIBNAME")"
|
|
status "$LIBNAME" "shared ($(pkg-config --modversion "$LIBNAME"))"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
find_static() {
|
|
LIBNAME=$1
|
|
HEADERPATTERN=$2
|
|
STATICPATTERN=$3
|
|
|
|
HPATH=$(find_h . "$HEADERPATTERN")
|
|
if [ -n "$HPATH" ]; then
|
|
APATH=$(find_f . "$STATICPATTERN")
|
|
if [ -n "$APATH" ]; then
|
|
cflags "-I${HPATH%/*}"
|
|
lflags "${APATH}"
|
|
status "$LIBNAME" "static"
|
|
return 0
|
|
fi
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
find_library() {
|
|
LIBNAME=$1
|
|
DYNAMICLIBNAME=$2
|
|
HEADERPATTERN=$3
|
|
STATICPATTERN=$4
|
|
DYNAMICPATTERN=$5
|
|
|
|
# try static in current directory first
|
|
if find_static "$LIBNAME" "$HEADERPATTERN" "$STATICPATTERN"; then
|
|
return 0;
|
|
fi
|
|
|
|
# try shared
|
|
if find_pkgconfig "$LIBNAME"; then
|
|
return 0
|
|
fi
|
|
|
|
for i in "${DIRS[@]}"; do
|
|
DIR=($i)
|
|
HPATH=$(find_h "${DIR[0]}" "$HEADERPATTERN")
|
|
if [ -n "$HPATH" ]; then
|
|
SOPATH=$(find_f "${DIR[1]}" "$DYNAMICPATTERN")
|
|
if [ -n "$SOPATH" ]; then
|
|
cflags "-I${HPATH%/*}"
|
|
lflags "-L${SOPATH%/*} -l$DYNAMICLIBNAME"
|
|
status "$LIBNAME" "shared ... $SOPATH"
|
|
return 0
|
|
fi
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
# returns full png.h version string
|
|
pngh_string() {
|
|
echo "$(grep -m1 "define PNG_LIBPNG_VER_STRING" "$1" | \
|
|
grep -Eo '"[^"]+"' | grep -Eo '[^"]+')"
|
|
}
|
|
|
|
# returns major minor version numbers from png.h
|
|
pngh_majmin() {
|
|
local MAJ=$(grep -m1 "define PNG_LIBPNG_VER_MAJOR" "$1" | grep -Eo "[0-9]+")
|
|
local MIN=$(grep -m1 "define PNG_LIBPNG_VER_MINOR" "$1" | grep -Eo "[0-9]+")
|
|
echo "${MAJ}${MIN}"
|
|
}
|
|
|
|
error() {
|
|
status "$1" "error ... $2"
|
|
echo
|
|
exit 1
|
|
}
|
|
|
|
echo
|
|
|
|
# basic check
|
|
if ! echo "int main(){}" | "$CC" -xc -std=c99 -o /dev/null - &> /dev/null; then
|
|
error "Compiler" "$CC failed to compile anything (make sure it's installed and supports C99)"
|
|
fi
|
|
|
|
status "Compiler" "$CC"
|
|
|
|
# init flags
|
|
CFLAGS=${CFLAGS:--O3 -fno-math-errno -funroll-loops -fomit-frame-pointer -Wall}
|
|
cflags "-std=c99 -I."
|
|
|
|
# DEBUG
|
|
if [ -z "$DEBUG" ]; then
|
|
cflags "-DNDEBUG"
|
|
status "Debug" "no"
|
|
else
|
|
cflags "-g"
|
|
status "Debug" "yes"
|
|
fi
|
|
|
|
# SSE
|
|
if [ "$SSE" = 'auto' ]; then
|
|
if [[ "$(uname -m)" =~ (amd|x86_)64 ||
|
|
"$(grep -E -m1 "^flags" /proc/cpuinfo)" =~ "sse" ]]; then
|
|
SSE=1
|
|
fi
|
|
fi
|
|
|
|
if [ "$SSE" -eq 1 ]; then
|
|
status "SSE" "yes"
|
|
cflags "-DUSE_SSE=1"
|
|
cflags "-msse"
|
|
# Silence a later ICC warning due to -msse working slightly different.
|
|
conditional_cflags "-wd10121"
|
|
# Must be set explicitly for GCC on x86_32. Other compilers imply it.
|
|
conditional_cflags "-mfpmath=sse" "-msse"
|
|
elif [ "$SSE" -eq 0 ]; then
|
|
status "SSE" "no"
|
|
cflags "-DUSE_SSE=0"
|
|
fi
|
|
|
|
# OpenMP
|
|
if [ -n "$OPENMP" ]; then
|
|
if [[ "$("$CC" -xc -E -fopenmp <(echo "#ifdef _OPENMP
|
|
#include <omp.h>
|
|
#endif") 2>&1)" =~ "omp_get_thread_num" ]]; then
|
|
cflags "-fopenmp"
|
|
lflags "-fopenmp"
|
|
status "OpenMP" "yes"
|
|
else
|
|
error "OpenMP" "not supported by compiler (please install a compiler that supports OpenMP (e.g. gcc) and specify it with the CC= argument)"
|
|
fi
|
|
else
|
|
# silence warnings about omp pragmas
|
|
cflags "-Wno-unknown-pragmas"
|
|
conditional_cflags "-wd3180" # ICC
|
|
status "OpenMP" "no"
|
|
fi
|
|
|
|
# Cocoa
|
|
if [[ "$OSTYPE" =~ "darwin" ]]; then
|
|
cflags "-mmacosx-version-min=10.6"
|
|
lflags "-mmacosx-version-min=10.6"
|
|
|
|
if [ "$COCOA_READER" != 0 ] && "$CC" 2>/dev/null 1>/dev/null -xc -E <(echo "#import <Cocoa/Cocoa.h>"); then
|
|
COCOA_READER=1
|
|
cflags "-DUSE_COCOA=1"
|
|
lflags "-framework Cocoa"
|
|
status "Cocoa" "yes"
|
|
else
|
|
status "Cocoa" "no"
|
|
fi
|
|
fi
|
|
|
|
# pairs of possible *.h and lib*.so locations
|
|
DIRS=("/usr/local/include /usr/local/lib"
|
|
"/usr/include /usr/lib"
|
|
"/opt/local/include /opt/local/lib" # macports
|
|
)
|
|
|
|
if [[ "$OSTYPE" =~ "darwin" ]]; then
|
|
SOLIBSUFFIX=dylib
|
|
|
|
# Search Developer SDK paths, since Apple seems to have dropped the standard Unixy ones
|
|
XCODE_CMD="xcode-select"
|
|
XCODE_PATH=$($XCODE_CMD -p)
|
|
DIRS+=("$XCODE_PATH/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include $XCODE_PATH/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/lib")
|
|
DIRS+=("$XCODE_PATH/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/include $XCODE_PATH/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/lib")
|
|
else
|
|
SOLIBSUFFIX=so
|
|
fi
|
|
|
|
|
|
# libpng
|
|
SUCCESS=0
|
|
# try static in current directory first
|
|
PNGH=$(find_h . "png.h")
|
|
if [ -n "$PNGH" ]; then
|
|
PNGH_STRING=$(pngh_string "$PNGH")
|
|
PNGH_MAJMIN=$(pngh_majmin "$PNGH")
|
|
if [[ -n "$PNGH_STRING" && -n "$PNGH_MAJMIN" ]]; then
|
|
LIBPNGA=$(find_f . "libpng${PNGH_MAJMIN}.a")
|
|
if [ -n "$LIBPNGA" ]; then
|
|
cflags "-I${PNGH%/*}"
|
|
lflags "${LIBPNGA}"
|
|
status "libpng" "static (${PNGH_STRING})"
|
|
SUCCESS=1
|
|
fi
|
|
fi
|
|
fi
|
|
# try shared
|
|
if [ "$SUCCESS" -eq 0 ]; then
|
|
if find_pkgconfig libpng; then
|
|
SUCCESS=1
|
|
else
|
|
for i in "${DIRS[@]}"; do
|
|
DIR=($i)
|
|
PNGH=$(find_h "${DIR[0]}" "png.h")
|
|
if [ -n "$PNGH" ]; then
|
|
PNGH_STRING=$(pngh_string "$PNGH")
|
|
PNGH_MAJMIN=$(pngh_majmin "$PNGH")
|
|
if [[ -n "$PNGH_STRING" && -n "$PNGH_MAJMIN" ]]; then
|
|
LIBPNGSO=$(find_f "${DIR[1]}" "libpng${PNGH_MAJMIN}.$SOLIBSUFFIX*")
|
|
if [ -n "$LIBPNGSO" ]; then
|
|
cflags "-I${PNGH%/*}"
|
|
lflags "-L${LIBPNGSO%/*} -lpng${PNGH_MAJMIN}"
|
|
status "libpng" "shared (${PNGH_STRING})"
|
|
SUCCESS=1
|
|
break
|
|
fi
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
if [ "$SUCCESS" -eq 0 ]; then
|
|
if [[ "$OSTYPE" =~ "darwin" ]]; then
|
|
LIBPNG_CMD='`brew install libpng`'
|
|
else
|
|
LIBPNG_CMD='`apt-get install libpng-dev` or `yum install libpng-devel`'
|
|
fi
|
|
error "libpng" "not found (try: $LIBPNG_CMD)"
|
|
fi
|
|
|
|
# zlib
|
|
if ! find_library "zlib" "z" "zlib.h" "libz.a" "libz.$SOLIBSUFFIX*"; then
|
|
error "zlib" "not found (please install zlib-devel package)"
|
|
fi
|
|
|
|
# lcms2
|
|
if [ "$LCMS2" != 0 ]; then
|
|
if find_library "lcms2" "lcms2" "lcms2.h" "liblcms2.a" "liblcms2.$SOLIBSUFFIX*"; then
|
|
cflags "-DUSE_LCMS=1"
|
|
else
|
|
if [ "$LCMS2" = 'auto' ]; then
|
|
status "lcms2" "no"
|
|
else
|
|
error "lcms2" "not found (please install libcms2-devel package)"
|
|
fi
|
|
fi
|
|
else
|
|
status "lcms2" "no"
|
|
fi
|
|
|
|
echo
|
|
|
|
# As of GCC 4.5, 387 fp math is significantly slower in C99 mode without this.
|
|
# Note: CPUs without SSE2 use 387 for doubles, even when SSE fp math is set.
|
|
conditional_cflags "-fexcess-precision=fast"
|
|
|
|
# Intel C++ Compiler
|
|
|
|
# ICC does usually only produce fast(er) code when it can optimize to the full
|
|
# capabilites of the (Intel) CPU. This is equivalent to -march=native for GCC.
|
|
conditional_cflags "-xHOST"
|
|
|
|
# Disable unsafe fp optimizations and enforce fp precision as set in the source.
|
|
conditional_cflags "-fp-model source"
|
|
|
|
# Silence a gold linker warning about string misalignment.
|
|
conditional_cflags "-falign-stack=maintain-16-byte"
|
|
|
|
lflags "-lm" # Ubuntu requires this library last, issue #38
|
|
|
|
if [ -n "$EXTRA_CFLAGS" ]; then
|
|
cflags "$EXTRA_CFLAGS"
|
|
fi
|
|
|
|
if [ -n "$EXTRA_LDFLAGS" ]; then
|
|
lflags "$EXTRA_LDFLAGS"
|
|
fi
|
|
|
|
# Overwrite previous configuration.
|
|
echo "
|
|
# auto-generated by configure
|
|
PREFIX = $PREFIX
|
|
VERSION = $VERSION
|
|
CC = $CC
|
|
CFLAGS = $CFLAGS
|
|
LDFLAGS = $LDFLAGS
|
|
COCOA_READER = $COCOA_READER
|
|
" > "$CONFIG"
|
|
|
|
# Configure static library the same way
|
|
cp "$CONFIG" lib/
|