## Directories to search for usable builds: ## ## - [$PFX]_INC and [$PFX]_LIB ## - the dir specified by --with-[$pfx]=* ## - each dir named [$pfx]-* under [$PFX]_BASE (descending order) ## - each dir named [$pfx]-* under $ngx_src_dir/.. (descending order) ## - system_paths (see below) ## ## Note : specifying [$PFX]_INC or [$PFX]_LIB prevents other dirs being tried ## specifying --with-[$pfx]= prevents autodiscovery of dirs ## ## Note : if this file is not in the same directory as the config file, the value ## for ngx_auto_lib_file should be changed to a relative path from that file ## e.g. : $ngx_addon_dir/libs/ngx_auto_lib ## ## TODO : explain hooks ############# ## VERSION ## ############# ngx_auto_lib_version=1001 if [ ! $ngx_auto_lib_file_version ] || [ $ngx_auto_lib_file_version -lt $ngx_auto_lib_version ]; then if [ ! $ngx_addon_dir ]; then ngx_addon_dir=`cd $(dirname $0); pwd` fi ngx_auto_lib_file="$ngx_addon_dir/ngx_auto_lib_core" ngx_auto_lib_file_version="$ngx_auto_lib_version" fi ############### ## VARIABLES ## ############### v= v="$v inc_path" v="$v incs" v="$v libs" v="$v name" v="$v path" v="$v run" v="$v test" ev= ev="$ev add_libs" ev="$ev add_path" ev="$ev build_dirs" ev="$ev build_inc_dirs" ev="$ev build_lib_dirs" ev="$ev check_macros_defined" ev="$ev check_macros_non_zero" ev="$ev defines" ev="$ev deps" ev="$ev exit_if_not_found" ev="$ev haves" ev="$ev inc_names" ev="$ev lib_files" ev="$ev lib_names" ev="$ev libs_to_add" ev="$ev modules" ev="$ev srcs" ev="$ev shared" ev="$ev test_libs" ev="$ev variables" ngx_feature_vars="$v" ngx_feature_extra_vars="$ev" ngx_feature_all_vars="$v $ev" NGX_AUTO_LIB_DEFAULT_SYSTEM_DIRS='/usr/local /usr /opt/local /opt /usr/pkg' #################### ## UTIL FUNCTIONS ## #################### to_upper() { echo "$@" | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' } to_lower() { echo "$@" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' } #################### ## INIT FUNCTIONS ## #################### ngx_auto_lib_init() { . $ngx_auto_lib_file ngx_auto_lib_init_latest $@ } ngx_auto_lib_init_latest() { # set name and prefixes if [ ! $1 ]; then echo "ngx_auto_lib_init() requires that a name be passed" exit 1 fi ngx_auto_lib_name=$1 ngx_auto_lib_module_name=$2 if [ $2 ]; then NGX_AUTO_LIB_PFX=`to_upper $2` else NGX_AUTO_LIB_PFX=`to_upper $1` fi ngx_auto_lib_pfx=`to_lower $NGX_AUTO_LIB_PFX` ngx_auto_lib_clean_feature_vars } ngx_auto_lib_clean_feature_vars() { for var in $ngx_feature_all_vars; do eval ngx_feature_$var= done } ngx_auto_lib_get_variables() { local pfx=$ngx_auto_lib_pfx local PFX=$NGX_AUTO_LIB_PFX eval NGX_AUTO_LIB_INC=\"\$${PFX}_INC\" eval NGX_AUTO_LIB_LIB=\"\$${PFX}_LIB\" eval NGX_AUTO_LIB_DIR=\"\$${PFX}\" eval NGX_AUTO_LIB_BASE=\"\$${PFX}_BASE\" eval NGX_AUTO_LIB_SEARCH_LIB_INC=\"\$${PFX}_SEARCH_LIB_INC\" eval NGX_AUTO_LIB_SEARCH_DIR=\"\$${PFX}_SEARCH_DIR\" eval NGX_AUTO_LIB_SEARCH_BASE=\"\$${PFX}_SEARCH_BASE\" eval NGX_AUTO_LIB_SEARCH_BASE_PREFIX=\"\$${PFX}_SEARCH_BASE_PREFIX\" eval NGX_AUTO_LIB_SEARCH_PARENT=\"\$${PFX}_SEARCH_PARENT\" eval NGX_AUTO_LIB_SEARCH_SYSTEM=\"\$${PFX}_SEARCH_SYSTEM\" eval NGX_AUTO_LIB_SHARED=\"\$${PFX}_SHARED\" eval NGX_AUTO_LIB_SYSTEM_DIRS=\"\$${PFX}_SYSTEM_DIR\" eval USE_NGX_AUTO_LIB=\"\$USE_${LIB}\" if [ ! "$NGX_AUTO_LIB_DIR" ]; then NGX_AUTO_LIB_DIR=NONE fi if [ ! "$USE_NGX_AUTO_LIB" ]; then if [ $ngx_feature_check_macros_defined -o $ngx_feature_check_macros_non_zero ]; then USE_NGX_AUTO_LIB=MAYBE elif [ "$ngx_feature_required" = no ]; then USE_NGX_AUTO_LIB=MAYBE else USE_NGX_AUTO_LIB=YES fi fi if [ ! "$NGX_AUTO_LIB_SYSTEM_DIRS" ]; then NGX_AUTO_LIB_SYSTEM_DIRS=$NGX_AUTO_LIB_DEFAULT_SYSTEM_DIRS fi # TODO : add _STATIC, and do searches for both static and shared libs if [ ! "$NGX_AUTO_LIB_SHARED" ]; then if [ "$ngx_feature_shared" = no ]; then NGX_AUTO_LIB_SHARED=NO else NGX_AUTO_LIB_SHARED=YES fi fi NGX_AUTO_LIB_SEARCH_DEP=NO # set default search methods # Note : these can be over-ridden by setting NGX_AUTO_LIB_SEARCH_[type]=YES|NO local auto=y if [ "$NGX_AUTO_LIB_INC" ] || [ "$NGX_AUTO_LIB_LIB" ]; then ngx_auto_lib_search LIB_INC YES auto=n fi if [ "$NGX_AUTO_LIB_DIR" != NONE ]; then ngx_auto_lib_search DIR YES auto=n fi if [ "$NGX_AUTO_LIB_BASE" ]; then ngx_auto_lib_search BASE YES auto=n fi if [ $auto = y ]; then ngx_auto_lib_search PARENT YES ngx_auto_lib_search SYSTEM YES fi ngx_auto_lib_search LIB_INC NO ngx_auto_lib_search DIR NO ngx_auto_lib_search BASE NO ngx_auto_lib_search PARENT NO ngx_auto_lib_search SYSTEM NO if [ ! "$ngx_feature_lib_names" ]; then ngx_feature_lib_names=$pfx fi if [ ! "$ngx_feature_inc_names" ]; then ngx_feature_inc_names=$ngx_feature_lib_names fi if [ ! "$ngx_feature_exit_if_not_found" ]; then ngx_feature_exit_if_not_found=yes fi } ####################### ## DEFAULT FUNCTIONS ## ####################### ngx_auto_lib_set_default() { local suffix= if [ $1 ]; then suffix="_$1" fi local def=$2 local var="NGX_AUTO_LIB$suffix" val= if [ ! `eval echo '$'$var` ]; then eval $var=\"$def\" fi #eval echo "$var = \$$var" } ngx_auto_lib_search() { ngx_auto_lib_set_default "SEARCH_$1" $2 } #################### ## SAVE FUNCTIONS ## #################### ngx_auto_lib_save_vars() { OLD_CORE_DEPS=$CORE_DEPS OLD_CORE_INCS=$CORE_INCS OLD_CORE_LIBS=$CORE_LIBS OLD_CORE_SRCS=$CORE_SRCS OLD_LINK_DEPS=$LINK_DEPS CORE_DEPS= CORE_INCS= CORE_LIBS= CORE_SRCS= LINK_DEPS= } ngx_auto_lib_reset_vars() { CORE_DEPS=$OLD_CORE_DEPS CORE_INCS=$OLD_CORE_INCS CORE_LIBS=$OLD_CORE_LIBS CORE_SRCS=$OLD_CORE_SRCS LINK_DEPS=$OLD_LINK_DEPS } ngx_auto_lib_save_feature_vars() { for var in $ngx_feature_all_vars; do eval main_ngx_feature_$var=\"\$ngx_feature_$var\" done } ngx_auto_lib_reset_feature_vars() { for var in $ngx_feature_all_vars; do eval ngx_feature_$var=\"\$main_ngx_feature_$var\" done } ######################## ## CHECKING FUNCTIONS ## ######################## ngx_auto_lib_check_auto_config() { ngx_auto_lib_save_feature_vars ngx_auto_lib_clean_feature_vars ngx_feature=$1 ngx_feature_inc_path="`echo $CFLAGS | tr ' ' '\n' | grep -- -D | tr '\n' ' '`" ngx_feature_incs="#include <$NGX_AUTO_CONFIG_H>" ngx_feature_libs= ngx_feature_path=`pwd` ngx_feature_run=no ngx_feature_test=$2 #ngx_auto_lib_print_feature_vars . auto/feature if [ $ngx_found = yes ]; then rv=0 else rv=1 fi ngx_auto_lib_reset_feature_vars return $rv } ngx_auto_lib_check_macro_defined() { for m in $@; do ngx_auto_lib_check_auto_config "$m" " #ifndef $m rubbish #endif" && return 0 done return 1 } ngx_auto_lib_check_macro_non_zero() { for m in $@; do ngx_auto_lib_check_auto_config "$m" " #if !($m) rubbish #endif" && return 0 done return 1 } ngx_auto_lib_check_require() { if [ $USE_NGX_AUTO_LIB = YES ]; then return 0 elif [ $USE_NGX_AUTO_LIB = NO ]; then return 1 fi # check if the libraries are required elsewhere for l in $ngx_feature_lib_names; do [ ! "`echo $CORE_LIBS $ADDON_LIBS | grep -w -- -l$l`" ] && return 0 done # check that any required macros are set local d=$ngx_feature_check_macros_defined local nz=$ngx_feature_check_macros_non_zero if [ "$d" ] || [ "$nz" ]; then ngx_auto_lib_check_macro_defined $d && return 0 ngx_auto_lib_check_macro_non_zero $nz && return 0 fi ngx_auto_lib_check } ngx_auto_lib_check() { return 1 } ################################## ## TEST PHASE HANDLER FUNCTIONS ## ################################## ngx_auto_lib_test() { ngx_auto_lib_test_pre_setup "$@" ngx_auto_lib_test_setup "$@" ngx_auto_lib_test_post_setup "$@" ngx_auto_lib_test_feature } ngx_auto_lib_test_pre_setup() { return 0 } ngx_auto_lib_test_setup() { local INC=$1 local LIB=$2 ngx_auto_lib_inc_dir=$INC ngx_auto_lib_lib_dir=$LIB ngx_auto_lib_reset_feature_vars if [ ! "$ngx_feature_path" ]; then ngx_feature_path="$INC" fi ngx_feature_path="$ngx_feature_path $ngx_feature_add_path" for sfx in $ngx_feature_path_suffixes; do ngx_feature_path="$ngx_feature_path $INC/$sfx" done local inc= local lib= local incs="$ngx_feature_inc_names" local libs="$ngx_feature_lib_names" local lib_files="$ngx_feature_lib_files" for inc in $incs; do ngx_feature_incs="$ngx_feature_incs #include <$inc.h>" done if [ ! "$ngx_feature_libs" ]; then if [ $NGX_AUTO_LIB_SHARED = YES ]; then if [ $NGX_RPATH = YES ]; then ngx_feature_libs="-R$LIB" fi ngx_feature_libs="$ngx_feature_libs -L$LIB" for lib in $libs; do ngx_feature_libs="$ngx_feature_libs -l$lib" done # TODO : only add --rpath when the path is not a standard system path - warn if /usr ngx_feature_libs="$ngx_feature_libs -Wl,--rpath -Wl,$LIB" else for lib in $lib_files; do ngx_feature_libs="$ngx_feature_libs $LIB/$lib" done for lib in $libs; do ngx_feature_libs="$ngx_feature_libs $LIB/lib$lib.a" done fi fi if [ ! $ngx_feature_run ]; then ngx_feature_run=no fi if [ $NGX_AUTO_LIB_SHARED = YES ]; then # Add a test to be called in auto/feature after compilation that will check # whether any libraries that are linked are in fact using the path provided to # link libraries rather than a standard path. Note : this test will work on # all linked shared objects, even if supplied directly by setting # $ngx_feature_libs instead of usign $ngx_feature_lib_names # TODO : allow for some libraries to not be checked here if desired - if part of system paths libs="`echo $ngx_feature_libs | tr ' ' '\n' | grep -- -l | sed 's|-l||g'`" local test=" for l in $libs; do o="'\`ldd '$NGX_AUTOTEST' | grep '$LIB'/lib\$l\\.so\`; if [ ! \"\$o\" ]; then chmod -x $NGX_AUTOTEST; echo Linker does not link to correct version else chmod +x $NGX_AUTOTEST; fi done' test="`echo "$test" | tr '\n' ' '`" ngx_feature_test_libs="$ngx_feature_test_libs; $test" fi ngx_feature_libs="$ngx_feature_libs $ngx_feature_add_libs" ngx_feature_libs_to_add="$ngx_feature_libs" ngx_feature_libs="$ngx_feature_libs $ngx_feature_test_libs" ngx_feature="$ngx_auto_lib_name library $ngx_feature" } ngx_auto_lib_test_post_setup() { return 0 } ngx_auto_lib_test_feature() { #ngx_auto_lib_print_feature_vars . auto/feature [ $ngx_found = yes ] && return 0 return 1 } ######################## ## TEST DIR FUNCTIONS ## ######################## ngx_auto_lib_test_dir_pair() { ngx_auto_lib_test_inc_dir=$1 ngx_auto_lib_test_lib_dir=$2 if [ $1 = $2 ]; then ngx_feature="in $1$3" else ngx_feature="in $1 and $2$3" fi ngx_auto_lib_test "$1" "$2" "$3" } ngx_auto_lib_test_dir_pairs() { ngx_auto_lib_test_dir_pair "$1/include" "$2/lib" "$3" && return 0 ngx_auto_lib_test_dir_pair "$1" "$2" "$3" && return 0 return 1 } ngx_auto_lib_test_dirs() { local msg="$1" local bdir idir ldir local bdirs=$ngx_feature_build_dirs local idirs=$ngx_feature_build_inc_dirs local ldirs=$ngx_feature_build_lib_dirs shift for dir in "$@"; do ngx_auto_lib_test_dir=$dir for ldir in $ldirs; do for idir in $idirs; do ngx_auto_lib_test_dir_pair "$dir/$idir" "$dir/$ldir" "$msg" && return 0 done done for ldir in $ldirs; do ngx_auto_lib_test_dir_pair "$dir" "$dir/$ldir" "$msg" && return 0 done for idir in $idirs; do ngx_auto_lib_test_dir_pair "$dir/$idir" "$dir" "$msg" && return 0 done for bdir in $bdirs; do ngx_auto_lib_test_dir_pairs "$dir/$bdir" "$dir/$bdir" "$msg" && return 0 done ngx_auto_lib_test_dir_pairs "$dir" "$dir" "$msg" && return 0 ngx_auto_lib_test_dir= done return 1 } ngx_auto_lib_test_install_dirs() { local msg="$1" local dir= shift for dir in "$@"; do ngx_auto_lib_test_dir=$dir ngx_auto_lib_test_dir_pair "$dir/include" "$dir/lib" "$msg" && return 0 ngx_auto_lib_test_dir= done return 1 } ngx_auto_lib_run_tests() { local name="$ngx_auto_lib_name" local pfx="$ngx_auto_lib_pfx" local PFX="$NGX_AUTO_LIB_PFX" local INC="$NGX_AUTO_LIB_INC" local LIB="$NGX_AUTO_LIB_LIB" local DIR="$NGX_AUTO_LIB_DIR" local BASE="$NGX_AUTO_LIB_BASE" local MSG="$NGX_AUTO_LIB_MSG" ngx_found=no # dependency if [ $NGX_AUTO_LIB_SEARCH_DEP = YES ]; then ngx_auto_lib_test_dir_pair "$INC" "$LIB" "$MSG" return $? fi # lib and include dirs set explicitly (e.g. $OPENSSL_INC, $OPENSSL_LIB) if [ $NGX_AUTO_LIB_SEARCH_LIB_INC = YES ]; then ngx_auto_lib_test_dir_pair "$INC" "$LIB" " (specified by \$${PFX}_INC and \$${PFX}_LIB)" && return 0 fi # path specified by ${PFX} (e.g. $OPENSSL, $PCRE) # Note : these will be set automatically by configure for OpenSSL, PCRE, Zlib etc # TODO : change to searching more than one path if [ $NGX_AUTO_LIB_SEARCH_DIR = YES ] && [ $DIR != NONE ]; then ngx_auto_lib_test_dirs " (specified by \$${PFX})" $DIR && return 0 fi # directories beginning with '$pfx-' that are in $NGX_AUTO_LIB_BASE (e.g. $OPENSSL_BASE) if [ $NGX_AUTO_LIB_SEARCH_BASE = YES ] && [ $BASE ]; then p=$NGX_AUTO_LIB_SEARCH_BASE_PREFIX if [ "$p" = YES ]; then p="!ame $pfx-*" elif [ "$p" ]; then p="!ame $p*" fi ngx_auto_lib_test_dirs " (found under \$${PFX}_BASE)" \ `find $BASE/* -maxdepth 0 -type d $p 2> /dev/null | sort -r` && return 0 fi # directories beginning with '$pfx-' that are in the same directory as the Nginx source if [ $NGX_AUTO_LIB_SEARCH_PARENT = YES ]; then local src_dir=`cd ..; pwd` ngx_auto_lib_test_dirs " (found under Nginx source parent dir)" \ `find $src_dir/* -maxdepth 0 -type d !ame $pfx-* 2> /dev/null | sort -r` && return 0 fi # system folders if [ $NGX_AUTO_LIB_SEARCH_SYSTEM = YES ]; then ngx_auto_lib_test_install_dirs "" $NGX_AUTO_LIB_SYSTEM_DIRS && return 0 fi return 1 } ####################### ## HANDLER FUNCTIONS ## ####################### ngx_auto_lib_run() { ngx_auto_lib_get_variables eval AUTO_$NGX_AUTO_LIB_PFX=NO ngx_auto_lib_check_require || return ngx_auto_lib_setup || return ngx_auto_lib_save_feature_vars ngx_auto_lib_run_tests ngx_auto_lib_post_tests || return ngx_auto_lib_finalize } ngx_auto_lib_print_feature_vars() { echo ---------------------------- for var in $ngx_feature_vars; do eval "echo ngx_feature_$var = \$ngx_feature_$var" done echo ---------------------------- } ngx_auto_lib_setup() { return 0 } ngx_auto_lib_post_tests() { return 0 } ############################# ## SET VARIABLES FUNCTIONS ## ############################# # TODO : add HTTP/ADDON settings too ngx_auto_lib_set_core_variables() { # TODO : don't add includes / libs more than once eval CORE_DEPS=\"$CORE_DEPS $ngx_feature_deps\" eval CORE_INCS=\"$CORE_INCS $ngx_feature_path\" eval CORE_LIBS=\"$CORE_LIBS $ngx_feature_libs_to_add\" eval CORE_SRCS=\"$CORE_SRCS $ngx_feature_srcs\" } ngx_auto_lib_set_generic_variables() { local INC=$ngx_auto_lib_test_inc_dir local LIB=$ngx_auto_lib_test_lib_dir modules="$modules $ngx_feature_modules" for have in $ngx_feature_haves; do . auto/have done set - $ngx_feature_defines while [ $1 ]; do have=$1 value=$2 . auto/define done local PFX=$NGX_AUTO_LIB_PFX eval USE_$PFX=NO if [ $ngx_auto_lib_test_dir ]; then eval $PFX=$ngx_auto_lib_test_dir else eval $PFX=$ngx_auto_lib_lib_dir fi if [ $NGX_AUTO_LIB_SHARED != YES ]; then for l in $ngx_feature_lib_names; do CORE_LIBS=`echo $CORE_LIBS | sed 's|-\||g'` ADDON_LIBS=`echo $ADDON_LIBS | sed 's|-\||g'` done fi eval ${PFX}_INC=$INC eval ${PFX}_LIB=$LIB eval ${PFX}_SHARED=$NGX_AUTO_LIB_SHARED eval AUTO_$PFX=YES } ngx_auto_lib_set_custom_variables() { return 0 } ######################## ## FINALIZE FUNCTIONS ## ######################## ngx_auto_lib_finalize() { ngx_auto_lib_finalize_core } ngx_auto_lib_finalize_core() { if [ $ngx_found = yes ]; then ngx_auto_lib_set_core_variables ngx_auto_lib_set_generic_variables if [ "$ngx_feature_variables" ]; then eval $ngx_feature_variables fi ngx_auto_lib_set_custom_variables elif [ $ngx_feature_exit_if_not_found = yes ]; then if [ $ngx_auto_lib_module_name ]; then module_txt=" by the $ngx_auto_lib_module_name module" else module_text= fi lib=$ngx_auto_lib_name pfx=$ngx_auto_lib_pfx PFX=$NGX_AUTO_LIB_PFX cat << END $0: error: the $lib library is required$module_txt, but cannot be found using the current configuration. In order for the compilation to succeed, you will need to install the library using your system's package installer or point the configure script to the library using one of the following variables : to define a dir to find $pfx library (source or install dir) $PFX to define $pfx lib and include dirs separately ${PFX}_LIB & ${PFX}_INC to define a base dir to search for dirs beginning with $pfx- ${PFX}_BASE e.g. $ export ${PFX}_LIB=/path/to/library/lib $ export ${PFX}_LIB=/path/to/library/include $ $0 ... END exit 1 fi }