├── .gitignore ├── modules ├── configure.cxx ├── configure.pic ├── configure.good_cflags ├── configure.socket ├── configure.gitversion ├── configure.libsasl2 ├── configure.zlib ├── configure.libzstd ├── configure.lib ├── configure.libcurl ├── configure.fileversion ├── configure.parseversion ├── configure.builtin ├── configure.libssl ├── configure.host ├── configure.atomics ├── configure.cc └── configure.base ├── LICENSE ├── README.md ├── setup.sh ├── configure └── Makefile.base /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | .emacs.desktop 3 | 4 | -------------------------------------------------------------------------------- /modules/configure.cxx: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # C++ detection 4 | # 5 | # This script simply limits the checks of configure.cc 6 | 7 | 8 | MKL_CC_WANT_CXX=1 9 | -------------------------------------------------------------------------------- /modules/configure.pic: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Checks if -fPIC is supported, and if so turns it on. 4 | # 5 | # Sets: 6 | # HAVE_PIC 7 | # CPPFLAGS 8 | # 9 | 10 | function checks { 11 | 12 | if mkl_compile_check PIC HAVE_PIC disable CC "-fPIC" "" ; then 13 | mkl_mkvar_append CPPFLAGS CPPFLAGS "-fPIC" 14 | fi 15 | } 16 | 17 | -------------------------------------------------------------------------------- /modules/configure.good_cflags: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Provides some known-good CFLAGS 4 | # Sets: 5 | # CFLAGS 6 | # CXXFLAGS 7 | # CPPFLAGS 8 | 9 | 10 | function checks { 11 | mkl_mkvar_append CPPFLAGS CPPFLAGS \ 12 | "-Wall -Wsign-compare -Wfloat-equal -Wpointer-arith -Wcast-align" 13 | 14 | if [[ $MKL_WANT_WERROR = "y" ]]; then 15 | mkl_mkvar_append CPPFLAGS CPPFLAGS \ 16 | "-Werror" 17 | fi 18 | } 19 | -------------------------------------------------------------------------------- /modules/configure.socket: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Provides proper compiler flags for socket support, e.g. socket(3). 4 | 5 | function checks { 6 | 7 | local src=" 8 | #include 9 | #include 10 | #include 11 | void foo (void) { 12 | int s = socket(0, 0, 0); 13 | close(s); 14 | }" 15 | if ! mkl_compile_check socket "" cont CC "" "$src"; then 16 | if mkl_compile_check --ldflags="-lsocket -lnsl" socket_nsl "" fail CC "" "$src"; then 17 | mkl_mkvar_append socket_nsl LIBS "-lsocket -lnsl" 18 | fi 19 | fi 20 | } 21 | -------------------------------------------------------------------------------- /modules/configure.gitversion: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Sets version variable from git information. 4 | # Optional arguments: 5 | # "as" 6 | # VARIABLE_NAME 7 | # 8 | # Example: Set version in variable named "MYVERSION": 9 | # mkl_require gitversion as MYVERSION [default DEFVERSION] 10 | 11 | if [[ $1 == "as" ]]; then 12 | shift 13 | __MKL_GITVERSION_VARNAME="$1" 14 | shift 15 | else 16 | __MKL_GITVERSION_VARNAME="VERSION" 17 | fi 18 | 19 | if [[ $1 == "default" ]]; then 20 | shift 21 | __MKL_GITVERSION_DEFAULT="$1" 22 | shift 23 | fi 24 | 25 | 26 | function checks { 27 | mkl_allvar_set "gitversion" "$__MKL_GITVERSION_VARNAME" \ 28 | "$(git describe --abbrev=6 --tags HEAD --always 2>/dev/null || echo $__MKL_GITVERSION_DEFAULT)" 29 | } 30 | -------------------------------------------------------------------------------- /modules/configure.libsasl2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # libsasl2 support (for GSSAPI/Kerberos), without source installer. 4 | # 5 | # Usage: 6 | # mkl_require libsasl2 7 | # 8 | # 9 | # And then call the following function from the correct place/order in checks: 10 | # mkl_check libsasl2 11 | # 12 | 13 | mkl_toggle_option "Feature" ENABLE_GSSAPI "--enable-gssapi" "Enable SASL GSSAPI support with Cyrus libsasl2" "try" 14 | mkl_toggle_option "Feature" ENABLE_GSSAPI "--enable-sasl" "Deprecated: Alias for --enable-gssapi" 15 | 16 | function manual_checks { 17 | case "$ENABLE_GSSAPI" in 18 | n) return 0 ;; 19 | y) local action=fail ;; 20 | try) local action=disable ;; 21 | *) mkl_err "mklove internal error: invalid value for ENABLE_GSSAPI: $ENABLE_GSSAPI"; exit 1 ;; 22 | esac 23 | 24 | mkl_meta_set "libsasl2" "deb" "libsasl2-dev" 25 | mkl_meta_set "libsasl2" "rpm" "cyrus-sasl" 26 | mkl_meta_set "libsasl2" "apk" "cyrus-sasl-dev" 27 | 28 | local sasl_includes=" 29 | #include 30 | #include 31 | " 32 | 33 | if ! mkl_lib_check "libsasl2" "WITH_SASL_CYRUS" $action CC "-lsasl2" "$sasl_includes" ; then 34 | mkl_lib_check "libsasl" "WITH_SASL_CYRUS" $action CC "-lsasl" "$sasl_includes" 35 | fi 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Magnus Edenhill 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /modules/configure.zlib: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # zlib support, with installer 4 | # 5 | # Usage: 6 | # mkl_require zlib 7 | # 8 | # And then call the following function from the correct place/order in checks: 9 | # mkl_check zlib 10 | # 11 | 12 | mkl_toggle_option "Feature" ENABLE_ZLIB "--enable-zlib" "Enable support for zlib compression" "try" 13 | 14 | function manual_checks { 15 | case "$ENABLE_ZLIB" in 16 | n) return 0 ;; 17 | y) local action=fail ;; 18 | try) local action=disable ;; 19 | *) mkl_err "mklove internal error: invalid value for ENABLE_ZLIB: $ENABLE_ZLIB"; exit 1 ;; 20 | esac 21 | 22 | mkl_meta_set "zlib" "apk" "zlib-dev" 23 | mkl_meta_set "zlib" "static" "libz.a" 24 | mkl_lib_check "zlib" "WITH_ZLIB" $action CC "-lz" \ 25 | " 26 | #include 27 | 28 | void foo (void) { 29 | z_stream *p = NULL; 30 | inflate(p, 0); 31 | } 32 | " 33 | } 34 | 35 | 36 | # Install zlib from source tarball 37 | # 38 | # Param 1: name (zlib) 39 | # Param 2: install-dir-prefix (e.g., DESTDIR) 40 | # Param 2: version (optional) 41 | function install_source { 42 | local name=$1 43 | local destdir=$2 44 | local ver=1.2.11 45 | 46 | echo "### Installing $name $ver from source to $destdir" 47 | if [[ ! -f Makefile ]]; then 48 | curl -fL https://zlib.net/zlib-${ver}.tar.gz | \ 49 | tar xzf - --strip-components 1 50 | fi 51 | 52 | CFLAGS=-fPIC ./configure --static --prefix=/usr 53 | make -j 54 | make test 55 | make DESTDIR="${destdir}" install 56 | return $? 57 | } 58 | -------------------------------------------------------------------------------- /modules/configure.libzstd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # libzstd support, with installer 4 | # 5 | # Usage: 6 | # mkl_require libzstd 7 | # 8 | # And then call the following function from the correct place/order in checks: 9 | # mkl_check libzstd 10 | # 11 | 12 | mkl_toggle_option "Feature" ENABLE_ZSTD "--enable-zstd" "Enable support for ZSTD compression" "try" 13 | 14 | function manual_checks { 15 | case "$ENABLE_ZSTD" in 16 | n) return 0 ;; 17 | y) local action=fail ;; 18 | try) local action=disable ;; 19 | *) mkl_err "mklove internal error: invalid value for ENABLE_ZSTD: $ENABLE_ZSTD"; exit 1 ;; 20 | esac 21 | 22 | mkl_meta_set "libzstd" "brew" "zstd" 23 | mkl_meta_set "libzstd" "apk" "zstd-dev zstd-static" 24 | mkl_meta_set "libzstd" "static" "libzstd.a" 25 | mkl_lib_check "libzstd" "WITH_ZSTD" $action CC "-lzstd" \ 26 | " 27 | #include 28 | #include 29 | 30 | void foo (void) { 31 | ZSTD_getFrameContentSize(NULL, 0); 32 | } 33 | " 34 | } 35 | 36 | 37 | # Install zstd from source tarball 38 | # 39 | # Param 1: name (libzstd) 40 | # Param 2: install-dir-prefix (e.g., DESTDIR) 41 | # Param 2: version (optional) 42 | function install_source { 43 | local name=$1 44 | local destdir=$2 45 | local ver=1.3.8 46 | 47 | echo "### Installing $name $ver from source to $destdir" 48 | if [[ ! -f Makefile ]]; then 49 | curl -fL https://github.com/facebook/zstd/releases/download/v${ver}/zstd-${ver}.tar.gz | \ 50 | tar xzf - --strip-components 1 51 | fi 52 | 53 | time make -j DESTDIR="${destdir}" prefix=/usr install 54 | return $? 55 | } 56 | -------------------------------------------------------------------------------- /modules/configure.lib: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Module for building shared libraries 4 | # Sets: 5 | # WITH_GNULD | WITH_OSXLD 6 | # WITH_LDS - linker script support 7 | mkl_require pic 8 | 9 | function checks { 10 | 11 | mkl_mkvar_append LIB_LDFLAGS LIB_LDFLAGS '-shared' 12 | 13 | # Check what arguments to pass to CC or LD for shared libraries 14 | mkl_meta_set gnulib name "GNU-compatible linker options" 15 | mkl_meta_set osxlib name "OSX linker options" 16 | 17 | if mkl_compile_check gnulib WITH_GNULD cont CC \ 18 | "-shared -Wl,-soname,mkltest.0" "" ; then 19 | # GNU linker 20 | mkl_mkvar_append LIB_LDFLAGS LIB_LDFLAGS '-Wl,-soname,$(LIBFILENAME)' 21 | 22 | elif mkl_compile_check osxlib WITH_OSXLD cont CC \ 23 | "-dynamiclib -Wl,-install_name,/tmp/mkltest.so.0" ; then 24 | # OSX linker 25 | mkl_mkvar_append LIB_LDFLAGS LIB_LDFLAGS '-dynamiclib -Wl,-install_name,$(DESTDIR)$(libdir)/$(LIBFILENAME)' 26 | fi 27 | 28 | # Check what argument is needed for passing linker script. 29 | local ldsfile=$(mktemp _mkltmpXXXXXX) 30 | echo "{ 31 | global: 32 | *; 33 | }; 34 | " > $ldsfile 35 | 36 | mkl_meta_set ldsflagvs name "GNU linker-script ld flag" 37 | mkl_meta_set ldsflagm name "Solaris linker-script ld flag" 38 | if mkl_compile_check ldsflagvs "" cont CC \ 39 | "-shared -Wl,--version-script=$ldsfile"; then 40 | mkl_mkvar_set ldsflagvs LDFLAG_LINKERSCRIPT "-Wl,--version-script=" 41 | mkl_mkvar_set lib_lds WITH_LDS y 42 | elif mkl_compile_check ldsflagm "" ignore CC \ 43 | "-shared -Wl,-M$ldsfile"; then 44 | mkl_mkvar_set ldsflagm LDFLAG_LINKERSCRIPT "-Wl,-M" 45 | mkl_mkvar_set lib_lds WITH_LDS y 46 | fi 47 | 48 | rm -f "$ldsfile" 49 | } 50 | -------------------------------------------------------------------------------- /modules/configure.libcurl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # libcurl support, with installer 4 | # 5 | # Usage: 6 | # mkl_require libcurl 7 | # 8 | # And then call the following function from the correct place/order in checks: 9 | # mkl_check libcurl 10 | # 11 | 12 | mkl_toggle_option "Feature" ENABLE_CURL "--enable-curl" "Enable HTTP client (using libcurl)" "try" 13 | 14 | function manual_checks { 15 | case "$ENABLE_CURL" in 16 | n) return 0 ;; 17 | y) local action=fail ;; 18 | try) local action=disable ;; 19 | *) mkl_err "mklove internal error: invalid value for ENABLE_CURL: $ENABLE_CURL"; exit 1 ;; 20 | esac 21 | 22 | mkl_meta_set "libcurl" "apk" "curl-dev curl-static" 23 | mkl_meta_set "libcurl" "deb" "libcurl4-openssl-dev" 24 | mkl_meta_set "libcurl" "static" "libcurl.a" 25 | mkl_lib_check "libcurl" "WITH_CURL" $action CC "-lcurl" \ 26 | " 27 | #include 28 | 29 | void foo (void) { 30 | curl_global_init(CURL_GLOBAL_DEFAULT); 31 | } 32 | " 33 | } 34 | 35 | 36 | # Install curl from source tarball 37 | # 38 | # Param 1: name (libcurl) 39 | # Param 2: install-dir-prefix (e.g., DESTDIR) 40 | # Param 2: version (optional) 41 | function install_source { 42 | local name=$1 43 | local destdir=$2 44 | local ver=7.78.0 45 | 46 | echo "### Installing $name $ver from source to $destdir" 47 | if [[ ! -f Makefile ]]; then 48 | curl -fL https://curl.se/download/curl-${ver}.tar.gz | \ 49 | tar xzf - --strip-components 1 50 | fi 51 | 52 | # Clear out LIBS to not interfer with lib detection process. 53 | LIBS="" ./configure \ 54 | --with-openssl \ 55 | --enable-static \ 56 | --disable-shared \ 57 | --disable-ntlm{,-wb} \ 58 | --disable-dict \ 59 | --disable-ftp \ 60 | --disable-file \ 61 | --disable-gopher \ 62 | --disable-imap \ 63 | --disable-imaps \ 64 | --disable-mqtt \ 65 | --disable-pop3 \ 66 | --disable-rtsp \ 67 | --disable-smb \ 68 | --disable-smtp \ 69 | --disable-telnet \ 70 | --disable-tftp \ 71 | --disable-ssh \ 72 | --disable-manual \ 73 | --disable-ldap{,s} \ 74 | --disable-libcurl-option \ 75 | --without-{librtmp,libidn2,winidn,nghttp2,nghttp3,ngtcp2,quiche,brotli} && 76 | time make -j && 77 | make DESTDIR="${destdir}" prefix=/usr install 78 | 79 | return $? 80 | } 81 | -------------------------------------------------------------------------------- /modules/configure.fileversion: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Reads version from file and sets variables accordingly 4 | # The first non-commented line in the file is expected to be the version string. 5 | # Arguments: 6 | # filename 7 | # STR_VERSION_VARIABLE_NAME 8 | # [ HEX_VERSION_VARIABLE_NAME ] 9 | # 10 | # Example: Set string version in variable named "MYVERSION_STR" and 11 | # the hex representation in "MYVERSION" 12 | # mkl_require VERSION.txt MYVERSION_STR MYVERSION 13 | 14 | if [[ -z "$2" ]]; then 15 | mkl_fail "fileversion" "none" "fail" "Missing argument(s), expected: FILENAME STR_VER HEX_VER" 16 | return 0 17 | fi 18 | 19 | fileversion_file="$1" 20 | fileversion_strvar="$2" 21 | fileversion_hexvar="$3" 22 | 23 | function checks { 24 | mkl_check_begin "fileversion" "" "no-cache" "version from file $fileversion_file" 25 | 26 | if [[ ! -s $fileversion_file ]]; then 27 | mkl_check_failed "fileversion" "" "fail" \ 28 | "Version file $fileversion_file is not readable" 29 | return 1 30 | fi 31 | 32 | local orig=$(grep -v ^\# "$fileversion_file" | grep -v '^$' | head -1) 33 | # Strip v prefix if any 34 | orig=${orig#v} 35 | 36 | # Try to decode version string into hex 37 | # Supported format is "[v]NN.NN.NN[.NN]" 38 | if [[ ! -z $fileversion_hexvar ]]; then 39 | local hex="" 40 | local s=${orig#v} # Strip v prefix, if any. 41 | local ncnt=0 42 | local n= 43 | for n in ${s//./ } ; do 44 | if [[ ! ( "$n" =~ ^[0-9][0-9]?$ ) ]]; then 45 | mkl_check_failed "fileversion" "" "fail" \ 46 | "$fileversion_file: Could not decode '$orig' into hex version, expecting format 'NN.NN.NN[.NN]'" 47 | return 1 48 | fi 49 | hex="$hex$(printf %02x $n)" 50 | ncnt=$(expr $ncnt + 1) 51 | done 52 | 53 | if [[ ! -z $hex ]]; then 54 | # Finish all four bytess 55 | for n in {$ncnt..4} ; do 56 | hex="$hex$(printf %02x 0)" 57 | done 58 | mkl_allvar_set "fileversion" "$fileversion_hexvar" "0x$hex" 59 | fi 60 | fi 61 | 62 | mkl_allvar_set "fileversion" "$fileversion_strvar" "$orig" 63 | 64 | mkl_check_done "fileversion" "" "cont" "ok" "${!fileversion_strvar}" 65 | } 66 | -------------------------------------------------------------------------------- /modules/configure.parseversion: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Parses the provided version string and creates variables accordingly. 4 | # [ "hex2str" ] -- version-string is in hex (e.g., 0x00080300) 5 | # version-string 6 | # STR_VERSION_VARIABLE_NAME 7 | # [ HEX_VERSION_VARIABLE_NAME ] 8 | # 9 | # Note: The version will also be set in MKL_APP_VERSION 10 | # 11 | # Example: Set string version in variable named "MYVERSION_STR" and 12 | # the hex representation in "MYVERSION" 13 | # mkl_require parseversion "$(head -1 VERSION.txt)" MYVERSION_STR MYVERSION 14 | 15 | if [[ $1 == "hex2str" ]]; then 16 | parseversion_type="hex" 17 | parseversion_fmt="${2}:END:%d%d%d%d" 18 | shift 19 | shift 20 | else 21 | parseversion_type="" 22 | parseversion_fmt="%d.%d.%d.%d" 23 | fi 24 | 25 | if [[ -z "$2" ]]; then 26 | mkl_fail "parseversion" "none" "fail" "Missing argument(s)" 27 | return 0 28 | fi 29 | 30 | parseversion_orig="$1" 31 | parseversion_strvar="$2" 32 | parseversion_hexvar="$3" 33 | 34 | function checks { 35 | mkl_check_begin --verb "parsing" "parseversion" "" "no-cache" \ 36 | "version '$parseversion_orig'" 37 | 38 | # Strip v prefix if any 39 | orig=${parseversion_orig#v} 40 | 41 | if [[ $orig == 0x* ]]; then 42 | parseversion_type="hex" 43 | orig=${orig#0x} 44 | fi 45 | 46 | if [[ -z $orig ]]; then 47 | mkl_check_failed "parseversion" "" "fail" "Version string is empty" 48 | return 1 49 | fi 50 | 51 | # If orig is in hex we construct a string format instead. 52 | if [[ $parseversion_type == "hex" ]]; then 53 | local s=$orig 54 | local str="" 55 | local vals="" 56 | while [[ ! -z $s ]]; do 57 | local n=${s:0:2} 58 | s=${s:${#n}} 59 | vals="${vals}$(printf %d 0x$n) " 60 | done 61 | str=$(printf "$parseversion_fmt" $vals) 62 | orig=${str%:END:*} 63 | fi 64 | 65 | 66 | # Try to decode version string into hex 67 | # Supported format is "[v]NN.NN.NN[.NN]" 68 | if [[ ! -z $parseversion_hexvar ]]; then 69 | local hex="" 70 | local s=$orig 71 | local ncnt=0 72 | local n= 73 | for n in ${s//./ } ; do 74 | if [[ ! ( "$n" =~ ^[0-9][0-9]?$ ) ]]; then 75 | mkl_check_failed "parseversion" "" "fail" \ 76 | "Could not decode '$parseversion_orig' into hex version, expecting format 'NN.NN.NN[.NN]'" 77 | return 1 78 | fi 79 | hex="$hex$(printf %02x $n)" 80 | ncnt=$(expr $ncnt + 1) 81 | done 82 | 83 | if [[ ! -z $hex ]]; then 84 | # Finish all four bytess 85 | while [[ ${#hex} -lt 8 ]]; do 86 | hex="$hex$(printf %02x 0)" 87 | done 88 | mkl_allvar_set "parseversion" "$parseversion_hexvar" "0x$hex" 89 | fi 90 | fi 91 | 92 | mkl_allvar_set "parseversion" "$parseversion_strvar" "$orig" 93 | mkl_allvar_set "parseversion" MKL_APP_VERSION "$orig" 94 | mkl_check_done "parseversion" "" "cont" "ok" "${!parseversion_strvar}" 95 | } 96 | -------------------------------------------------------------------------------- /modules/configure.builtin: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # mklove builtin checks and options 4 | # Sets: 5 | # prefix, etc.. 6 | 7 | 8 | mkl_option "Standard" prefix "--prefix=PATH" \ 9 | "Install arch-independent files in PATH" "/usr/local" 10 | mkl_option "Standard" exec_prefix "--exec-prefix=PATH" \ 11 | "Install arch-dependent files in PATH" "\$prefix" 12 | mkl_option "Standard" bindir "--bindir=PATH" "User executables" "\$exec_prefix/bin" 13 | mkl_option "Standard" sbindir "--sbindir=PATH" "System admin executables" \ 14 | "\$exec_prefix/sbin" 15 | mkl_option "Standard" libexecdir "--libexecdir=PATH" "Program executables" \ 16 | "\$exec_prefix/libexec" 17 | mkl_option "Standard" datadir "--datadir=PATH" "Read-only arch-independent data" \ 18 | "\$prefix/share" 19 | mkl_option "Standard" sysconfdir "--sysconfdir=PATH" "Configuration data" \ 20 | "\$prefix/etc" 21 | mkl_option "Standard" sharedstatedir "--sharedstatedir=PATH" \ 22 | "Modifiable arch-independent data" "\$prefix/com" 23 | mkl_option "Standard" localstatedir "--localstatedir=PATH" \ 24 | "Modifiable local state data" "\$prefix/var" 25 | mkl_option "Standard" runstatedir "--runstatedir=PATH" \ 26 | "Modifiable per-process data" "\$prefix/var/run" 27 | mkl_option "Standard" libdir "--libdir=PATH" "Libraries" "\$exec_prefix/lib" 28 | mkl_option "Standard" includedir "--includedir=PATH" "C/C++ header files" \ 29 | "\$prefix/include" 30 | mkl_option "Standard" infodir "--infodir=PATH" "Info documentation" "\$prefix/info" 31 | mkl_option "Standard" mandir "--mandir=PATH" "Manual pages" "\$prefix/man" 32 | 33 | mkl_option "Configure tool" "" "--list-modules" "List loaded mklove modules" 34 | mkl_option "Configure tool" "" "--list-checks" "List checks" 35 | mkl_option "Configure tool" env:MKL_FAILFATAL "--fail-fatal" "All failures are fatal" 36 | mkl_option "Configure tool" env:MKL_NOCACHE "--no-cache" "Dont use or generate config.cache" 37 | mkl_option "Configure tool" env:MKL_DEBUG "--debug" "Enable configure debugging" 38 | mkl_option "Configure tool" env:MKL_CLEAN "--clean" "Remove generated configure files" 39 | mkl_option "Configure tool" "" "--reconfigure" "Rerun configure with same arguments as last run" 40 | mkl_option "Configure tool" env:MKL_NO_DOWNLOAD "--no-download" "Disable downloads of required mklove modules" 41 | mkl_option "Configure tool" env:MKL_UPDATE_MODS "--update-modules" "Update modules from global repository" 42 | mkl_option "Configure tool" env:MKL_REPO_URL "--repo-url=URL_OR_PATH" "Override mklove modules repo URL" "$MKL_REPO_URL" 43 | mkl_option "Configure tool" "" "--help" "Show configure usage" 44 | 45 | 46 | # These autoconf compatibility options are ignored by mklove 47 | mkl_toggle_option "Compatibility" "mk:COMPAT_MAINT_MODE" "--enable-maintainer-mode" "Maintainer mode (no-op)" 48 | mkl_option "Compatibility" "mk:PROGRAM_PREFIX" "--program-prefix=PFX" "Program prefix (no-op)" 49 | mkl_option "Compatibility" "mk:COMPAT_DISABLE_DEP_TRACK" "--disable-dependency-tracking" "Disable dependency tracking (no-op)" 50 | mkl_option "Compatibility" "mk:COMPAT_DISABLE_SILENT_RULES" "--disable-silent-rules" "Verbose build output (no-op)" 51 | mkl_option "Compatibility" "mk:COMPAT_SILENT" "--silent" "Less verbose build output (no-op)" 52 | mkl_toggle_option "Compatibility" "mk:COMPAT_ENABLE_SHARED" "--enable-shared" "Build shared library (no-op)" 53 | mkl_toggle_option "Compatibility" "mk:COMPAT_DISABLE_OPT_CHECK" '--enable-option-checking=*' "Disable configure option checking (no-op)" 54 | 55 | 56 | mkl_option "Dependency" env:MKL_INSTALL_DEPS "--install-deps" "Attempt to install missing dependencies" 57 | mkl_option "Dependency" env:MKL_SOURCE_DEPS_ONLY "--source-deps-only" "Only perform source builds of dependencies, not using any package managers" 58 | 59 | 60 | function checks { 61 | 62 | if [[ ! -z $libdir ]]; then 63 | mkl_mkvar_append "libdir" LDFLAGS "-L${libdir}" 64 | fi 65 | 66 | if [[ ! -z $includedir ]]; then 67 | mkl_mkvar_append "includedir" CPPFLAGS "-I${includedir}" 68 | fi 69 | 70 | } 71 | -------------------------------------------------------------------------------- /modules/configure.libssl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # libssl and libcrypto (OpenSSL or derivate) support, with installer. 4 | # Requires OpenSSL version v1.0.1 or later. 5 | # 6 | # Usage: 7 | # mkl_require libssl 8 | # 9 | 10 | # And then call the following function from the correct place/order in checks: 11 | # mkl_check libssl 12 | # 13 | # 14 | # This module is a bit hacky since OpenSSL provides both libcrypto and libssl, 15 | # the latter depending on the former, but from a user perspective it is 16 | # SSL that is the feature, not crypto. 17 | 18 | mkl_toggle_option "Feature" ENABLE_SSL "--enable-ssl" "Enable SSL support" "try" 19 | 20 | 21 | function manual_checks { 22 | case "$ENABLE_SSL" in 23 | n) return 0 ;; 24 | y) local action=fail ;; 25 | try) local action=disable ;; 26 | *) mkl_err "mklove internal error: invalid value for ENABLE_SSL: $ENABLE_SSL"; exit 1 ;; 27 | esac 28 | 29 | if [[ $MKL_DISTRO == "osx" ]]; then 30 | # Add brew's OpenSSL pkg-config path on OSX 31 | # to avoid picking up the outdated system-provided openssl/libcrypto. 32 | mkl_env_append PKG_CONFIG_PATH "/usr/local/opt/openssl/lib/pkgconfig" ":" 33 | fi 34 | 35 | # OpenSSL provides both libcrypto and libssl 36 | if [[ $WITH_STATIC_LINKING != y ]]; then 37 | # Debian's OpenSSL static libraries are broken. 38 | mkl_meta_set "libcrypto" "deb" "libssl-dev" 39 | fi 40 | mkl_meta_set "libcrypto" "rpm" "openssl-devel" 41 | mkl_meta_set "libcrypto" "brew" "openssl" 42 | mkl_meta_set "libcrypto" "apk" "openssl-dev" 43 | mkl_meta_set "libcrypto" "static" "libcrypto.a" 44 | 45 | if ! mkl_lib_check "libcrypto" "" $action CC "-lcrypto" " 46 | #include 47 | #include 48 | #if OPENSSL_VERSION_NUMBER < 0x1000100fL 49 | #error \"Requires OpenSSL version >= v1.0.1\" 50 | #endif"; then 51 | return 52 | fi 53 | 54 | 55 | # 56 | # libssl 57 | # 58 | mkl_meta_set "libssl" "static" "libssl.a" 59 | 60 | if [[ $(mkl_meta_get "libcrypto" "installed_with") == "source" ]]; then 61 | # Try to resolve the libssl.a static library path based on the 62 | # libcrypto (openssl) install path. 63 | mkl_resolve_static_libs "libssl" "$(mkl_dep_destdir libcrypto)" 64 | fi 65 | 66 | mkl_lib_check "libssl" "WITH_SSL" $action CC "-lssl -lcrypto" \ 67 | "#include 68 | #if OPENSSL_VERSION_NUMBER < 0x1000100fL 69 | #error \"Requires OpenSSL version >= v1.0.1\" 70 | #endif" 71 | } 72 | 73 | 74 | # No source installer on osx: rely on openssl from homebrew 75 | if [[ $MKL_DISTRO != osx ]]; then 76 | 77 | # Install libcrypto/libssl from source tarball on linux. 78 | # 79 | # Param 1: name (libcrypto) 80 | # Param 2: install-dir-prefix (e.g., DESTDIR) 81 | # Param 2: version (optional) 82 | function libcrypto_install_source { 83 | local name=$1 84 | local destdir=$2 85 | local ver=1.1.1k 86 | local url=https://www.openssl.org/source/openssl-${ver}.tar.gz 87 | 88 | local conf_args="--openssldir=/usr/lib/ssl no-shared no-zlib no-deprecated" 89 | if [[ $ver == 1.0.* ]]; then 90 | extra_conf_args="${extra_conf_args} no-krb5" 91 | fi 92 | 93 | echo "### Installing $name $ver from source ($url) to $destdir" 94 | if [[ ! -f config ]]; then 95 | echo "### Downloading" 96 | curl -fL $url | tar xzf - --strip-components 1 97 | fi 98 | 99 | echo "### Configuring" 100 | ./config --prefix="/usr" $conf_args || return $? 101 | 102 | echo "### Building" 103 | make 104 | 105 | echo "### Installing to $destdir" 106 | if [[ $ver == 1.0.* ]]; then 107 | make INSTALL_PREFIX="$destdir" install_sw 108 | else 109 | make DESTDIR="$destdir" install 110 | fi 111 | 112 | return $? 113 | } 114 | fi 115 | -------------------------------------------------------------------------------- /modules/configure.host: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Host OS support 4 | # Sets: 5 | # HOST 6 | # BUILD 7 | # TARGET 8 | 9 | # FIXME: No need for this right now 10 | #mkl_require host_linux 11 | #mkl_require host_osx 12 | #mkl_require host_cygwin 13 | 14 | #mkl_option "Cross-compilation" "mk:HOST_OS" "--host-os=osname" "Host OS (linux,osx,cygwin,..)" "auto" 15 | 16 | 17 | # autoconf compatibility - does nothing at this point 18 | mkl_option "Cross-compilation" "mk:HOST" "--host=HOST" "Configure to build programs to run on HOST (no-op)" 19 | mkl_option "Cross-compilation" "mk:BUILD" "--build=BUILD" "Configure for building on BUILD (no-op)" 20 | mkl_option "Cross-compilation" "mk:TARGET" "--target=TARGET" "Configure for building cross-toolkits for platform TARGET (no-op)" 21 | 22 | 23 | # Resolve the OS/distro at import time, rather than as a check, 24 | # so that MKL_DISTRO is available to other modules at import time. 25 | function resolve_distro { 26 | solib_ext=.so 27 | 28 | # Try lsb_release 29 | local sys 30 | sys=$(lsb_release -is 2>/dev/null) 31 | if [[ $? -gt 0 ]]; then 32 | # That didnt work, try uname. 33 | local kn=$(uname -s) 34 | case $kn in 35 | Linux) 36 | sys=Linux 37 | solib_ext=.so 38 | 39 | if [[ -f /etc/os-release ]]; then 40 | eval $(grep ^ID= /etc/os-release) 41 | if [[ -n $ID ]]; then 42 | sys="$ID" 43 | fi 44 | elif [[ -f /etc/centos-release ]]; then 45 | sys=centos 46 | elif [[ -f /etc/alpine-release ]]; then 47 | sys=alpine 48 | fi 49 | ;; 50 | Darwin) 51 | sys=osx 52 | solib_ext=.dylib 53 | ;; 54 | CYGWIN*) 55 | sys=Cygwin 56 | solib_ext=.dll 57 | ;; 58 | *) 59 | sys="$kn" 60 | solib_ext=.so 61 | ;; 62 | esac 63 | fi 64 | 65 | # Convert to lower case 66 | sys=$(echo $sys | tr '[:upper:]' '[:lower:]') 67 | mkl_mkvar_set "distro" "MKL_DISTRO" "$sys" 68 | mkl_allvar_set "distro" "SOLIB_EXT" "$solib_ext" 69 | } 70 | 71 | resolve_distro 72 | 73 | 74 | function checks { 75 | # Try to figure out what OS/distro we are running on. 76 | mkl_check_begin "distro" "" "no-cache" "OS or distribution" 77 | 78 | if [[ -z $MKL_DISTRO ]]; then 79 | mkl_check_failed "distro" "" "ignore" "" 80 | else 81 | mkl_check_done "distro" "" "ignore" "ok" "$MKL_DISTRO" 82 | fi 83 | } 84 | 85 | #function checks { 86 | # mkl_check_begin "host" "HOST_OS" "no-cache" "host OS" 87 | # 88 | # # 89 | # # If --host-os=.. was not specified then this is most likely not a 90 | # # a cross-compilation and we can base the host-os on the native OS. 91 | # # 92 | # if [[ $HOST_OS != "auto" ]]; then 93 | # mkl_check_done "host" "HOST_OS" "cont" "ok" "$HOST_OS" 94 | # return 0 95 | # fi 96 | # 97 | # kn=$(uname -s) 98 | # case $kn in 99 | # Linux) 100 | # hostos=linux 101 | # ;; 102 | # Darwin) 103 | # hostos=osx 104 | # ;; 105 | # CYGWIN*) 106 | # hostos=cygwin 107 | # ;; 108 | # *) 109 | # hostos="$(mkl_lower $kn)" 110 | # mkl_err "Unknown host OS kernel name: $kn" 111 | # mkl_err0 " Will attempt to load module host_$hostos anyway." 112 | # mkl_err0 " Please consider writing a configure.host_$hostos" 113 | # ;; 114 | # esac 115 | # 116 | # if ! mkl_require --try "host_$hostos"; then 117 | # # Module not found 118 | # mkl_check_done "host" "HOST_OS" "cont" "failed" "$kn?" 119 | # else 120 | # # Module loaded 121 | # 122 | # if mkl_func_exists "host_${hostos}_setup" ; then 123 | # "host_${hostos}_setup" 124 | # fi 125 | # 126 | # mkl_check_done "host" "HOST_OS" "cont" "ok" "$hostos" 127 | # fi 128 | # 129 | # # Set HOST_OS var even if probing failed. 130 | # mkl_mkvar_set "host" "HOST_OS" "$hostos" 131 | #} 132 | 133 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | mklove - not autoconf 2 | ===================== 3 | 4 | mklove provides an auto-configuration and build environment for C/C++ 5 | applications and libraries. 6 | 7 | It aims to be a lightweight drop-in compatible replacement to 8 | the overly bloated autoconf. 9 | 10 | mklove has two prongs on its fork: 11 | * the configure script, and 12 | * the Makefile base targets 13 | 14 | These can be used together or on their own. The configure script provides 15 | standard Makefile variable names in Makefile.config, while Makefile.base 16 | uses these standard names. Other than that there is no special magic 17 | tie between the two and you can use whichever part you like, or both, or none 18 | (which seems pointless). 19 | 20 | mklove is used in popular open source projects and works with Debian's debhelper 21 | based autoconf package builders out of the box. See the following real-life uses 22 | for inspiration: 23 | * [librdkafka](https://github.com/edenhill/librdkafka) - [configure.librdkafka](https://github.com/edenhill/librdkafka/blob/master/configure.librdkafka) 24 | * [kafkacat](https://github.com/edenhill/kafkacat) - [configure.kafkacat](https://github.com/edenhill/kafkacat/blob/master/configure.kafkacat) 25 | 26 | 27 | Why mklove and not autoconf/automake 28 | ------------------------------------ 29 | * I dont want my Makefiles or targets auto generated. 30 | Why? Because it's hard to debug and it's trivial to write proper targets 31 | manually. (mklove provides optional standard targets for common operations). 32 | * The generated makefiles (et.al) from autoconf are usually larger than the 33 | sum of all source code for smaller projects. This is ridiculous. 34 | * autoconf is declarative, mklove is imperative, this allows fine grained 35 | and natural control flow that follows your line of thought. 36 | * I dont want to spend my time watching configure test for things that 37 | have been true since 1970. "checking for size of char... 1 byte". 38 | 39 | 40 | Base design requirements for mklove 41 | ----------------------------------- 42 | * I want portability to be taken care of for me. 43 | * I want to understand the output files of configure: 44 | Makefile.config and config.h have no targets or logic, they only contain 45 | variable and #define assignments. 46 | * I want Makefile.config variables and config.h to match, and they do. 47 | WITH_FOOLIB will be defined in both files (to 1 in config.h, 48 | and y in Makefile) 49 | * I want configure checks to be reusable, in mklove they are separate 50 | module files that you can add as you see fit to your program. 51 | * Module files are automatically download on use if not present locally. 52 | * **Dont stop on each error**; run as many checks as possible then present me 53 | the fatal failures when done 54 | * Suggest to me what packages to install to fix a failure. 55 | * Be drop-in compatible with the beast. 56 | 57 | Hip features 58 | ------------ 59 | * Colored output, find errors quickly. 60 | * `./configure --reconfigure` reruns configure with the same arguments 61 | as the last run. 62 | * Will download mklove modules if necessary. 63 | 64 | 65 | Checks produce the following output 66 | ----------------------------------- 67 | * Make variable with default value set to y or n, e.g: 68 | WITH_LIBFOO=y 69 | * Config define with default value set to 1 or 0 70 | WITH_LIBFOO=1 71 | 72 | 73 | Modules 74 | ------- 75 | 76 | Missing modules are downloaded automatically when required. 77 | 78 | See `mklove/modules` for the available modules. 79 | 80 | 81 | Instructions 82 | ------------ 83 | 84 | Run the `setup.sh` script from the mklove checkout directory 85 | (not from your project's mklove directory). 86 | Specify your project's top level directory as the only argument to setup.sh: 87 | 88 | ```` 89 | # Go to mklove checkout directory 90 | cd mklove 91 | 92 | # Run setup, specify the path to your project 93 | ./setup.sh ~/src/myproject 94 | 95 | # Answer the questions and let mklove set up itself. 96 | 97 | # Go to your project directory 98 | cd ~/src/myproject 99 | 100 | # Add your own options and checks by creating a configure. file. 101 | emacs configure.myproject 102 | 103 | # Update modules. 104 | # This copies the required modules to your project's mklove/modules directory 105 | # so that your project can be packaged and shipped with all required 106 | # mklove files. 107 | # Note: --update-modules will overwrite modules in /mklove. 108 | ./configure --update-modules 109 | 110 | 111 | # Configure your project 112 | ./configure 113 | 114 | # Build it 115 | make (or whatever) 116 | 117 | ```` 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /modules/configure.atomics: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Checks for atomic ops: 4 | # compiler builtin (__sync_..) and portable libatomic's (__atomic_..) 5 | # Will also provide abstraction by defining the prefix to use. 6 | # 7 | # Sets: 8 | # HAVE_ATOMICS 9 | # HAVE_ATOMICS_32 10 | # HAVE_ATOMICS_64 11 | # HAVE_ATOMICS_32_ATOMIC __atomic interface 12 | # HAVE_ATOMICS_32_SYNC __sync interface 13 | # HAVE_ATOMICS_64_ATOMIC __atomic interface 14 | # HAVE_ATOMICS_64_SYNC __sync interface 15 | # WITH_LIBATOMIC 16 | # LIBS 17 | # 18 | # ATOMIC_OP(OP1,OP2,PTR,VAL) 19 | # ATOMIC_OP32(OP1,OP2,PTR,VAL) 20 | # ATOMIC_OP64(OP1,OP2,PTR,VAL) 21 | # where op* is 'add,sub,fetch' 22 | # e.g: ATOMIC_OP32(add, fetch, &i, 10) 23 | # becomes __atomic_add_fetch(&i, 10, ..) or 24 | # __sync_add_and_fetch(&i, 10) 25 | # 26 | 27 | function checks { 28 | 29 | 30 | # We prefer the newer __atomic stuff, but 64-bit atomics might 31 | # require linking with -latomic, so we need to perform these tests 32 | # in the proper order: 33 | # __atomic 32 34 | # __atomic 32 -latomic 35 | # __sync 32 36 | # 37 | # __atomic 64 38 | # __atomic 64 -latomic 39 | # __sync 64 40 | 41 | local _libs= 42 | local _a32="__atomic_ ## OP1 ## _ ## OP2(PTR, VAL, __ATOMIC_SEQ_CST)" 43 | local _a64="__atomic_ ## OP1 ## _ ## OP2(PTR, VAL, __ATOMIC_SEQ_CST)" 44 | 45 | # 32-bit: 46 | # Try fully builtin __atomic 47 | if ! mkl_compile_check __atomic_32 HAVE_ATOMICS_32 cont CC "" \ 48 | " 49 | #include 50 | int32_t foo (int32_t i) { 51 | return __atomic_add_fetch(&i, 1, __ATOMIC_SEQ_CST); 52 | }" 53 | then 54 | # Try __atomic with -latomic 55 | if mkl_compile_check --ldflags="-latomic" __atomic_32_lib HAVE_ATOMICS_32 \ 56 | cont CC "" \ 57 | " 58 | #include 59 | int32_t foo (int32_t i) { 60 | return __atomic_add_fetch(&i, 1, __ATOMIC_SEQ_CST); 61 | }" 62 | then 63 | _libs="-latomic" 64 | mkl_allvar_set "__atomic_32_lib" "HAVE_ATOMICS_32_ATOMIC" "y" 65 | else 66 | # Try __sync interface 67 | if mkl_compile_check __sync_32 HAVE_ATOMICS_32 disable CC "" \ 68 | " 69 | #include 70 | int32_t foo (int32_t i) { 71 | return __sync_add_and_fetch(&i, 1); 72 | }" 73 | then 74 | _a32="__sync_ ## OP1 ## _and_ ## OP2(PTR, VAL)" 75 | mkl_allvar_set "__sync_32" "HAVE_ATOMICS_32_SYNC" "y" 76 | else 77 | _a32="" 78 | fi 79 | fi 80 | else 81 | mkl_allvar_set "__atomic_32" "HAVE_ATOMICS_32_ATOMIC" "y" 82 | fi 83 | 84 | 85 | if [[ ! -z $_a32 ]]; then 86 | mkl_define_set "atomic_32" "ATOMIC_OP32(OP1,OP2,PTR,VAL)" "code:$_a32" 87 | fi 88 | 89 | 90 | 91 | # 64-bit: 92 | # Try fully builtin __atomic 93 | if ! mkl_compile_check __atomic_64 HAVE_ATOMICS_64 cont CC "" \ 94 | " 95 | #include 96 | int64_t foo (int64_t i) { 97 | return __atomic_add_fetch(&i, 1, __ATOMIC_SEQ_CST); 98 | }" 99 | then 100 | # Try __atomic with -latomic 101 | if mkl_compile_check --ldflags="-latomic" __atomic_64_lib HAVE_ATOMICS_64 \ 102 | cont CC "" \ 103 | " 104 | #include 105 | int64_t foo (int64_t i) { 106 | return __atomic_add_fetch(&i, 1, __ATOMIC_SEQ_CST); 107 | }" 108 | then 109 | _libs="-latomic" 110 | mkl_allvar_set "__atomic_64_lib" "HAVE_ATOMICS_64_ATOMIC" "y" 111 | else 112 | # Try __sync interface 113 | if mkl_compile_check __sync_64 HAVE_ATOMICS_64 disable CC "" \ 114 | " 115 | #include 116 | int64_t foo (int64_t i) { 117 | return __sync_add_and_fetch(&i, 1); 118 | }" 119 | then 120 | _a64="__sync_ ## OP1 ## _and_ ## OP2 (PTR, VAL)" 121 | mkl_allvar_set "__sync_64" "HAVE_ATOMICS_64_SYNC" "y" 122 | else 123 | _a64="" 124 | fi 125 | fi 126 | else 127 | mkl_allvar_set "__atomic_64" "HAVE_ATOMICS_64_ATOMIC" "y" 128 | fi 129 | 130 | 131 | if [[ ! -z $_a64 ]]; then 132 | mkl_define_set "atomic_64" "ATOMIC_OP64(OP1,OP2,PTR,VAL)" "code:$_a64" 133 | 134 | # Define generic ATOMIC() macro identical to 64-bit atomics" 135 | mkl_define_set "atomic_64" "ATOMIC_OP(OP1,OP2,PTR,VAL)" "code:$_a64" 136 | fi 137 | 138 | 139 | if [[ ! -z $_libs ]]; then 140 | mkl_mkvar_append LDFLAGS LDFLAGS "-Wl,--as-needed" 141 | mkl_mkvar_append LIBS LIBS "$_libs" 142 | fi 143 | 144 | } 145 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 4 | 5 | MKL_RED="\033[031m" 6 | MKL_GREEN="\033[032m" 7 | MKL_YELLOW="\033[033m" 8 | MKL_BLUE="\033[034m" 9 | MKL_CLR_RESET="\033[0m" 10 | 11 | # Set to "-v" for verbose file copies 12 | CP_V= 13 | 14 | function puts { 15 | echo -e "$*" 16 | } 17 | 18 | function fatal { 19 | puts "${MKL_RED}Fatal error: $*${MKL_CLR_RESET}" 20 | exit 1 21 | } 22 | 23 | interactive=1 24 | inst_conf=n 25 | inst_mkb=n 26 | 27 | while true ; do 28 | case "$1" in 29 | --all) 30 | inst_conf=y 31 | inst_mkb=y 32 | interactive=0 33 | ;; 34 | --mk) 35 | inst_mkb=y 36 | interactive=0 37 | ;; 38 | --conf) 39 | inst_conf=y 40 | interactive=0 41 | ;; 42 | *) 43 | break 44 | ;; 45 | esac 46 | shift 47 | done 48 | 49 | mklove_dir=$(pwd) 50 | proj_dir=$1 51 | 52 | 53 | 54 | 55 | # 56 | # Check usage 57 | # 58 | if [[ ! -d $proj_dir ]]; then 59 | puts "mklove setup.sh" 60 | puts "Interactive utility for setting up mklove for your project" 61 | puts "" 62 | puts "Usage: ./setup.sh [options] " 63 | puts "" 64 | puts "Options:" 65 | puts " --all Set up both configure and Makefile.base" 66 | puts " --mk Set up Makefile.base" 67 | puts " --conf Set up configure" 68 | exit 1 69 | fi 70 | 71 | puts "${MKL_GREEN}Welcome to mklove setup${MKL_CLR_RESET}" 72 | puts "" 73 | 74 | # 75 | # Check that paths make sense 76 | # 77 | if [[ ! -f $mklove_dir/configure || ! -f $mklove_dir/Makefile.base ]]; then 78 | puts "${MKL_YELLOW}NOTE: setup.sh must be run from the mklove directory${MKL_CLR_RESET}" 79 | puts "" 80 | fatal "$mklove_dir does not look like the mklove directory" 81 | 82 | fi 83 | 84 | if [[ $mklove_dir == $proj_dir ]]; then 85 | fatal "setup.sh should be run from your project's directory, not the mklove directory" 86 | fi 87 | 88 | 89 | 90 | # 91 | # Ask what parts of mklove are to be set up. 92 | # 93 | while [[ $interactive == 1 ]] ; do 94 | puts "${MKL_BLUE}What parts of mklove do you want to use in your project:${MKL_CLR_RESET}" 95 | puts " 1 - configure and Makefile.base" 96 | puts " 2 - configure only" 97 | puts " 3 - Makefile.base only" 98 | read -p "Choice(1)> " -e what 99 | 100 | [[ -z $what ]] && what=1 101 | 102 | case $what in 103 | 1) 104 | inst_conf=y 105 | inst_mkb=y 106 | ;; 107 | 2) 108 | inst_conf=y 109 | ;; 110 | 3) 111 | inst_mkb=y 112 | ;; 113 | *) 114 | puts "${MKL_RED}Unknown option: $what${MKL_CLR_RESET}" 115 | continue 116 | esac 117 | break 118 | done 119 | 120 | 121 | # 122 | # Ask for confirmation 123 | # 124 | puts "" 125 | puts "${MKL_BLUE}Will set up your project with:${MKL_CLR_RESET}" 126 | [[ $inst_conf == y ]] && puts " - configure script" 127 | [[ $inst_mkb == y ]] && puts " - Makefile.base" 128 | puts " - from mklove directory $mklove_dir" 129 | puts " - to project directory $proj_dir" 130 | 131 | [[ $interactive == 1 ]] && read -p "Press enter to confirm or Ctrl-C to abort" 132 | 133 | 134 | puts "" 135 | puts "${MKL_BLUE}Creating $proj_dir/mklove/modules and copying files${MKL_CLR_RESET}" 136 | 137 | mkdir -p "$proj_dir/mklove/modules" || fatal "Failed to create directory" 138 | 139 | if [[ $inst_conf == y ]]; then 140 | cp $CP_V "$mklove_dir/configure" "$proj_dir/" || fatal "Copy failure" 141 | cp $CP_V "$mklove_dir/modules/configure.base" "$proj_dir/mklove/modules" || fatal "Copy failure" 142 | 143 | # Let configure resolve initial dependencies 144 | puts "" 145 | puts "${MKL_BLUE}Calling ./configure --update-modules to resolve initial dependencies${MKL_CLR_RESET}" 146 | (cd "$proj_dir" && MKL_REPO_URL="$mklove_dir" ./configure --update-modules) || puts "${MKL_RED}Update modules failed${MKL_CLR_RESET}" 147 | fi 148 | 149 | if [[ $inst_mkb == y ]]; then 150 | cp $CP_V "$mklove_dir/Makefile.base" "$proj_dir/mklove/" || fatal "Copy failure" 151 | fi 152 | 153 | 154 | puts "" 155 | puts "${MKL_GREEN}Congratulations! mklove is now set up for your project${MKL_CLR_RESET}" 156 | puts "Things to do in your project directory $proj_dir:" 157 | [[ $inst_conf == y ]] && puts " - Create a configure. to add your own checks and --options" 158 | [[ $inst_conf == y ]] && puts " - Use existing mklove configure modules by calling 'mkl_require ' from configure." 159 | [[ $inst_conf == y ]] && puts " - You should ship your project with all required mklove modules included, 160 | do this by calling ./configure --update-modules" 161 | [[ $inst_mkb == y ]] && puts " - Create a Makefile including both Makefile.base and Makefile.config" 162 | [[ $inst_mkb == y ]] && puts " - Write your own targets in your Makefile, or use the available standard targets from Makefile.base" 163 | puts "" 164 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | 4 | BASHVER=$(expr ${BASH_VERSINFO[0]} \* 1000 + ${BASH_VERSINFO[1]}) 5 | 6 | if [ "$BASHVER" -lt 3002 ]; then 7 | echo "ERROR: mklove requires bash version 3.2 or later but you are using $BASH_VERSION ($BASHVER)" 8 | echo " See https://github.com/edenhill/mklove/issues/15" 9 | exit 1 10 | fi 11 | 12 | MKL_CONFIGURE_ARGS="$0 $*" 13 | 14 | # Load base module 15 | source mklove/modules/configure.base 16 | 17 | # Read some special command line options right away that must be known prior to 18 | # sourcing modules. 19 | mkl_in_list "$*" "--no-download" && MKL_NO_DOWNLOAD=1 20 | # Disable downloads when --help is used to avoid blocking calls. 21 | mkl_in_list "$*" "--help" && MKL_NO_DOWNLOAD=1 22 | mkl_in_list "$*" "--debug" && MKL_DEBUG=1 23 | 24 | # This is the earliest possible time to check for color support in 25 | # terminal because mkl_check_terminal_color_support uses mkl_dbg which 26 | # needs to know if MKL_DEBUG is set 27 | mkl_check_terminal_color_support 28 | 29 | # Delete temporary Makefile and header files on exit. 30 | trap "{ rm -f $MKL_OUTMK $MKL_OUTH; }" EXIT 31 | 32 | 33 | 34 | ## 35 | ## Load builtin modules 36 | ## 37 | 38 | # Builtin options, etc. 39 | mkl_require builtin 40 | 41 | # Host/target support 42 | mkl_require host 43 | 44 | # Compiler detection 45 | mkl_require cc 46 | 47 | 48 | # Load application provided modules (in current directory), if any. 49 | for fname in configure.* ; do 50 | if [[ $fname = 'configure.*' ]]; then 51 | continue 52 | fi 53 | 54 | # Skip temporary files 55 | if [[ $fname = *~ ]]; then 56 | continue 57 | fi 58 | 59 | mkl_require $fname 60 | done 61 | 62 | 63 | 64 | 65 | ## 66 | ## Argument parsing (options) 67 | ## 68 | ## 69 | 70 | _SAVE_ARGS="$*" 71 | 72 | # Parse arguments 73 | while [[ ! -z $@ ]]; do 74 | if [[ $1 != --* ]]; then 75 | mkl_err "Unknown non-option argument: $1" 76 | mkl_usage 77 | exit 1 78 | fi 79 | 80 | opt=${1#--} 81 | shift 82 | 83 | if [[ $opt = *=* ]]; then 84 | name="${opt%%=*}" 85 | arg="${opt#*=}" 86 | eqarg=1 87 | else 88 | name="$opt" 89 | arg="" 90 | eqarg=0 91 | fi 92 | 93 | safeopt="$(mkl_env_esc $name)" 94 | 95 | if ! mkl_func_exists opt_$safeopt ; then 96 | mkl_err "Unknown option $opt" 97 | mkl_usage 98 | exit 1 99 | fi 100 | 101 | # Check if this option needs an argument. 102 | reqarg=$(mkl_meta_get "MKL_OPT_ARGS" "$(mkl_env_esc $name)") 103 | if [[ ! -z $reqarg ]]; then 104 | if [[ $eqarg == 0 && -z $arg ]]; then 105 | arg="$1" 106 | shift 107 | 108 | if [[ -z $arg && $reqarg != '\*' ]]; then 109 | mkl_err "Missing argument to option --$name $reqarg" 110 | exit 1 111 | fi 112 | fi 113 | else 114 | if [[ ! -z $arg ]]; then 115 | mkl_err "Option --$name expects no argument" 116 | exit 1 117 | fi 118 | arg=y 119 | fi 120 | 121 | case $name in 122 | re|reconfigure) 123 | oldcmd=$(head -1 config.log | grep '^# configure exec: ' | \ 124 | sed -e 's/^\# configure exec: [^ ]*configure//') 125 | echo "Reconfiguring: $0 $oldcmd" 126 | exec $0 $oldcmd 127 | ;; 128 | 129 | list-modules) 130 | echo "Modules loaded:" 131 | for mod in $MKL_MODULES ; do 132 | echo " $mod" 133 | done 134 | exit 0 135 | ;; 136 | 137 | list-checks) 138 | echo "Check functions in calling order:" 139 | for mf in $MKL_CHECKS ; do 140 | mod=${mf%:*} 141 | func=${mf#*:} 142 | echo -e "${MKL_GREEN}From module $mod:$MKL_CLR_RESET" 143 | declare -f $func 144 | echo "" 145 | done 146 | exit 0 147 | ;; 148 | 149 | update-modules) 150 | fails=0 151 | echo "Updating modules" 152 | for mod in $MKL_MODULES ; do 153 | [[ $mod == "self" ]] && continue 154 | echo -n "Updating $mod..." 155 | if mkl_module_download "$mod" > /dev/null ; then 156 | echo -e "${MKL_GREEN}ok${MKL_CLR_RESET}" 157 | else 158 | echo -e "${MKL_RED}failed${MKL_CLR_RESET}" 159 | fails=$(expr $fails + 1) 160 | fi 161 | done 162 | exit $fails 163 | ;; 164 | 165 | help) 166 | mkl_usage 167 | exit 0 168 | ;; 169 | 170 | *) 171 | opt_$safeopt "$arg" || exit 1 172 | mkl_var_append MKL_OPTS_SET "$safeopt" 173 | ;; 174 | esac 175 | done 176 | 177 | if [[ ! -z $MKL_CLEAN ]]; then 178 | mkl_clean 179 | exit 0 180 | fi 181 | 182 | # Move away previous log file 183 | [[ -f $MKL_OUTDBG ]] && mv $MKL_OUTDBG ${MKL_OUTDBG}.old 184 | 185 | 186 | # Create output files 187 | echo "# configure exec: $0 $_SAVE_ARGS" >> $MKL_OUTDBG 188 | echo "# On $(date)" >> $MKL_OUTDBG 189 | 190 | rm -f $MKL_OUTMK $MKL_OUTH 191 | 192 | 193 | # Load cache file 194 | mkl_cache_read 195 | 196 | # Run checks 197 | mkl_checks_run 198 | 199 | # Check accumulated failures, will not return on failure. 200 | mkl_check_fails 201 | 202 | # Generate outputs 203 | mkl_generate 204 | 205 | # Summarize what happened 206 | mkl_summary 207 | 208 | # Write cache file 209 | mkl_cache_write 210 | 211 | 212 | echo "" 213 | echo "Now type 'make' to build" 214 | trap - EXIT 215 | exit 0 216 | -------------------------------------------------------------------------------- /modules/configure.cc: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Compiler detection 4 | # Sets: 5 | # CC, CXX, CFLAGS, CPPFLAGS, LDFLAGS, ARFLAGS, PKG_CONFIG, INSTALL, MBITS 6 | 7 | 8 | mkl_require host 9 | 10 | function checks { 11 | 12 | # C compiler 13 | mkl_meta_set "ccenv" "name" "C compiler from CC env" 14 | if ! mkl_command_check "ccenv" "WITH_CC" cont "$CC --version"; then 15 | if mkl_command_check "gcc" "WITH_GCC" cont "gcc --version"; then 16 | CC=gcc 17 | elif mkl_command_check "clang" "WITH_CLANG" cont "clang --version"; then 18 | CC=clang 19 | elif mkl_command_check "cc" "WITH_CC" fail "cc --version"; then 20 | CC=cc 21 | fi 22 | fi 23 | export CC="${CC}" 24 | mkl_mkvar_set CC CC "$CC" 25 | 26 | if [[ $MKL_CC_WANT_CXX == 1 ]]; then 27 | # C++ compiler 28 | mkl_meta_set "cxxenv" "name" "C++ compiler from CXX env" 29 | if ! mkl_command_check "cxxenv" "WITH_CXX" cont "$CXX --version" ; then 30 | mkl_meta_set "gxx" "name" "C++ compiler (g++)" 31 | mkl_meta_set "clangxx" "name" "C++ compiler (clang++)" 32 | mkl_meta_set "cxx" "name" "C++ compiler (c++)" 33 | if mkl_command_check "gxx" "WITH_GXX" cont "g++ --version"; then 34 | CXX=g++ 35 | elif mkl_command_check "clangxx" "WITH_CLANGXX" cont "clang++ --version"; then 36 | CXX=clang++ 37 | elif mkl_command_check "cxx" "WITH_CXX" fail "c++ --version"; then 38 | CXX=c++ 39 | fi 40 | fi 41 | export CXX="${CXX}" 42 | mkl_mkvar_set "CXX" CXX "$CXX" 43 | fi 44 | 45 | # Handle machine bits, if specified. 46 | if [[ ! -z "$MBITS" ]]; then 47 | mkl_meta_set mbits_m name "mbits compiler flag (-m$MBITS)" 48 | if mkl_compile_check mbits_m "" fail CC "-m$MBITS"; then 49 | mkl_mkvar_append CPPFLAGS CPPFLAGS "-m$MBITS" 50 | mkl_mkvar_append LDFLAGS LDFLAGS "-m$MBITS" 51 | fi 52 | if [[ -z "$ARFLAGS" && $MBITS == 64 && $MKL_DISTRO == "sunos" ]]; then 53 | # Turn on 64-bit archives on SunOS 54 | mkl_mkvar_append ARFLAGS ARFLAGS "S" 55 | fi 56 | fi 57 | 58 | # Provide prefix and checks for various other build tools. 59 | local t= 60 | for t in LD:ld NM:nm OBJDUMP:objdump STRIP:strip LIBTOOL:libtool RANLIB:ranlib ; do 61 | local tenv=${t%:*} 62 | t=${t#*:} 63 | local tval="${!tenv}" 64 | 65 | [[ -z $tval ]] && tval="$t" 66 | 67 | if mkl_prog_check "$t" "" disable "$tval" ; then 68 | if [[ $tval != ${!tenv} ]]; then 69 | export "$tenv"="$tval" 70 | fi 71 | mkl_mkvar_set $tenv $tenv "$tval" 72 | fi 73 | done 74 | 75 | # Compiler and linker flags 76 | [[ ! -z $CFLAGS ]] && mkl_mkvar_set "CFLAGS" "CFLAGS" "$CFLAGS" 77 | [[ ! -z $CPPFLAGS ]] && mkl_mkvar_set "CPPFLAGS" "CPPFLAGS" "$CPPFLAGS" 78 | [[ ! -z $CXXFLAGS ]] && mkl_mkvar_set "CXXFLAGS" "CXXFLAGS" "$CXXFLAGS" 79 | [[ ! -z $LDFLAGS ]] && mkl_mkvar_set "LDFLAGS" "LDFLAGS" "$LDFLAGS" 80 | [[ ! -z $ARFLAGS ]] && mkl_mkvar_set "ARFLAGS" "ARFLAGS" "$ARFLAGS" 81 | 82 | if [[ $MKL_NO_DEBUG_SYMBOLS != "y" ]]; then 83 | # Add debug symbol flag (-g) 84 | # OSX 10.9 requires -gstrict-dwarf for some reason. 85 | mkl_meta_set cc_g_dwarf name "debug symbols compiler flag (-g...)" 86 | if [[ $MKL_DISTRO == "osx" ]]; then 87 | if mkl_compile_check cc_g_dwarf "" cont CC "-gstrict-dwarf"; then 88 | mkl_mkvar_append CPPFLAGS CPPFLAGS "-gstrict-dwarf" 89 | else 90 | mkl_mkvar_append CPPFLAGS CPPFLAGS "-g" 91 | fi 92 | else 93 | mkl_mkvar_append CPPFLAGS CPPFLAGS "-g" 94 | fi 95 | fi 96 | 97 | 98 | # pkg-config 99 | if [ -z "$PKG_CONFIG" ]; then 100 | PKG_CONFIG=pkg-config 101 | fi 102 | 103 | if mkl_command_check "pkgconfig" "WITH_PKGCONFIG" cont "$PKG_CONFIG --version"; then 104 | export PKG_CONFIG 105 | fi 106 | mkl_mkvar_set "pkgconfig" PKG_CONFIG $PKG_CONFIG 107 | 108 | [[ ! -z "$append_PKG_CONFIG_PATH" ]] && mkl_env_append PKG_CONFIG_PATH "$append_PKG_CONFIG_PATH" ":" 109 | 110 | # install 111 | if [ -z "$INSTALL" ]; then 112 | if [[ $MKL_DISTRO == "sunos" ]]; then 113 | mkl_meta_set ginstall name "GNU install" 114 | if mkl_command_check ginstall "" ignore "ginstall --version"; then 115 | INSTALL=$(which ginstall) 116 | else 117 | INSTALL=$(which install) 118 | fi 119 | else 120 | INSTALL=$(which install) 121 | fi 122 | fi 123 | 124 | if mkl_command_check "install" "WITH_INSTALL" cont "$INSTALL --version"; then 125 | export INSTALL 126 | fi 127 | mkl_mkvar_set "install" INSTALL $INSTALL 128 | 129 | 130 | # Enable profiling if desired 131 | if [[ $WITH_PROFILING == y ]]; then 132 | mkl_allvar_set "" "WITH_PROFILING" "y" 133 | mkl_mkvar_append CPPFLAGS CPPFLAGS "-pg" 134 | mkl_mkvar_append LDFLAGS LDFLAGS "-pg" 135 | fi 136 | 137 | # Optimization 138 | if [[ $WITHOUT_OPTIMIZATION == n ]]; then 139 | mkl_mkvar_append CPPFLAGS CPPFLAGS "-O2" 140 | else 141 | mkl_mkvar_append CPPFLAGS CPPFLAGS "-O0" 142 | fi 143 | 144 | # Static linking 145 | if [[ $WITH_STATIC_LINKING == y ]]; then 146 | # LDFLAGS_STATIC is the LDFLAGS needed to enable static linking 147 | # of sub-sequent libraries, while 148 | # LDFLAGS_DYNAMIC is the LDFLAGS needed to enable dynamic linking. 149 | if [[ $MKL_DISTRO != "osx" ]]; then 150 | mkl_mkvar_set staticlinking LDFLAGS_STATIC "-Wl,-Bstatic" 151 | mkl_mkvar_set staticlinking LDFLAGS_DYNAMIC "-Wl,-Bdynamic" 152 | mkl_mkvar_set staticlinking HAS_LDFLAGS_STATIC y 153 | else 154 | # OSX linker can't enable/disable static linking so we'll 155 | # need to find the .a through STATIC_LIB_libname env var 156 | mkl_mkvar_set staticlinking HAS_LDFLAGS_STATIC n 157 | # libtool -static supported 158 | mkl_mkvar_set staticlinking HAS_LIBTOOL_STATIC y 159 | fi 160 | fi 161 | } 162 | 163 | 164 | mkl_option "Compiler" "env:CC" "--cc=CC" "Build using C compiler CC" "\$CC" 165 | mkl_option "Compiler" "env:CXX" "--cxx=CXX" "Build using C++ compiler CXX" "\$CXX" 166 | mkl_option "Compiler" "ARCH" "--arch=ARCH" "Build for architecture" "$(uname -m)" 167 | mkl_option "Compiler" "CPU" "--cpu=CPU" "Build and optimize for specific CPU" "generic" 168 | mkl_option "Compiler" "MBITS" "--mbits=BITS" "Machine bits (32 or 64)" "" 169 | 170 | for n in CFLAGS CPPFLAGS CXXFLAGS LDFLAGS ARFLAGS; do 171 | mkl_option "Compiler" "mk:$n" "--$n=$n" "Add $n flags" 172 | done 173 | 174 | mkl_option "Compiler" "env:append_PKG_CONFIG_PATH" "--pkg-config-path=EXTRA_PATHS" "Extra paths for pkg-config" 175 | 176 | mkl_option "Compiler" "WITH_PROFILING" "--enable-profiling" "Enable profiling" 177 | mkl_option "Compiler" "WITH_STATIC_LINKING" "--enable-static" "Enable static linking" 178 | mkl_option "Compiler" "WITHOUT_OPTIMIZATION" "--disable-optimization" "Disable optimization flag to compiler" "n" 179 | mkl_option "Compiler" "env:MKL_NO_DEBUG_SYMBOLS" "--disable-debug-symbols" "Disable debugging symbols" "n" 180 | mkl_option "Compiler" "env:MKL_WANT_WERROR" "--enable-werror" "Enable compiler warnings as errors" "n" 181 | mkl_option "Compiler" "WITH_STRIP" "--enable-strip" "Strip libraries when installing" "n" 182 | -------------------------------------------------------------------------------- /Makefile.base: -------------------------------------------------------------------------------- 1 | # Base Makefile providing various standard targets 2 | # Part of mklove suite but may be used independently. 3 | 4 | MKL_RED?= \033[031m 5 | MKL_GREEN?= \033[032m 6 | MKL_YELLOW?= \033[033m 7 | MKL_BLUE?= \033[034m 8 | MKL_CLR_RESET?= \033[0m 9 | 10 | DEPS= $(OBJS:%.o=%.d) 11 | 12 | # TOPDIR is "TOPDIR/mklove/../" i.e., TOPDIR. 13 | # We do it with two dir calls instead of /.. to support mklove being symlinked. 14 | MKLOVE_DIR := $(dir $(lastword $(MAKEFILE_LIST))) 15 | TOPDIR = $(MKLOVE_DIR:mklove/=.) 16 | 17 | 18 | # Convert LIBNAME ("libxyz") to "xyz" 19 | LIBNAME0=$(LIBNAME:lib%=%) 20 | 21 | # Silence lousy default ARFLAGS (rv) 22 | ARFLAGS= 23 | 24 | ifndef MKL_MAKEFILE_CONFIG 25 | -include $(TOPDIR)/Makefile.config 26 | endif 27 | 28 | # Use C compiler as default linker. 29 | # C++ libraries will need to override this with CXX after 30 | # including Makefile.base 31 | CC_LD?=$(CC) 32 | 33 | _UNAME_S := $(shell uname -s) 34 | ifeq ($(_UNAME_S),Darwin) 35 | LIBFILENAME=$(LIBNAME).$(LIBVER)$(SOLIB_EXT) 36 | LIBFILENAMELINK=$(LIBNAME)$(SOLIB_EXT) 37 | LIBFILENAMEDBG=$(LIBNAME)-dbg.$(LIBVER)$(SOLIB_EXT) 38 | LDD_PRINT="otool -L" 39 | else 40 | LIBFILENAME=$(LIBNAME)$(SOLIB_EXT).$(LIBVER) 41 | LIBFILENAMELINK=$(LIBNAME)$(SOLIB_EXT) 42 | LIBFILENAMEDBG=$(LIBNAME)-dbg$(SOLIB_EXT).$(LIBVER) 43 | LDD_PRINT="ldd" 44 | endif 45 | 46 | # DESTDIR must be an absolute path 47 | ifneq ($(DESTDIR),) 48 | DESTDIR:=$(abspath $(DESTDIR)) 49 | endif 50 | 51 | INSTALL?= install 52 | INSTALL_PROGRAM?= $(INSTALL) 53 | INSTALL_DATA?= $(INSTALL) -m 644 54 | 55 | prefix?= /usr/local 56 | exec_prefix?= $(prefix) 57 | bindir?= $(exec_prefix)/bin 58 | sbindir?= $(exec_prefix)/sbin 59 | libexecdir?= $(exec_prefix)/libexec/ # append PKGNAME on install 60 | datarootdir?= $(prefix)/share 61 | datadir?= $(datarootdir) # append PKGNAME on install 62 | sysconfdir?= $(prefix)/etc 63 | sharedstatedir?=$(prefix)/com 64 | localestatedir?=$(prefix)/var 65 | runstatedir?= $(localestatedir)/run 66 | includedir?= $(prefix)/include 67 | docdir?= $(datarootdir)/doc/$(PKGNAME) 68 | infodir?= $(datarootdir)/info 69 | libdir?= $(prefix)/lib 70 | localedir?= $(datarootdir)/locale 71 | pkgconfigdir?= $(libdir)/pkgconfig 72 | mandir?= $(datarootdir)/man 73 | man1dir?= $(mandir)/man1 74 | man2dir?= $(mandir)/man2 75 | man3dir?= $(mandir)/man3 76 | man4dir?= $(mandir)/man4 77 | man5dir?= $(mandir)/man5 78 | man6dir?= $(mandir)/man6 79 | man7dir?= $(mandir)/man7 80 | man8dir?= $(mandir)/man8 81 | 82 | # An application Makefile should set DISABLE_LDS=y prior to 83 | # including Makefile.base if it does not wish to have a linker-script. 84 | ifeq ($(WITH_LDS)-$(DISABLE_LDS),y-) 85 | # linker-script file 86 | LIBNAME_LDS?=$(LIBNAME).lds 87 | endif 88 | 89 | # Checks that mklove is set up and ready for building 90 | mklove-check: 91 | @if [ ! -f "$(TOPDIR)/Makefile.config" ]; then \ 92 | printf "$(MKL_RED)$(TOPDIR)/Makefile.config missing: please run ./configure$(MKL_CLR_RESET)\n" ; \ 93 | exit 1 ; \ 94 | fi 95 | 96 | %.o: %.c 97 | $(CC) -MD -MP $(CPPFLAGS) $(CFLAGS) -c $< -o $@ 98 | 99 | %.o: %.cpp 100 | $(CXX) -MD -MP $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ 101 | 102 | 103 | lib: $(LIBFILENAME) $(LIBNAME).a $(LIBNAME)-static.a $(LIBFILENAMELINK) lib-gen-pkg-config 104 | 105 | # Linker-script (if WITH_LDS=y): overridable by application Makefile 106 | $(LIBNAME_LDS): 107 | 108 | $(LIBFILENAME): $(OBJS) $(LIBNAME_LDS) 109 | @printf "$(MKL_YELLOW)Creating shared library $@$(MKL_CLR_RESET)\n" 110 | $(CC_LD) $(LDFLAGS) $(LIB_LDFLAGS) $(OBJS) -o $@ $(LIBS) 111 | ifeq ($(WITH_STRIP),y) 112 | cp $@ $(LIBFILENAMEDBG) 113 | $(STRIP) -S $@ 114 | endif 115 | 116 | $(LIBNAME).a: $(OBJS) 117 | @printf "$(MKL_YELLOW)Creating static library $@$(MKL_CLR_RESET)\n" 118 | $(AR) rcs$(ARFLAGS) $@ $(OBJS) 119 | ifeq ($(WITH_STRIP),y) 120 | cp $@ $(LIBNAME)-dbg.a 121 | $(STRIP) -S $@ 122 | $(RANLIB) $@ 123 | endif 124 | 125 | ifeq ($(MKL_NO_SELFCONTAINED_STATIC_LIB),y) 126 | _STATIC_FILENAME=$(LIBNAME).a 127 | $(LIBNAME)-static.a: 128 | 129 | else # MKL_NO_SELFCONTAINED_STATIC_LIB 130 | 131 | ifneq ($(MKL_STATIC_LIBS),) 132 | _STATIC_FILENAME=$(LIBNAME)-static.a 133 | $(LIBNAME)-static.a: $(LIBNAME).a 134 | @printf "$(MKL_YELLOW)Creating self-contained static library $@$(MKL_CLR_RESET)\n" 135 | ifeq ($(HAS_LIBTOOL_STATIC),y) 136 | $(LIBTOOL) -static -o $@ - $(LIBNAME).a $(MKL_STATIC_LIBS) 137 | else # HAS_LIBTOOL_STATIC 138 | (_tmp=$$(mktemp arstaticXXXXXX) ; \ 139 | echo "CREATE $@" > $$_tmp ; \ 140 | for _f in $(LIBNAME).a $(MKL_STATIC_LIBS) ; do \ 141 | echo "ADDLIB $$_f" >> $$_tmp ; \ 142 | done ; \ 143 | echo "SAVE" >> $$_tmp ; \ 144 | echo "END" >> $$_tmp ; \ 145 | cat $$_tmp ; \ 146 | ar -M < $$_tmp || exit 1 ; \ 147 | rm $$_tmp) 148 | endif # HAS_LIBTOOL_STATIC 149 | cp $@ $(LIBNAME)-static-dbg.a 150 | # The self-contained static library is always stripped, regardless 151 | # of --enable-strip, since otherwise it would become too big. 152 | $(STRIP) -S $@ 153 | $(RANLIB) $@ 154 | 155 | ifneq ($(MKL_DYNAMIC_LIBS),) 156 | @printf "$(MKL_RED)WARNING:$(MKL_YELLOW) $@: The following libraries were not available as static libraries and need to be linked dynamically: $(MKL_DYNAMIC_LIBS)$(MKL_CLR_RESET)\n" 157 | endif # MKL_DYNAMIC_LIBS 158 | 159 | else # MKL_STATIC_LIBS is empty 160 | _STATIC_FILENAME=$(LIBNAME).a 161 | $(LIBNAME)-static.a: 162 | @printf "$(MKL_RED)WARNING:$(MKL_YELLOW) $@: Not creating self-contained static library $@: no static libraries available/enabled$(MKL_CLR_RESET)\n" 163 | endif # MKL_STATIC_LIBS 164 | 165 | endif # MKL_NO_SELFCONTAINED_STATIC_LIB 166 | 167 | $(LIBFILENAMELINK): $(LIBFILENAME) 168 | @printf "$(MKL_YELLOW)Creating $@ symlink$(MKL_CLR_RESET)\n" 169 | rm -f "$@" && ln -s "$^" "$@" 170 | 171 | 172 | # pkg-config .pc file definition 173 | ifeq ($(GEN_PKG_CONFIG),y) 174 | define _PKG_CONFIG_DEF 175 | prefix=$(prefix) 176 | libdir=$(libdir) 177 | includedir=$(includedir) 178 | 179 | Name: $(LIBNAME) 180 | Description: $(MKL_APP_DESC_ONELINE) 181 | Version: $(MKL_APP_VERSION) 182 | Requires.private: $(MKL_PKGCONFIG_REQUIRES_PRIVATE) 183 | Cflags: -I$${includedir} 184 | Libs: -L$${libdir} -l$(LIBNAME0) 185 | Libs.private: $(MKL_PKGCONFIG_LIBS_PRIVATE) 186 | endef 187 | 188 | export _PKG_CONFIG_DEF 189 | 190 | define _PKG_CONFIG_STATIC_DEF 191 | prefix=$(prefix) 192 | libdir=$(libdir) 193 | includedir=$(includedir) 194 | 195 | Name: $(LIBNAME)-static 196 | Description: $(MKL_APP_DESC_ONELINE) (static) 197 | Version: $(MKL_APP_VERSION) 198 | Requires: $(MKL_PKGCONFIG_REQUIRES:rdkafka=rdkafka-static) 199 | Cflags: -I$${includedir} 200 | Libs: -L$${libdir} $${pc_sysrootdir}$${libdir}/$(_STATIC_FILENAME) $(MKL_PKGCONFIG_LIBS_PRIVATE) 201 | endef 202 | 203 | export _PKG_CONFIG_STATIC_DEF 204 | 205 | $(LIBNAME0).pc: $(TOPDIR)/Makefile.config 206 | @printf "$(MKL_YELLOW)Generating pkg-config file $@$(MKL_CLR_RESET)\n" 207 | @echo "$$_PKG_CONFIG_DEF" > $@ 208 | 209 | $(LIBNAME0)-static.pc: $(TOPDIR)/Makefile.config $(LIBNAME)-static.a 210 | @printf "$(MKL_YELLOW)Generating pkg-config file $@$(MKL_CLR_RESET)\n" 211 | @echo "$$_PKG_CONFIG_STATIC_DEF" > $@ 212 | 213 | lib-gen-pkg-config: $(LIBNAME0).pc $(LIBNAME0)-static.pc 214 | 215 | lib-clean-pkg-config: 216 | rm -f $(LIBNAME0).pc $(LIBNAME0)-static.pc 217 | else 218 | lib-gen-pkg-config: 219 | lib-clean-pkg-config: 220 | endif 221 | 222 | 223 | $(BIN): $(OBJS) 224 | @printf "$(MKL_YELLOW)Creating program $@$(MKL_CLR_RESET)\n" 225 | $(CC_LD) $(CPPFLAGS) $(LDFLAGS) $(OBJS) -o $@ $(LIBS) 226 | 227 | 228 | file-check: 229 | @printf "$(MKL_YELLOW)Checking $(LIBNAME) integrity$(MKL_CLR_RESET)\n" 230 | @RET=true ; \ 231 | for f in $(CHECK_FILES) ; do \ 232 | printf "%-30s " $$f ; \ 233 | if [ -f "$$f" ]; then \ 234 | printf "$(MKL_GREEN)OK$(MKL_CLR_RESET)\n" ; \ 235 | else \ 236 | printf "$(MKL_RED)MISSING$(MKL_CLR_RESET)\n" ; \ 237 | RET=false ; \ 238 | fi ; \ 239 | done ; \ 240 | $$RET 241 | 242 | copyright-check: 243 | @(_exit=0 ; \ 244 | for f in $$(git ls-tree -r --name-only HEAD | \ 245 | egrep '\.(c|h|cpp|sh|py|pl)$$' ) ; do \ 246 | if [ -n "$(MKL_COPYRIGHT_SKIP)" ] && echo "$$f" | egrep -q "$(MKL_COPYRIGHT_SKIP)" ; then \ 247 | continue ; \ 248 | fi ; \ 249 | if ! head -40 $$f | grep -qi copyright $$f ; then \ 250 | echo error: Copyright missing in $$f ; \ 251 | _exit=1 ; \ 252 | fi; \ 253 | done ; \ 254 | exit $$_exit) 255 | 256 | 257 | lib-install: 258 | @printf "$(MKL_YELLOW)Install $(LIBNAME) to $$DESTDIR$(prefix)$(MKL_CLR_RESET)\n" 259 | $(INSTALL) -d $$DESTDIR$(includedir)/$(PKGNAME) 260 | $(INSTALL) -d $$DESTDIR$(libdir) 261 | $(INSTALL) $(HDRS) $$DESTDIR$(includedir)/$(PKGNAME) 262 | $(INSTALL) $(LIBNAME).a $$DESTDIR$(libdir) 263 | [ ! -f $(LIBNAME)-static.a ] || $(INSTALL) $(LIBNAME)-static.a $$DESTDIR$(libdir) 264 | $(INSTALL) $(LIBFILENAME) $$DESTDIR$(libdir) 265 | [ -f "$(LIBNAME0).pc" ] && ( \ 266 | $(INSTALL) -d $$DESTDIR$(pkgconfigdir) && \ 267 | $(INSTALL) -m 0644 $(LIBNAME0).pc $$DESTDIR$(pkgconfigdir) \ 268 | ) 269 | [ -f "$(LIBNAME0)-static.pc" ] && ( \ 270 | $(INSTALL) -d $$DESTDIR$(pkgconfigdir) && \ 271 | $(INSTALL) -m 0644 $(LIBNAME0)-static.pc $$DESTDIR$(pkgconfigdir) \ 272 | ) 273 | (cd $$DESTDIR$(libdir) && ln -sf $(LIBFILENAME) $(LIBFILENAMELINK)) 274 | 275 | lib-uninstall: 276 | @printf "$(MKL_YELLOW)Uninstall $(LIBNAME) from $$DESTDIR$(prefix)$(MKL_CLR_RESET)\n" 277 | for hdr in $(HDRS) ; do \ 278 | rm -f $$DESTDIR$(includedir)/$(PKGNAME)/$$hdr ; done 279 | rm -f $$DESTDIR$(libdir)/$(LIBNAME).a 280 | rm -f $$DESTDIR$(libdir)/$(LIBNAME)-static.a 281 | rm -f $$DESTDIR$(libdir)/$(LIBFILENAME) 282 | rm -f $$DESTDIR$(libdir)/$(LIBFILENAMELINK) 283 | rmdir $$DESTDIR$(includedir)/$(PKGNAME) || true 284 | rm -f $$DESTDIR$(pkgconfigdir)/$(LIBNAME0).pc 285 | rm -f $$DESTDIR$(pkgconfigdir)/$(LIBNAME0)-static.pc 286 | rmdir $$DESTDIR$(pkgconfigdir) || true 287 | 288 | bin-install: 289 | @printf "$(MKL_YELLOW)Install $(BIN) to $$DESTDIR$(prefix)$(MKL_CLR_RESET)\n" 290 | $(INSTALL) -d $$DESTDIR$(bindir) && \ 291 | $(INSTALL) $(BIN) $$DESTDIR$(bindir) 292 | 293 | bin-uninstall: 294 | @printf "$(MKL_YELLOW)Uninstall $(BIN) from $$DESTDIR$(prefix)$(MKL_CLR_RESET)\n" 295 | rm -f $$DESTDIR$(bindir)/$(BIN) 296 | rmdir $$DESTDIR$(bindir) || true 297 | 298 | doc-install: $(DOC_FILES) 299 | @printf "$(MKL_YELLOW)Installing documentation to $$DESTDIR$(prefix)$(MKL_CLR_RESET)\n" 300 | $(INSTALL) -d $$DESTDIR$(docdir) 301 | $(INSTALL) $(DOC_FILES) $$DESTDIR$(docdir) 302 | 303 | doc-uninstall: 304 | @printf "$(MKL_YELLOW)Uninstall documentation from $$DESTDIR$(prefix)$(MKL_CLR_RESET)\n" 305 | for _f in $(DOC_FILES) ; do rm -f $$DESTDIR$(docdir)/$$_f ; done 306 | rmdir $$DESTDIR$(docdir) || true 307 | 308 | generic-clean: 309 | rm -f $(OBJS) $(DEPS) 310 | 311 | lib-clean: generic-clean lib-clean-pkg-config 312 | rm -f $(LIBNAME)*.a $(LIBFILENAME) $(LIBFILENAMEDBG) \ 313 | $(LIBFILENAMELINK) $(LIBNAME_LDS) 314 | 315 | bin-clean: generic-clean 316 | rm -f $(BIN) 317 | 318 | deps-clean: 319 | rm -rf "$(MKLOVE_DIR)/deps" 320 | -------------------------------------------------------------------------------- /modules/configure.base: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # 4 | # mklove base configure module, implements the mklove configure framework 5 | # 6 | 7 | MKL_MODULES="base" 8 | MKL_CACHEVARS="CFLAGS LDFLAGS PKG_CONFIG_PATH" 9 | MKL_MKVARS="" 10 | MKL_DEFINES="" 11 | MKL_CHECKS="" 12 | MKL_LOAD_STACK="" 13 | 14 | MKL_IDNEXT=1 15 | 16 | # Default mklove directory to PWD/mklove 17 | [[ -z "$MKLOVE_DIR" ]] && MKLOVE_DIR="$PWD/mklove" 18 | 19 | MKL_OUTMK="$PWD/_mklout.mk" 20 | MKL_OUTH="$PWD/_mklout.h" 21 | MKL_OUTDBG="$PWD/config.log" 22 | 23 | MKL_GENERATORS="base:mkl_generate_late_vars" 24 | MKL_CLEANERS="" 25 | 26 | MKL_FAILS="" 27 | MKL_LATE_VARS="" 28 | 29 | MKL_OPTS_SET="" 30 | 31 | MKL_RED="" 32 | MKL_GREEN="" 33 | MKL_YELLOW="" 34 | MKL_BLUE="" 35 | MKL_CLR_RESET="" 36 | 37 | 38 | MKL_NO_DOWNLOAD=0 39 | MKL_INSTALL_DEPS=n 40 | MKL_SOURCE_DEPS_ONLY=n 41 | 42 | MKL_DESTDIR_ADDED=n 43 | 44 | if [[ -z "$MKL_REPO_URL" ]]; then 45 | MKL_REPO_URL="http://github.com/edenhill/mklove/raw/master" 46 | fi 47 | 48 | 49 | 50 | ########################################################################### 51 | # 52 | # Variable types: 53 | # env - Standard environment variables. 54 | # var - mklove runtime variable, cached or not. 55 | # mkvar - Makefile variables, also sets runvar 56 | # define - config.h variables/defines 57 | # 58 | ########################################################################### 59 | 60 | # Low level variable assignment 61 | # Arguments: 62 | # variable name 63 | # variable value 64 | function mkl_var0_set { 65 | export "$1"="$2" 66 | } 67 | 68 | # Sets a runtime variable (only used during configure) 69 | # If "cache" is provided these variables are cached to config.cache. 70 | # Arguments: 71 | # variable name 72 | # variable value 73 | # [ "cache" ] 74 | function mkl_var_set { 75 | mkl_var0_set "$1" "$2" 76 | if [[ $3 == "cache" ]]; then 77 | if ! mkl_in_list "$MKL_CACHEVARS" "$1" ; then 78 | MKL_CACHEVARS="$MKL_CACHEVARS $1" 79 | fi 80 | fi 81 | } 82 | 83 | # Unsets a mkl variable 84 | # Arguments: 85 | # variable name 86 | function mkl_var_unset { 87 | unset $1 88 | } 89 | 90 | # Appends to a mkl variable (space delimited) 91 | # Arguments: 92 | # variable name 93 | # variable value 94 | function mkl_var_append { 95 | if [[ -z ${!1} ]]; then 96 | mkl_var_set "$1" "$2" 97 | else 98 | mkl_var0_set "$1" "${!1} $2" 99 | fi 100 | } 101 | 102 | 103 | # Prepends to a mkl variable (space delimited) 104 | # Arguments: 105 | # variable name 106 | # variable value 107 | function mkl_var_prepend { 108 | if [[ -z ${!1} ]]; then 109 | mkl_var_set "$1" "$2" 110 | else 111 | mkl_var0_set "$1" "$2 ${!1}" 112 | fi 113 | } 114 | 115 | # Shift the first word off a variable. 116 | # Arguments: 117 | # variable name 118 | function mkl_var_shift { 119 | local n="${!1}" 120 | mkl_var0_set "$1" "${n#* }" 121 | return 0 122 | } 123 | 124 | 125 | # Returns the contents of mkl variable 126 | # Arguments: 127 | # variable name 128 | function mkl_var_get { 129 | echo "${!1}" 130 | } 131 | 132 | 133 | 134 | 135 | # Set environment variable (runtime) 136 | # These variables are not cached nor written to any of the output files, 137 | # its just simply a helper wrapper for standard envs. 138 | # Arguments: 139 | # varname 140 | # varvalue 141 | function mkl_env_set { 142 | mkl_var0_set "$1" "$2" 143 | } 144 | 145 | # Append to environment variable 146 | # Arguments: 147 | # varname 148 | # varvalue 149 | # [ separator (" ") ] 150 | function mkl_env_append { 151 | local sep=" " 152 | if [[ -z ${!1} ]]; then 153 | mkl_env_set "$1" "$2" 154 | else 155 | [ ! -z ${3} ] && sep="$3" 156 | mkl_var0_set "$1" "${!1}${sep}$2" 157 | fi 158 | 159 | } 160 | 161 | # Prepend to environment variable 162 | # Arguments: 163 | # varname 164 | # varvalue 165 | # [ separator (" ") ] 166 | function mkl_env_prepend { 167 | local sep=" " 168 | if [[ -z ${!1} ]]; then 169 | mkl_env_set "$1" "$2" 170 | else 171 | [ ! -z ${3} ] && sep="$3" 172 | mkl_var0_set "$1" "$2${sep}${!1}" 173 | fi 174 | 175 | } 176 | 177 | 178 | 179 | 180 | # Set a make variable (Makefile.config) 181 | # Arguments: 182 | # config name 183 | # variable name 184 | # value 185 | function mkl_mkvar_set { 186 | if [[ ! -z $2 ]]; then 187 | mkl_env_set "$2" "$3" 188 | mkl_in_list "$MKL_MKVARS" "$2"|| mkl_env_append MKL_MKVARS $2 189 | fi 190 | } 191 | 192 | 193 | # Prepends to a make variable (Makefile.config) 194 | # Arguments: 195 | # config name 196 | # variable name 197 | # value 198 | # [ separator (" ") ] 199 | function mkl_mkvar_prepend { 200 | if [[ ! -z $2 ]]; then 201 | mkl_env_prepend "$2" "$3" "$4" 202 | mkl_in_list "$MKL_MKVARS" "$2"|| mkl_env_append MKL_MKVARS $2 203 | fi 204 | } 205 | 206 | 207 | # Appends to a make variable (Makefile.config) 208 | # Arguments: 209 | # config name 210 | # variable name 211 | # value 212 | # [ separator (" ") ] 213 | function mkl_mkvar_append { 214 | if [[ ! -z $2 ]]; then 215 | mkl_env_append "$2" "$3" "$4" 216 | mkl_in_list "$MKL_MKVARS" "$2"|| mkl_env_append MKL_MKVARS $2 217 | fi 218 | } 219 | 220 | 221 | # Prepends to a make variable (Makefile.config) 222 | # Arguments: 223 | # config name 224 | # variable name 225 | # value 226 | # [ separator (" ") ] 227 | function mkl_mkvar_prepend { 228 | if [[ ! -z $2 ]]; then 229 | mkl_env_prepend "$2" "$3" "$4" 230 | mkl_in_list "$MKL_MKVARS" "$2"|| mkl_env_append MKL_MKVARS $2 231 | fi 232 | } 233 | 234 | # Return mkvar variable value 235 | # Arguments: 236 | # variable name 237 | function mkl_mkvar_get { 238 | [[ -z ${!1} ]] && return 1 239 | echo ${!1} 240 | return 0 241 | } 242 | 243 | 244 | 245 | # Defines a config header define (config.h) 246 | # Arguments: 247 | # config name 248 | # define name 249 | # define value (optional, default: 1) 250 | # if value starts with code: then no "" are added 251 | function mkl_define_set { 252 | 253 | if [[ -z $2 ]]; then 254 | return 0 255 | fi 256 | 257 | local stmt="" 258 | local defid= 259 | if [[ $2 = *\(* ]]; then 260 | # macro 261 | defid="def_${2%%(*}" 262 | else 263 | # define 264 | defid="def_$2" 265 | fi 266 | 267 | [[ -z $1 ]] || stmt="// $1\n" 268 | 269 | local val="$3" 270 | if [[ -z "$val" ]]; then 271 | val="$(mkl_def $2 1)" 272 | fi 273 | 274 | # Define as code, string or integer? 275 | if [[ $val == code:* ]]; then 276 | # Code block, copy verbatim without quotes, strip code: prefix 277 | val=${val#code:} 278 | elif [[ ! ( "$val" =~ ^[0-9]+([lL]?[lL][dDuU]?)?$ || \ 279 | "$val" =~ ^0x[0-9a-fA-F]+([lL]?[lL][dDuU]?)?$ ) ]]; then 280 | # String: quote 281 | val="\"$val\"" 282 | fi 283 | # else: unquoted integer/hex 284 | 285 | stmt="${stmt}#define $2 $val" 286 | mkl_env_set "$defid" "$stmt" 287 | mkl_env_append MKL_DEFINES "$defid" 288 | } 289 | 290 | 291 | 292 | 293 | 294 | # Sets "all" configuration variables, that is: 295 | # for name set: Makefile variable, config.h define 296 | # Will convert value "y"|"n" to 1|0 for config.h 297 | # Arguments: 298 | # config name 299 | # variable name 300 | # value 301 | function mkl_allvar_set { 302 | mkl_mkvar_set "$1" "$2" "$3" 303 | local val=$3 304 | if [[ $3 = "y" ]]; then 305 | val=1 306 | elif [[ $3 = "n" ]]; then 307 | val=0 308 | fi 309 | mkl_define_set "$1" "$2" "$val" 310 | } 311 | 312 | 313 | ########################################################################### 314 | # 315 | # Dependency installation, et.al. 316 | # 317 | # 318 | ########################################################################### 319 | 320 | # Returns the local dependency directory. 321 | function mkl_depdir { 322 | local dir="$MKLOVE_DIR/deps" 323 | [[ -d $dir ]] || mkdir -p "$dir" 324 | if ! grep -q ^deps$ "$MKLOVE_DIR/.gitignore" 2>/dev/null ; then 325 | echo "deps" >> "$MKLOVE_DIR/.gitignore" 326 | fi 327 | 328 | echo "$dir" 329 | } 330 | 331 | # Returns the package's installation directory / DESTDIR. 332 | function mkl_dep_destdir { 333 | echo "$(mkl_depdir)/dest" 334 | } 335 | 336 | # Returns the package's source directory. 337 | function mkl_dep_srcdir { 338 | echo "$(mkl_depdir)/src/$1" 339 | } 340 | 341 | 342 | # Get the static library file name(s) for a package. 343 | function mkl_lib_static_fnames { 344 | local name=$1 345 | mkl_meta_get $name "static" "" 346 | } 347 | 348 | 349 | # Returns true if previous ./configure ran a dep install for this package. 350 | function mkl_dep_install_cached { 351 | local name=$1 352 | 353 | if [[ -n $(mkl_var_get "MKL_STATUS_${1}_INSTALL") ]] || 354 | [[ -n $(mkl_var_get "MKL_STATUS_${1}_INSTALL_SRC") ]]; then 355 | return 0 # true 356 | else 357 | return 1 # false 358 | fi 359 | } 360 | 361 | # Install an external dependency using the platform's native 362 | # package manager. 363 | # Should only be called from mkl_dep_install 364 | # 365 | # Param 1: config name 366 | function mkl_dep_install_pkg { 367 | local name=$1 368 | local iname="${name}_INSTALL" 369 | local retcode=1 # default to fail 370 | local method="none" 371 | local pkgs 372 | local cmd 373 | 374 | mkl_dbg "Attempting native install of dependency $name on $MKL_DISTRO with effective user $EUID" 375 | 376 | 377 | # Try the platform specific installer first. 378 | case ${MKL_DISTRO}-${EUID} in 379 | debian-0|ubuntu-0) 380 | method=apt 381 | pkgs=$(mkl_meta_get $name deb) 382 | cmd="apt install -y $pkgs" 383 | ;; 384 | 385 | centos-0|rhel-0|redhat-0|fedora-0) 386 | method=yum 387 | pkgs=$(mkl_meta_get $name rpm) 388 | cmd="yum install -y $pkgs" 389 | ;; 390 | 391 | alpine-0) 392 | method=apk 393 | pkgs=$(mkl_meta_get $name apk) 394 | cmd="apk add $pkgs" 395 | ;; 396 | 397 | osx-*) 398 | method=brew 399 | pkgs=$(mkl_meta_get $name brew) 400 | cmd="brew install $pkgs" 401 | ;; 402 | 403 | *) 404 | mkl_dbg "$name: No native installer set for $name on $MKL_DISTRO (euid $EUID)" 405 | return 1 406 | ;; 407 | esac 408 | 409 | if [[ -z $pkgs ]]; then 410 | mkl_dbg "$name: No packages to install ($method)" 411 | return 1 412 | fi 413 | 414 | mkl_check_begin --verb "installing dependencies ($cmd)" $iname "" no-cache "$name" 415 | $cmd >>$MKL_OUTDBG 2>&1 416 | retcode=$? 417 | 418 | if [[ $retcode -eq 0 ]]; then 419 | mkl_dbg "Native install of $name (using $method, $cmd) succeeded" 420 | mkl_check_done "$iname" "" cont "using $method" 421 | mkl_meta_set $name installed_with "$method" 422 | elif [[ $method != "none" ]]; then 423 | mkl_dbg "Native install of $name (using $method, $cmd) failed: retcode $retcode" 424 | mkl_check_failed "$iname" "" cont "using $method" 425 | fi 426 | 427 | return $retcode 428 | } 429 | 430 | 431 | # Returns 0 (yes) if this dependency has a source builder, else 1 (no) 432 | function mkl_dep_has_builder { 433 | local name=$1 434 | local func="${name}_install_source" 435 | mkl_func_exists $func 436 | } 437 | 438 | 439 | # Returns 0 (yes) if this dependency has a package installer, else 1 (no) 440 | function mkl_dep_has_installer { 441 | local name=$1 442 | if mkl_dep_has_builder "$name" || \ 443 | [[ -n $(mkl_meta_get $name deb) ]] || \ 444 | [[ -n $(mkl_meta_get $name rpm) ]] || \ 445 | [[ -n $(mkl_meta_get $name brew) ]] || \ 446 | [[ -n $(mkl_meta_get $name apk) ]]; then 447 | return 0 448 | else 449 | return 1 450 | fi 451 | } 452 | 453 | 454 | # Install an external dependency from source. 455 | # 456 | # The resulting libraries must be installed in $ddir/usr/lib (or lib64), 457 | # and include files in $ddir/usr/include. 458 | # 459 | # Any dependency installed from source will be linked statically 460 | # regardless of --enable-static, if the build produced static libraries. 461 | 462 | # 463 | # Param 1: config name 464 | function mkl_dep_install_source { 465 | local name=$1 466 | local iname="${name}_INSTALL_SRC" 467 | local retcode= 468 | 469 | local func="${name}_install_source" 470 | 471 | if ! mkl_dep_has_builder $name ; then 472 | mkl_dbg "No source builder for $name ($func) available" 473 | return 1 474 | fi 475 | 476 | mkl_check_begin --verb "building dependency" $iname "" no-cache "$name" 477 | 478 | # Create install directory / DESTDIR 479 | local ddir=$(mkl_dep_destdir $name) 480 | [[ -d $ddir ]] || mkdir -p "$ddir" 481 | 482 | # Create and go to source directory 483 | local sdir=$(mkl_dep_srcdir $name) 484 | [[ -d $sdir ]] || mkdir -p "$sdir" 485 | mkl_pushd "$sdir" 486 | 487 | local ilog="${sdir}/_mkl_install.log" 488 | 489 | # Build and install 490 | mkl_dbg "Building $name from source in $sdir (func $func)" 491 | 492 | $func $name "$ddir" >$ilog 2>&1 493 | retcode=$? 494 | 495 | mkl_popd # $sdir 496 | 497 | if [[ $retcode -eq 0 ]]; then 498 | mkl_dbg "Source install of $name succeeded" 499 | mkl_check_done "$iname" "" cont "ok" "from source" 500 | mkl_meta_set $name installed_with "source" 501 | else 502 | mkl_dbg "Source install of $name failed" 503 | mkl_check_failed "$iname" "" disable "source installer failed (see $ilog)" 504 | mkl_err "$name source build failed, see $ilog for details. Last 50 lines:" 505 | tail -50 "$ilog" 506 | fi 507 | 508 | return $retcode 509 | } 510 | 511 | 512 | # Tries to resolve/find full paths to static libraries for a module, 513 | # using the provided scan dir path. 514 | # Any found libraries are set as STATIC_LIB_.. defines. 515 | # 516 | # Param 1: config name 517 | # Param 2: scandir 518 | # 519 | # Returns 0 if libraries were found, else 1. 520 | function mkl_resolve_static_libs { 521 | local name="$1" 522 | local scandir="$2" 523 | local stlibfnames=$(mkl_lib_static_fnames $name) 524 | local stlibvar="STATIC_LIB_${name}" 525 | 526 | if [[ -z $stlibfnames || -n "${!stlibvar}" ]]; then 527 | mkl_dbg "$name: not resolving static libraries (stlibfnames=$stlibfnames, $stlibvar=${!stlibvar})" 528 | mkl_allvar_set "$name" "WITH_STATIC_LIB_$name" y 529 | return 1 530 | fi 531 | 532 | local fname= 533 | local stlibs="" 534 | mkl_dbg "$name: resolving static libraries from $stlibfnames in $scandir" 535 | for fname in $stlibfnames ; do 536 | local stlib=$(find "${scandir}" -name "$fname" 2>/dev/null | head -1) 537 | if [[ -n $stlib ]]; then 538 | stlibs="${stlibs} $stlib" 539 | fi 540 | done 541 | 542 | # Trim leading whitespaces 543 | stlibs=${stlibs# } 544 | 545 | if [[ -n $stlibs ]]; then 546 | mkl_dbg "$name: $stlibvar: found static libs: $stlibs" 547 | mkl_var_set $stlibvar "$stlibs" "cache" 548 | mkl_allvar_set "$name" "WITH_STATIC_LIB_$name" y 549 | return 0 550 | else 551 | mkl_dbg "$name: did not find any static libraries for $stlibfnames in ${scandir}" 552 | return 1 553 | fi 554 | } 555 | 556 | 557 | # Install an external dependecy 558 | # 559 | # Param 1: config name (e.g zstd) 560 | function mkl_dep_install { 561 | local name=$1 562 | local retcode= 563 | 564 | local ddir=$(mkl_dep_destdir $name) 565 | 566 | if [[ $MKL_SOURCE_DEPS_ONLY != y ]] || ! mkl_dep_has_builder $name ; then 567 | # 568 | # Try native package manager first, or if no source builder 569 | # is available for this dependency. 570 | # 571 | mkl_dep_install_pkg $name 572 | retcode=$? 573 | 574 | if [[ $retcode -eq 0 ]]; then 575 | return $retcode 576 | fi 577 | fi 578 | 579 | # 580 | # Try source installer. 581 | # 582 | mkl_dep_install_source $name 583 | retcode=$? 584 | 585 | if [[ $retcode -ne 0 ]]; then 586 | if [[ $MKL_SOURCE_DEPS_ONLY == y ]]; then 587 | # Require dependencies, regardless of original action, 588 | # if --source-deps-only is specified, to ensure 589 | # that we do indeed link with the desired library. 590 | mkl_fail "$name" "" fail "Failed to install dependency $name" 591 | fi 592 | return $retcode 593 | fi 594 | 595 | local ddir=$(mkl_dep_destdir $name) 596 | 597 | # Find the static library(s), if any. 598 | if ! mkl_resolve_static_libs "$name" "${ddir}/usr"; then 599 | # No static libraries found, set up dynamic linker path 600 | mkl_mkvar_prepend LDFLAGS LDFLAGS "-L${ddir}/usr/lib64 -L${ddir}/usr/lib" 601 | fi 602 | 603 | # Add the deps destdir to various build flags so that tools can pick 604 | # up the artifacts (.pc files, includes, libs, etc) they need. 605 | if [[ $MKL_DESTDIR_ADDED == n ]]; then 606 | # Add environment variables so that later built dependencies 607 | # can find this one. 608 | mkl_env_prepend LDFLAGS "-L${ddir}/usr/lib64 -L${ddir}/usr/lib" 609 | mkl_env_prepend CPPFLAGS "-I${ddir}/usr/include" 610 | mkl_env_prepend PKG_CONFIG_PATH "${ddir}/usr/lib/pkgconfig" ":" 611 | # And tell pkg-config to get static linker flags. 612 | mkl_env_set PKG_CONFIG "${PKG_CONFIG} --static" 613 | MKL_DESTDIR_ADDED=y 614 | fi 615 | 616 | # Append the package's install path to compiler and linker flags. 617 | mkl_dbg "$name: Adding install-deps paths ($ddir) to compiler and linker flags" 618 | mkl_mkvar_prepend CPPFLAGS CPPFLAGS "-I${ddir}/usr/include" 619 | 620 | return $retcode 621 | } 622 | 623 | 624 | 625 | ########################################################################### 626 | # 627 | # 628 | # Check failure functionality 629 | # 630 | # 631 | ########################################################################### 632 | 633 | 634 | # Summarize all fatal failures and then exits. 635 | function mkl_fail_summary { 636 | echo " 637 | 638 | " 639 | 640 | local pkg_cmd="" 641 | local install_pkgs="" 642 | mkl_err "###########################################################" 643 | mkl_err "### Configure failed ###" 644 | mkl_err "###########################################################" 645 | mkl_err "### Accumulated failures: ###" 646 | mkl_err "###########################################################" 647 | local n 648 | for n in $MKL_FAILS ; do 649 | local conf=$(mkl_var_get MKL_FAIL__${n}__conf) 650 | mkl_err " $conf ($(mkl_var_get MKL_FAIL__${n}__define)) $(mkl_meta_get $conf name)" 651 | if mkl_meta_exists $conf desc; then 652 | mkl_err0 " desc: $MKL_YELLOW$(mkl_meta_get $conf desc)$MKL_CLR_RESET" 653 | fi 654 | mkl_err0 " module: $(mkl_var_get MKL_FAIL__${n}__module)" 655 | mkl_err0 " action: $(mkl_var_get MKL_FAIL__${n}__action)" 656 | mkl_err0 " reason: 657 | $(mkl_var_get MKL_FAIL__${n}__reason) 658 | " 659 | # Dig up some metadata to assist the user 660 | case $MKL_DISTRO in 661 | debian|ubuntu) 662 | local debs=$(mkl_meta_get $conf "deb") 663 | pkg_cmd="sudo apt install -y" 664 | if [[ ${#debs} > 0 ]]; then 665 | install_pkgs="$install_pkgs $debs" 666 | fi 667 | ;; 668 | centos|rhel|redhat|fedora) 669 | local rpms=$(mkl_meta_get $conf "rpm") 670 | pkg_cmd="sudo yum install -y" 671 | if [[ ${#rpms} > 0 ]]; then 672 | install_pkgs="$install_pkgs $rpms" 673 | fi 674 | ;; 675 | alpine) 676 | local apks=$(mkl_meta_get $conf "apk") 677 | pkg_cmd="apk add " 678 | if [[ ${#apks} > 0 ]]; then 679 | install_pkgs="$install_pkgs $apks" 680 | fi 681 | ;; 682 | osx) 683 | local pkgs=$(mkl_meta_get $conf "brew") 684 | pkg_cmd="brew install" 685 | if [[ ${#pkgs} > 0 ]]; then 686 | install_pkgs="$install_pkgs $pkgs" 687 | fi 688 | ;; 689 | esac 690 | done 691 | 692 | if [[ ! -z $install_pkgs ]]; then 693 | mkl_err "###########################################################" 694 | mkl_err "### Installing the following packages might help: ###" 695 | mkl_err "###########################################################" 696 | mkl_err0 "$pkg_cmd $install_pkgs" 697 | mkl_err0 "" 698 | fi 699 | exit 1 700 | } 701 | 702 | 703 | # Checks if there were failures. 704 | # Returns 0 if there were no failures, else calls failure summary and exits. 705 | function mkl_check_fails { 706 | if [[ ${#MKL_FAILS} = 0 ]]; then 707 | return 0 708 | fi 709 | mkl_fail_summary 710 | } 711 | 712 | # A check has failed but we want to carry on (and we should!). 713 | # We fail it all later. 714 | # Arguments: 715 | # config name 716 | # define name 717 | # action 718 | # reason 719 | function mkl_fail { 720 | local n="$(mkl_env_esc "$1")" 721 | mkl_var_set "MKL_FAIL__${n}__conf" "$1" 722 | mkl_var_set "MKL_FAIL__${n}__module" $MKL_MODULE 723 | mkl_var_set "MKL_FAIL__${n}__define" $2 724 | mkl_var_set "MKL_FAIL__${n}__action" "$3" 725 | if [[ -z $(mkl_var_get "MKL_FAIL__${n}__reason") ]]; then 726 | mkl_var_set "MKL_FAIL__${n}__reason" "$4" 727 | else 728 | mkl_var_append "MKL_FAIL__${n}__reason" " 729 | And also: 730 | $4" 731 | fi 732 | mkl_in_list "$MKL_FAILS" "$n" || mkl_var_append MKL_FAILS "$n" 733 | } 734 | 735 | 736 | # A check failed, handle it 737 | # Arguments: 738 | # config name 739 | # define name 740 | # action (fail|disable|ignore|cont) 741 | # reason 742 | function mkl_check_failed { 743 | # Override action based on require directives, unless the action is 744 | # set to cont (for fallthrough to sub-sequent tests). 745 | local action="$3" 746 | if [[ $3 != "cont" ]]; then 747 | action=$(mkl_meta_get "MOD__$MKL_MODULE" "override_action" $3) 748 | fi 749 | 750 | # --fail-fatal option 751 | [[ $MKL_FAILFATAL ]] && action="fail" 752 | 753 | mkl_check_done "$1" "$2" "$action" "failed" 754 | mkl_dbg "Check $1 ($2, action $action (originally $3)) failed: $4" 755 | 756 | 757 | case $action in 758 | fail) 759 | # Check failed fatally, fail everything eventually 760 | mkl_fail "$1" "$2" "$3" "$4" 761 | return 1 762 | ;; 763 | 764 | disable) 765 | # Check failed, disable 766 | [[ ! -z $2 ]] && mkl_mkvar_set "$1" "$2" "n" 767 | return 1 768 | ;; 769 | ignore) 770 | # Check failed but we ignore the results and set it anyway. 771 | [[ ! -z $2 ]] && mkl_define_set "$1" "$2" "1" 772 | [[ ! -z $2 ]] && mkl_mkvar_set "$1" "$2" "y" 773 | return 1 774 | ;; 775 | cont) 776 | # Check failed but we ignore the results and do nothing. 777 | return 0 778 | ;; 779 | esac 780 | } 781 | 782 | 783 | 784 | 785 | ########################################################################### 786 | # 787 | # 788 | # Output generators 789 | # 790 | # 791 | ########################################################################### 792 | 793 | # Generate late variables. 794 | # Late variables are those referenced in command line option defaults 795 | # but then never set by --option. 796 | function mkl_generate_late_vars { 797 | local n 798 | for n in $MKL_LATE_VARS ; do 799 | local func=${n%:*} 800 | local safeopt=${func#opt_} 801 | local val=${n#*:} 802 | if mkl_in_list "$MKL_OPTS_SET" "$safeopt" ; then 803 | # Skip options set explicitly with --option 804 | continue 805 | fi 806 | # Expand variable references "\$foo" by calling eval 807 | # and pass it opt_... function. 808 | $func "$(eval echo $val)" 809 | done 810 | } 811 | 812 | # Generate output files. 813 | # Must be called following a succesful configure run. 814 | function mkl_generate { 815 | 816 | # Generate MKL_STATIC_LIBS and MKL_DYNAMIC_LIBS from LIBS 817 | local arg= 818 | for arg in $LIBS ; do 819 | if [[ $arg == -l* ]]; then 820 | mkl_mkvar_append "" MKL_DYNAMIC_LIBS $arg 821 | elif [[ $arg == *.a ]]; then 822 | mkl_mkvar_append "" MKL_STATIC_LIBS $arg 823 | else 824 | mkl_dbg "Ignoring arg $arg from LIBS while building STATIC and DYNAMIC lists" 825 | fi 826 | done 827 | 828 | local mf= 829 | for mf in $MKL_GENERATORS ; do 830 | MKL_MODULE=${mf%:*} 831 | local func=${mf#*:} 832 | $func || exit 1 833 | done 834 | 835 | # Generate a built-in options define based on WITH_..=y 836 | local with_y= 837 | for n in $MKL_MKVARS ; do 838 | if [[ $n == WITH_* ]] && [[ $n != WITH_STATIC_LIB_* ]] && [[ ${!n} == y ]]; then 839 | with_y="$with_y ${n#WITH_}" 840 | fi 841 | done 842 | with_y="${with_y# }" 843 | 844 | mkl_allvar_set "BUILT_WITH" "BUILT_WITH" "$with_y" 845 | 846 | mkl_write_mk "# Automatically generated by $0 $*" 847 | mkl_write_mk "# Config variables" 848 | mkl_write_mk "#" 849 | mkl_write_mk "# Generated by:" 850 | mkl_write_mk "# $MKL_CONFIGURE_ARGS" 851 | mkl_write_mk "" 852 | 853 | # This variable is used by Makefile.base to avoid multiple inclusions. 854 | mkl_write_mk "MKL_MAKEFILE_CONFIG=y" 855 | 856 | # Export colors to Makefile.config 857 | mkl_write_mk "MKL_RED=\t${MKL_RED}" 858 | mkl_write_mk "MKL_GREEN=\t${MKL_GREEN}" 859 | mkl_write_mk "MKL_YELLOW=\t${MKL_YELLOW}" 860 | mkl_write_mk "MKL_BLUE=\t${MKL_BLUE}" 861 | mkl_write_mk "MKL_CLR_RESET=\t${MKL_CLR_RESET}" 862 | 863 | local n= 864 | for n in $MKL_MKVARS ; do 865 | # Some special variables should be prefixable by the caller, so 866 | # define them in the makefile as appends. 867 | local op="=" 868 | case $n in 869 | CFLAGS|CPPFLAGS|CXXFLAGS|LDFLAGS|LIBS) 870 | op="+=" 871 | ;; 872 | esac 873 | mkl_write_mk "$n$op\t${!n}" 874 | done 875 | mkl_write_mk "# End of config variables" 876 | 877 | MKL_OUTMK_FINAL=Makefile.config 878 | mv $MKL_OUTMK $MKL_OUTMK_FINAL 879 | 880 | echo "Generated $MKL_OUTMK_FINAL" 881 | 882 | # Generate config.h 883 | mkl_write_h "// Automatically generated by $0 $*" 884 | mkl_write_h "#ifndef _CONFIG_H_" 885 | mkl_write_h "#define _CONFIG_H_" 886 | for n in $MKL_DEFINES ; do 887 | mkl_write_h "${!n}" 888 | done 889 | mkl_write_h "#endif /* _CONFIG_H_ */" 890 | 891 | MKL_OUTH_FINAL=config.h 892 | mv $MKL_OUTH $MKL_OUTH_FINAL 893 | 894 | echo "Generated $MKL_OUTH_FINAL" 895 | } 896 | 897 | # Remove file noisily, if it exists 898 | function mkl_rm { 899 | if [[ -f $fname ]]; then 900 | echo "Removing $fname" 901 | rm -f "$fname" 902 | fi 903 | } 904 | 905 | # Remove files generated by configure 906 | function mkl_clean { 907 | for fname in Makefile.config config.h config.cache config.log ; do 908 | mkl_rm "$fname" 909 | done 910 | 911 | local mf= 912 | for mf in $MKL_CLEANERS ; do 913 | MKL_MODULE=${mf%:*} 914 | local func=${mf#*:} 915 | $func || exit 1 916 | done 917 | 918 | } 919 | 920 | 921 | # Print summary of succesful configure run 922 | function mkl_summary { 923 | 924 | echo " 925 | Configuration summary:" 926 | local n= 927 | for n in $MKL_MKVARS ; do 928 | # Skip the boring booleans 929 | if [[ $n == ENABLE_* || $n == WITH_* || $n == WITHOUT_* || $n == HAVE_* || $n == def_* ]]; then 930 | continue 931 | fi 932 | printf " %-24s %s\n" "$n" "${!n}" 933 | done 934 | } 935 | 936 | 937 | 938 | # Write to mk file 939 | # Argument: 940 | # string .. 941 | function mkl_write_mk { 942 | echo -e "$*" >> $MKL_OUTMK 943 | } 944 | 945 | # Write to header file 946 | # Argument: 947 | # string .. 948 | function mkl_write_h { 949 | echo -e "$*" >> $MKL_OUTH 950 | } 951 | 952 | 953 | 954 | ########################################################################### 955 | # 956 | # 957 | # Logging and debugging 958 | # 959 | # 960 | ########################################################################### 961 | 962 | # Debug print 963 | # Only visible on terminal if MKL_DEBUG is set. 964 | # Always written to config.log 965 | # Argument: 966 | # string .. 967 | function mkl_dbg { 968 | if [[ ! -z $MKL_DEBUG ]]; then 969 | echo -e "${MKL_BLUE}DBG:$$: $*${MKL_CLR_RESET}" 1>&2 970 | fi 971 | echo "DBG $$: $*" >> $MKL_OUTDBG 972 | } 973 | 974 | # Error print (with color) 975 | # Always printed to terminal and config.log 976 | # Argument: 977 | # string .. 978 | function mkl_err { 979 | echo -e "${MKL_RED}$*${MKL_CLR_RESET}" 1>&2 980 | echo "$*" >> $MKL_OUTDBG 981 | } 982 | 983 | # Same as mkl_err but without coloring 984 | # Argument: 985 | # string .. 986 | function mkl_err0 { 987 | echo -e "$*" 1>&2 988 | echo "$*" >> $MKL_OUTDBG 989 | } 990 | 991 | # Standard print 992 | # Always printed to terminal and config.log 993 | # Argument: 994 | # string .. 995 | function mkl_info { 996 | echo -e "$*" 1>&2 997 | echo -e "$*" >> $MKL_OUTDBG 998 | } 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | ########################################################################### 1007 | # 1008 | # 1009 | # Misc helpers 1010 | # 1011 | # 1012 | ########################################################################### 1013 | 1014 | # Returns the absolute path (but not necesarily canonical) of the first argument 1015 | function mkl_abspath { 1016 | echo $1 | sed -e "s|^\([^/]\)|$PWD/\1|" 1017 | } 1018 | 1019 | # Returns true (0) if function $1 exists, else false (1) 1020 | function mkl_func_exists { 1021 | declare -f "$1" > /dev/null 1022 | return $? 1023 | } 1024 | 1025 | # Rename function. 1026 | # Returns 0 on success or 1 if old function (origname) was not defined. 1027 | # Arguments: 1028 | # origname 1029 | # newname 1030 | function mkl_func_rename { 1031 | if ! mkl_func_exists $1 ; then 1032 | return 1 1033 | fi 1034 | local orig=$(declare -f $1) 1035 | local new="$2${orig#$1}" 1036 | eval "$new" 1037 | unset -f "$1" 1038 | return 0 1039 | } 1040 | 1041 | 1042 | # Push module function for later call by mklove. 1043 | # The function is renamed to an internal name. 1044 | # Arguments: 1045 | # list variable name 1046 | # module name 1047 | # function name 1048 | function mkl_func_push { 1049 | local newfunc="__mkl__f_${2}_$(( MKL_IDNEXT++ ))" 1050 | if mkl_func_rename "$3" "$newfunc" ; then 1051 | mkl_var_append "$1" "$2:$newfunc" 1052 | fi 1053 | } 1054 | 1055 | 1056 | 1057 | # Returns value, or the default string if value is empty. 1058 | # Arguments: 1059 | # value 1060 | # default 1061 | function mkl_def { 1062 | if [[ ! -z $1 ]]; then 1063 | echo $1 1064 | else 1065 | echo $2 1066 | fi 1067 | } 1068 | 1069 | 1070 | # Render a string (e.g., evaluate its $varrefs) 1071 | # Arguments: 1072 | # string 1073 | function mkl_render { 1074 | if [[ $* == *\$* ]]; then 1075 | eval "echo $*" 1076 | else 1077 | echo "$*" 1078 | fi 1079 | } 1080 | 1081 | # Escape a string so that it becomes suitable for being an env variable. 1082 | # This is a destructive operation and the original string cannot be restored. 1083 | function mkl_env_esc { 1084 | echo $* | LC_ALL=C sed -e 's/[^a-zA-Z0-9_]/_/g' 1085 | } 1086 | 1087 | # Convert arguments to upper case 1088 | function mkl_upper { 1089 | echo "$*" | tr '[:lower:]' '[:upper:]' 1090 | } 1091 | 1092 | # Convert arguments to lower case 1093 | function mkl_lower { 1094 | echo "$*" | tr '[:upper:]' '[:lower:]' 1095 | } 1096 | 1097 | 1098 | # Checks if element is in list 1099 | # Arguments: 1100 | # list 1101 | # element 1102 | function mkl_in_list { 1103 | local n 1104 | for n in $1 ; do 1105 | [[ $n == $2 ]] && return 0 1106 | done 1107 | return 1 1108 | } 1109 | 1110 | 1111 | # Silent versions of pushd and popd 1112 | function mkl_pushd { 1113 | pushd "$1" >/dev/null 1114 | } 1115 | 1116 | function mkl_popd { 1117 | popd >/dev/null 1118 | } 1119 | 1120 | 1121 | ########################################################################### 1122 | # 1123 | # 1124 | # Cache functionality 1125 | # 1126 | # 1127 | ########################################################################### 1128 | 1129 | 1130 | # Write cache file 1131 | function mkl_cache_write { 1132 | [[ ! -z "$MKL_NOCACHE" ]] && return 0 1133 | echo "# mklove configure cache file generated at $(date)" > config.cache 1134 | for n in $MKL_CACHEVARS ; do 1135 | echo "$n=${!n}" >> config.cache 1136 | done 1137 | echo "Generated config.cache" 1138 | } 1139 | 1140 | 1141 | # Read cache file 1142 | function mkl_cache_read { 1143 | [[ ! -z "$MKL_NOCACHE" ]] && return 0 1144 | [ -f config.cache ] || return 1 1145 | 1146 | echo "using cache file config.cache" 1147 | 1148 | local ORIG_IFS=$IFS 1149 | IFS="$IFS=" 1150 | while read -r n v ; do 1151 | [[ -z $n || $n = \#* || -z $v ]] && continue 1152 | # Don't let cache overwrite variables 1153 | [[ -n ${n+r} ]] || mkl_var_set $n $v cache 1154 | done < config.cache 1155 | IFS=$ORIG_IFS 1156 | } 1157 | 1158 | 1159 | ########################################################################### 1160 | # 1161 | # 1162 | # Config name meta data 1163 | # 1164 | # 1165 | ########################################################################### 1166 | 1167 | # Set metadata for config name 1168 | # This metadata is used by mkl in various situations 1169 | # Arguments: 1170 | # config name 1171 | # metadata key 1172 | # metadata value (appended) 1173 | function mkl_meta_set { 1174 | local metaname="mkl__$1__$2" 1175 | eval "$metaname=\"\$$metaname $3\"" 1176 | } 1177 | 1178 | # Returns metadata for config name 1179 | # Arguments: 1180 | # config name 1181 | # metadata key 1182 | # default (optional) 1183 | function mkl_meta_get { 1184 | local metaname="mkl__$1__$2" 1185 | if [[ ! -z ${!metaname} ]]; then 1186 | echo ${!metaname} 1187 | else 1188 | echo "$3" 1189 | fi 1190 | } 1191 | 1192 | # Checks if metadata exists 1193 | # Arguments: 1194 | # config name 1195 | # metadata key 1196 | function mkl_meta_exists { 1197 | local metaname="mkl__$1__$2" 1198 | if [[ ! -z ${!metaname} ]]; then 1199 | return 0 1200 | else 1201 | return 1 1202 | fi 1203 | } 1204 | 1205 | 1206 | 1207 | 1208 | 1209 | ########################################################################### 1210 | # 1211 | # 1212 | # Check framework 1213 | # 1214 | # 1215 | ########################################################################### 1216 | 1217 | 1218 | # Print that a check is beginning to run 1219 | # Returns 0 if a cached result was used (do not continue with your tests), 1220 | # else 1. 1221 | # 1222 | # If the check should not be cachable then specify argument 3 as "no-cache", 1223 | # this is useful when a check not only checks but actually sets config 1224 | # variables itself (which is not recommended, but desired sometimes). 1225 | # 1226 | # Arguments: 1227 | # [ --verb "verb.." ] (replace "checking for") 1228 | # config name 1229 | # define name 1230 | # action (fail,cont,disable or no-cache) 1231 | # [ display name ] 1232 | function mkl_check_begin { 1233 | local verb="checking for" 1234 | if [[ $1 == "--verb" ]]; then 1235 | verb="$2" 1236 | shift 1237 | shift 1238 | fi 1239 | 1240 | local name=$(mkl_meta_get $1 name "$4") 1241 | [[ -z $name ]] && name="$1" 1242 | 1243 | echo -n "$verb $name..." 1244 | if [[ $3 != "no-cache" ]]; then 1245 | local status=$(mkl_var_get "MKL_STATUS_$1") 1246 | # Check cache (from previous run or this one). 1247 | # Only used cached value if the cached check succeeded: 1248 | # it is more likely that a failed check has been fixed than the other 1249 | # way around. 1250 | if [[ ! -z $status && ( $status = "ok" ) ]]; then 1251 | mkl_check_done "$1" "$2" "$3" $status "cached" 1252 | return 0 1253 | fi 1254 | fi 1255 | return 1 1256 | } 1257 | 1258 | 1259 | # Calls the manual_checks function for the given module. 1260 | # Use this for modules that provide check hooks that require 1261 | # certain call ordering, such as dependent library checks. 1262 | # 1263 | # Param 1: module name 1264 | function mkl_check { 1265 | local modname=$1 1266 | 1267 | local func="${modname}_manual_checks" 1268 | if ! mkl_func_exists "$func" ; then 1269 | mkl_fail "Check function for module $modname not found: missing mkl_require $modname ?" 1270 | return 1 1271 | fi 1272 | 1273 | $func 1274 | return $? 1275 | } 1276 | 1277 | 1278 | # Print that a check is done 1279 | # Arguments: 1280 | # config name 1281 | # define name 1282 | # action 1283 | # status (ok|failed) 1284 | # extra-info (optional) 1285 | function mkl_check_done { 1286 | # Clean up configname to be a safe varname 1287 | local cname=${1//-/_} 1288 | mkl_var_set "MKL_STATUS_$cname" "$4" cache 1289 | 1290 | mkl_dbg "Setting $1 ($cname) status to $4 (action $3)" 1291 | 1292 | local extra="" 1293 | if [[ $4 = "failed" ]]; then 1294 | local clr=$MKL_YELLOW 1295 | extra=" ($3)" 1296 | case "$3" in 1297 | fail) 1298 | clr=$MKL_RED 1299 | ;; 1300 | cont) 1301 | extra="" 1302 | ;; 1303 | esac 1304 | echo -e " $clr$4$MKL_CLR_RESET${extra}" 1305 | else 1306 | [[ ! -z $2 ]] && mkl_define_set "$cname" "$2" "1" 1307 | [[ ! -z $2 ]] && mkl_mkvar_set "$cname" "$2" "y" 1308 | [ ! -z "$5" ] && extra=" ($5)" 1309 | echo -e " $MKL_GREEN$4${MKL_CLR_RESET}$extra" 1310 | fi 1311 | } 1312 | 1313 | 1314 | # Perform configure check by compiling source snippet 1315 | # Arguments: 1316 | # [--sub] (run checker as a sub-check, not doing begin/fail/ok) 1317 | # [--ldflags="..." ] (appended after "compiler arguments" below) 1318 | # config name 1319 | # define name 1320 | # action (fail|disable) 1321 | # compiler (CC|CXX) 1322 | # compiler arguments (optional "", example: "-lzookeeper") 1323 | # source snippet 1324 | function mkl_compile_check { 1325 | 1326 | local sub=0 1327 | if [[ $1 == --sub ]]; then 1328 | sub=1 1329 | shift 1330 | fi 1331 | 1332 | local ldf= 1333 | if [[ $1 == --ldflags=* ]]; then 1334 | ldf=${1#*=} 1335 | shift 1336 | fi 1337 | 1338 | if [[ $sub -eq 0 ]]; then 1339 | mkl_check_begin "$1" "$2" "$3" "$1 (by compile)" && return $? 1340 | fi 1341 | 1342 | local cflags= 1343 | 1344 | if [[ $4 = "CXX" ]]; then 1345 | local ext=cpp 1346 | cflags="$(mkl_mkvar_get CXXFLAGS)" 1347 | else 1348 | local ext=c 1349 | cflags="$(mkl_mkvar_get CFLAGS)" 1350 | fi 1351 | 1352 | local srcfile=$(mktemp _mkltmpXXXXXX) 1353 | mv "$srcfile" "${srcfile}.$ext" 1354 | srcfile="$srcfile.$ext" 1355 | echo "$6" > $srcfile 1356 | echo " 1357 | int main () { return 0; } 1358 | " >> $srcfile 1359 | 1360 | local cmd="${!4} $cflags $(mkl_mkvar_get CPPFLAGS) -Wall -Werror $srcfile -o ${srcfile}.o $ldf $(mkl_mkvar_get LDFLAGS) $5 $(mkl_mkvar_get LIBS)"; 1361 | mkl_dbg "Compile check $1 ($2) (sub=$sub): $cmd" 1362 | 1363 | local output 1364 | output=$($cmd 2>&1) 1365 | 1366 | if [[ $? != 0 ]] ; then 1367 | mkl_dbg "compile check for $1 ($2) failed: $cmd: $output" 1368 | [[ $sub -eq 0 ]] && mkl_check_failed "$1" "$2" "$3" "compile check failed: 1369 | CC: $4 1370 | flags: $5 1371 | $cmd: 1372 | $output 1373 | source: $6" 1374 | local ret=1 1375 | else 1376 | [[ $sub -eq 0 ]] && mkl_check_done "$1" "$2" "$3" "ok" 1377 | local ret=0 1378 | fi 1379 | 1380 | # OSX XCode toolchain creates dSYM directories when -g is set, 1381 | # delete them specifically. 1382 | rm -rf "$srcfile" "${srcfile}.o" "$srcfile*dSYM" 1383 | 1384 | return $ret 1385 | } 1386 | 1387 | 1388 | # Low-level: Try to link with a library. 1389 | # Arguments: 1390 | # linker flags (e.g. "-lpthreads") 1391 | function mkl_link_check0 { 1392 | local libs=$1 1393 | local srcfile=$(mktemp _mktmpXXXXXX) 1394 | echo "#include 1395 | int main () { FILE *fp = stderr; return fp ? 0 : 0; }" > ${srcfile}.c 1396 | 1397 | local cmd="${CC} $(mkl_mkvar_get CFLAGS) $(mkl_mkvar_get LDFLAGS) ${srcfile}.c -o ${srcfile}_out $libs"; 1398 | mkl_dbg "Link check for $1: $cmd" 1399 | 1400 | local output 1401 | output=$($cmd 2>&1) 1402 | local retcode=$? 1403 | 1404 | if [[ $retcode -ne 0 ]] ; then 1405 | mkl_dbg "Link check for $1 failed: $output" 1406 | fi 1407 | 1408 | rm -f $srcfile* 1409 | return $retcode 1410 | } 1411 | 1412 | 1413 | # Try to link with a library. 1414 | # Arguments: 1415 | # config name 1416 | # define name 1417 | # action (fail|disable) 1418 | # linker flags (e.g. "-lpthreads") 1419 | function mkl_link_check { 1420 | mkl_check_begin "$1" "$2" "$3" "$1 (by linking)" && return $? 1421 | 1422 | if mkl_link_check0 "$4" ; then 1423 | mkl_check_done "$1" "$2" "$3" "ok" "$4" 1424 | return 0 1425 | else 1426 | mkl_dbg "link check for $1 ($2) failed: $output" 1427 | mkl_check_failed "$1" "$2" "$3" "compile check failed: 1428 | $output" 1429 | return 1 1430 | fi 1431 | } 1432 | 1433 | 1434 | 1435 | # Tries to figure out if we can use a static library or not. 1436 | # 1437 | # WARNING: This function must not emit any stdout output other than the 1438 | # updated list of libs. Do not use any stdout-printing checker. 1439 | # 1440 | # Arguments: 1441 | # config name (e.g., zstd) 1442 | # compiler flags (optional "", e.g: "-lzstd") 1443 | # Returns/outputs: 1444 | # New list of compiler flags 1445 | function mkl_lib_check_static { 1446 | local configname=$1 1447 | local libs=$2 1448 | local arfile_var=STATIC_LIB_${configname} 1449 | local stfnames=$(mkl_lib_static_fnames $configname) 1450 | 1451 | mkl_dbg "$configname: Check for static library (libs $libs, arfile variable $arfile_var=${!arfile_var}, static filenames $stfnames)" 1452 | 1453 | # If STATIC_LIB_ specifies .a file(s) we use that instead. 1454 | if [[ -n ${!arfile_var} ]]; then 1455 | libs="${!arfile_var}" 1456 | 1457 | elif [[ $WITH_STATIC_LINKING != y ]]; then 1458 | # Static linking not enabled 1459 | echo "" 1460 | return 1461 | 1462 | elif [[ $HAS_LDFLAGS_STATIC == y ]] && [[ -n $stfnames ]]; then 1463 | local libname 1464 | local stlibs= 1465 | for libname in $stfnames; do 1466 | # Convert the static filename to a linker flag: 1467 | # libzstd.a -> -lzstd 1468 | libname=${libname#lib} 1469 | libname="-l${libname%.a}" 1470 | stlibs="${stlibs}${libname} " 1471 | done 1472 | libs="${LDFLAGS_STATIC} $stlibs ${LDFLAGS_DYNAMIC}" 1473 | mkl_dbg "$configname: after replacing libs: $libs" 1474 | 1475 | elif [[ $libs == *-L* ]]; then 1476 | # Try to resolve full static paths using any -Lpaths in $libs 1477 | local lpath 1478 | for lpath in $libs; do 1479 | [[ $lpath == -L* ]] || continue 1480 | 1481 | lpath="${lpath#-L}" 1482 | [[ -d $lpath ]] || continue 1483 | 1484 | if mkl_resolve_static_libs "$configname" "$lpath"; then 1485 | break 1486 | fi 1487 | done 1488 | 1489 | libs="${!arfile_var}" 1490 | mkl_dbg "$configname: after -L resolve, libs is $libs" 1491 | 1492 | else 1493 | mkl_dbg "$configname: Neither $arfile_var=/path/to/libname.a specified nor static linker flags supported: static linking probably won't work" 1494 | libs="" 1495 | fi 1496 | 1497 | if [[ -z $libs ]]; then 1498 | echo "" 1499 | return 1500 | fi 1501 | 1502 | # Attempt to link a small program with these static libraries 1503 | mkl_dbg "$configname: verifying that linking \"$libs\" works" 1504 | if ! mkl_link_check0 "$libs" ; then 1505 | mkl_dbg "$configname: Could not use static libray flags: $libs" 1506 | echo "" 1507 | return 1508 | fi 1509 | 1510 | mkl_allvar_set "$configname" "${configname}_STATIC" "y" 1511 | 1512 | echo $libs 1513 | } 1514 | 1515 | 1516 | # Checks that the specified lib is available through a number of methods. 1517 | # compiler flags are automatically appended to "LIBS" mkvar on success. 1518 | # 1519 | # If STATIC_LIB_ is set to the path of an .a file 1520 | # it will be used instead of -l. 1521 | # 1522 | # _STATIC will be automatically defined (for both Makefile.config 1523 | # and config.h) if the library is to be linked statically, or was installed 1524 | # with a source dependency installer. 1525 | # 1526 | # Arguments: 1527 | # [--override-action=] (internal use, overrides action argument) 1528 | # [--no-static] (do not attempt to link the library statically) 1529 | # [--libname=] (library name if different from config name, such as 1530 | # when the libname includes a dash) 1531 | # config name (library name (for pkg-config)) 1532 | # define name 1533 | # action (fail|disable|cont) 1534 | # compiler (CC|CXX) 1535 | # compiler flags (optional "", e.g: "-lyajl") 1536 | # source snippet 1537 | function mkl_lib_check0 { 1538 | 1539 | local override_action= 1540 | local nostaticopt= 1541 | local libnameopt= 1542 | local libname= 1543 | 1544 | while [[ $1 == --* ]]; do 1545 | if [[ $1 == --override-action=* ]]; then 1546 | override_action=${1#*=} 1547 | elif [[ $1 == --no-static ]]; then 1548 | nostaticopt=$1 1549 | elif [[ $1 == --libname* ]]; then 1550 | libnameopt=$1 1551 | libname="${libnameopt#*=}" 1552 | else 1553 | mkl_err "mkl_lib_check: invalid option $1" 1554 | exit 1 1555 | fi 1556 | shift 1557 | done 1558 | 1559 | if [[ -z $libname ]]; then 1560 | libname=$1 1561 | fi 1562 | 1563 | local action=$3 1564 | if [[ -n $override_action ]]; then 1565 | action=$override_action 1566 | fi 1567 | 1568 | # pkg-config result (0=ok) 1569 | local pkg_conf_failed=1 1570 | if [[ $WITH_PKGCONFIG == "y" ]]; then 1571 | # Let pkg-config populate CFLAGS, et.al. 1572 | # Return on success. 1573 | mkl_pkg_config_check $nostaticopt $libnameopt "$1" "$2" cont "$4" "$6" && return $? 1574 | fi 1575 | 1576 | local libs="$5" 1577 | local is_static=0 1578 | 1579 | if [[ -z $nostaticopt ]]; then 1580 | local stlibs=$(mkl_lib_check_static $1 "$libs") 1581 | if [[ -n $stlibs ]]; then 1582 | libs=$stlibs 1583 | is_static=1 1584 | fi 1585 | fi 1586 | 1587 | if ! mkl_compile_check "$1" "$2" "$action" "$4" "$libs" "$6"; then 1588 | return 1 1589 | fi 1590 | 1591 | if [[ -n $libs ]]; then 1592 | # Add libraries in reverse order to make sure inter-dependencies 1593 | # are resolved in the correct order. 1594 | # E.g., check for crypto and then ssl should result in -lssl -lcrypto 1595 | mkl_dbg "$1: from lib_check: LIBS: prepend $libs" 1596 | mkl_mkvar_prepend "$1" LIBS "$libs" 1597 | if [[ $is_static == 0 ]]; then 1598 | # Static libraries are automatically bundled with 1599 | # librdkafka-static.a so there is no need to add them as an 1600 | # external linkage dependency. 1601 | mkl_mkvar_prepend "$1" MKL_PKGCONFIG_LIBS_PRIVATE "$libs" 1602 | fi 1603 | fi 1604 | 1605 | return 0 1606 | } 1607 | 1608 | 1609 | # Wrapper for mkl_lib_check0 which attempts dependency installation 1610 | # if --install-deps is specified. 1611 | # 1612 | # See mkl_lib_check0 for arguments and details. 1613 | function mkl_lib_check { 1614 | 1615 | local arg= 1616 | local name= 1617 | 1618 | # Find config name parameter (first non-option (--...)) 1619 | for arg in $* ; do 1620 | if [[ $arg == --* ]]; then 1621 | continue 1622 | fi 1623 | name=$arg 1624 | break 1625 | done 1626 | 1627 | if [[ $MKL_INSTALL_DEPS != y ]] || ! mkl_dep_has_installer "$name" ; then 1628 | mkl_lib_check0 "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" 1629 | return $? 1630 | fi 1631 | 1632 | 1633 | # Automatic dependency installation mode: 1634 | # First pass is lib check with cont, 1635 | # if it fails, attempt dependency installation, 1636 | # and then make second with caller's fail-action. 1637 | 1638 | local retcode= 1639 | 1640 | # With --source-deps-only we want to make sure the dependency 1641 | # being used is in-fact from the dependency builder (if supported), 1642 | # rather than a system installed alternative, so skip the pre-check and 1643 | # go directly to dependency installation/build below. 1644 | if [[ $MKL_SOURCE_DEPS_ONLY != y ]] || ! mkl_dep_has_builder $name ; then 1645 | mkl_lib_check0 --override-action=cont "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" 1646 | retcode=$? 1647 | if [[ $retcode -eq 0 ]]; then 1648 | # Successful on first pass 1649 | return $retcode 1650 | fi 1651 | else 1652 | mkl_dbg "$name: skipping dependency pre-check in favour of --source-deps-only" 1653 | fi 1654 | 1655 | # Install dependency 1656 | if ! mkl_dep_install "$name" ; then 1657 | return 1 1658 | fi 1659 | 1660 | # Second pass: check again, this time fail hard 1661 | mkl_lib_check0 --override-action=fail "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" 1662 | return $? 1663 | } 1664 | 1665 | 1666 | 1667 | # Check for library with pkg-config 1668 | # Automatically sets CFLAGS and LIBS from pkg-config information. 1669 | # Arguments: 1670 | # [--no-static] (do not attempt to link the library statically) 1671 | # [--libname=] (library name if different from config name, such as 1672 | # when the libname includes a dash) 1673 | # config name 1674 | # define name 1675 | # action (fail|disable|ignore|cont) 1676 | # compiler (CC|CXX) 1677 | # source snippet 1678 | function mkl_pkg_config_check { 1679 | 1680 | local nostaticopt= 1681 | if [[ $1 == --no-static ]]; then 1682 | nostaticopt=$1 1683 | shift 1684 | fi 1685 | 1686 | local libname=$1 1687 | if [[ $1 == --libname* ]]; then 1688 | libname="${libnameopt#*=}" 1689 | shift 1690 | fi 1691 | 1692 | local cname="${1}_PKGCONFIG" 1693 | mkl_check_begin "$cname" "$2" "no-cache" "$1 (by pkg-config)" && return $? 1694 | 1695 | local cflags= 1696 | local cmd="${PKG_CONFIG} --short-errors --cflags $libname" 1697 | mkl_dbg "pkg-config check $libname for CFLAGS ($2): $cmd" 1698 | 1699 | cflags=$($cmd 2>&1) 1700 | if [[ $? != 0 ]]; then 1701 | mkl_dbg "'$cmd' failed: $cflags" 1702 | # Clear define name ($2): caller may have additional checks 1703 | mkl_check_failed "$cname" "" "$3" "'$cmd' failed: 1704 | $cflags" 1705 | return 1 1706 | fi 1707 | 1708 | if [[ $(mkl_meta_get $1 installed_with) == "source" && \ 1709 | $WITH_STATIC_LINKING == y && \ 1710 | $MKL_SOURCE_DEPS_ONLY == y ]]; then 1711 | # If attempting static linking and we're using source-only 1712 | # dependencies, then there is no need for pkg-config since 1713 | # the source installer will have set the required flags. 1714 | return 1 1715 | fi 1716 | 1717 | local libs= 1718 | cmd="${PKG_CONFIG} --short-errors --libs $libname" 1719 | mkl_dbg "pkg-config check $libname for LIBS ($2): $cmd" 1720 | libs=$($cmd 2>&1) 1721 | if [[ $? != 0 ]]; then 1722 | mkl_dbg "${PKG_CONFIG} --libs $libname failed: $libs" 1723 | # Clear define name ($2): caller may have additional checks 1724 | mkl_check_failed "$cname" "" "$3" "pkg-config --libs failed" 1725 | return 1 1726 | fi 1727 | 1728 | mkl_dbg "$1: from pkg-config: CFLAGS '$CFLAGS', LIBS '$LIBS'" 1729 | 1730 | local snippet="$5" 1731 | if [[ -n $snippet ]]; then 1732 | mkl_dbg "$1: performing compile check using pkg-config info" 1733 | 1734 | if ! mkl_compile_check --sub "$1" "$2" "no-cache" "$4" "$cflags $libs" "$snippet"; then 1735 | mkl_check_failed "$cname" "" "$3" "compile check failed" 1736 | return 1 1737 | fi 1738 | fi 1739 | 1740 | mkl_mkvar_append $1 "MKL_PKGCONFIG_REQUIRES_PRIVATE" "$libname" 1741 | 1742 | mkl_mkvar_append $1 "CFLAGS" "$cflags" 1743 | 1744 | if [[ -z $nostaticopt ]]; then 1745 | local stlibs=$(mkl_lib_check_static $1 "$libs") 1746 | if [[ -n $stlibs ]]; then 1747 | libs=$stlibs 1748 | else 1749 | # if we don't find a static library to bundle into the 1750 | # -static.a, we need to export a pkgconfig dependency 1751 | # so it can be resolved when linking downstream packages 1752 | mkl_mkvar_append $1 "MKL_PKGCONFIG_REQUIRES" "$libname" 1753 | fi 1754 | fi 1755 | 1756 | mkl_dbg "$1: from pkg-config: LIBS: prepend $libs" 1757 | mkl_mkvar_prepend "$1" LIBS "$libs" 1758 | 1759 | mkl_check_done "$1" "$2" "$3" "ok" 1760 | 1761 | return 0 1762 | } 1763 | 1764 | 1765 | # Check that a command runs and exits succesfully. 1766 | # Arguments: 1767 | # config name 1768 | # define name (optional, can be empty) 1769 | # action 1770 | # command 1771 | function mkl_command_check { 1772 | mkl_check_begin "$1" "$2" "$3" "$1 (by command)" && return $? 1773 | 1774 | local out= 1775 | out=$($4 2>&1) 1776 | if [[ $? != 0 ]]; then 1777 | mkl_dbg "$1: $2: $4 failed: $out" 1778 | mkl_check_failed "$1" "$2" "$3" "command '$4' failed: 1779 | $out" 1780 | return 1 1781 | fi 1782 | 1783 | mkl_check_done "$1" "$2" "$3" "ok" 1784 | 1785 | return 0 1786 | } 1787 | 1788 | 1789 | # Check that a program is executable, but will not execute it. 1790 | # Arguments: 1791 | # config name 1792 | # define name (optional, can be empty) 1793 | # action 1794 | # program name (e.g, objdump) 1795 | function mkl_prog_check { 1796 | mkl_check_begin --verb "checking executable" "$1" "$2" "$3" "$1" && return $? 1797 | 1798 | local out= 1799 | out=$(command -v "$4" 2>&1) 1800 | if [[ $? != 0 ]]; then 1801 | mkl_dbg "$1: $2: $4 is not executable: $out" 1802 | mkl_check_failed "$1" "$2" "$3" "$4 is not executable" 1803 | return 1 1804 | fi 1805 | 1806 | mkl_check_done "$1" "$2" "$3" "ok" 1807 | 1808 | return 0 1809 | } 1810 | 1811 | 1812 | 1813 | 1814 | # Checks that the check for the given config name passed. 1815 | # This does not behave like the other checks, if the given config name passed 1816 | # its test then nothing is printed. Else the configure will fail. 1817 | # Arguments: 1818 | # checked config name 1819 | function mkl_config_check { 1820 | local status=$(mkl_var_get "MKL_STATUS_$1") 1821 | [[ $status = "ok" ]] && return 0 1822 | mkl_fail $1 "" "fail" "$MKL_MODULE requires $1" 1823 | return 1 1824 | } 1825 | 1826 | 1827 | # Checks that all provided config names are set. 1828 | # Arguments: 1829 | # config name 1830 | # define name 1831 | # action 1832 | # check_config_name1 1833 | # check_config_name2.. 1834 | function mkl_config_check_all { 1835 | local cname= 1836 | local res="ok" 1837 | echo start this now for $1 1838 | for cname in ${@:4}; do 1839 | local st=$(mkl_var_get "MKL_STATUS_$cname") 1840 | [[ $status = "ok" ]] && continue 1841 | mkl_fail $1 $2 $3 "depends on $cname" 1842 | res="failed" 1843 | done 1844 | 1845 | echo "try res $res" 1846 | mkl_check_done "$1" "$2" "$3" $res 1847 | } 1848 | 1849 | 1850 | # Check environment variable 1851 | # Arguments: 1852 | # config name 1853 | # define name 1854 | # action 1855 | # environment variable 1856 | function mkl_env_check { 1857 | mkl_check_begin "$1" "$2" "$3" "$1 (by env $4)" && return $? 1858 | 1859 | if [[ -z ${!4} ]]; then 1860 | mkl_check_failed "$1" "$2" "$3" "environment variable $4 not set" 1861 | return 1 1862 | fi 1863 | 1864 | mkl_check_done "$1" "$2" "$3" "ok" "${!4}" 1865 | 1866 | return 0 1867 | } 1868 | 1869 | 1870 | # Run all checks 1871 | function mkl_checks_run { 1872 | # Set up common variables 1873 | mkl_allvar_set "" MKL_APP_NAME $(mkl_meta_get description name) 1874 | mkl_allvar_set "" MKL_APP_DESC_ONELINE "$(mkl_meta_get description oneline)" 1875 | 1876 | # Call checks functions in dependency order 1877 | local mf 1878 | for mf in $MKL_CHECKS ; do 1879 | MKL_MODULE=${mf%:*} 1880 | local func=${mf#*:} 1881 | 1882 | if mkl_func_exists $func ; then 1883 | $func 1884 | else 1885 | mkl_err "Check function $func from $MKL_MODULE disappeared ($mf)" 1886 | fi 1887 | unset MKL_MODULE 1888 | done 1889 | } 1890 | 1891 | 1892 | # Check for color support in terminal. 1893 | # If the terminal supports colors, the function will alter 1894 | # MKL_RED 1895 | # MKL_GREEN 1896 | # MKL_YELLOW 1897 | # MKL_BLUE 1898 | # MKL_CLR_RESET 1899 | function mkl_check_terminal_color_support { 1900 | local use_color=false 1901 | local has_tput=false 1902 | 1903 | if [[ -z ${TERM} ]]; then 1904 | # tput and dircolors require $TERM 1905 | mkl_dbg "\$TERM is not set! Cannot check for color support in terminal." 1906 | return 1 1907 | elif hash tput 2>/dev/null; then 1908 | has_tput=true 1909 | [[ $(tput colors 2>/dev/null) -ge 8 ]] && use_color=true 1910 | mkl_dbg "tput reports color support: ${use_color}" 1911 | elif hash dircolors 2>/dev/null; then 1912 | # Enable color support only on colorful terminals. 1913 | # dircolors --print-database uses its own built-in database 1914 | # instead of using /etc/DIR_COLORS. Try to use the external file 1915 | # first to take advantage of user additions. 1916 | local safe_term=${TERM//[^[:alnum:]]/?} 1917 | local match_lhs="" 1918 | [[ -f ~/.dir_colors ]] && match_lhs="${match_lhs}$(<~/.dir_colors)" 1919 | [[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(&1) 1995 | 1996 | if [[ $? -ne 0 ]]; then 1997 | rm -f "$tmpfile" 1998 | mkl_err "Failed to download $modname:" 1999 | mkl_err0 $out 2000 | return 1 2001 | fi 2002 | 2003 | # Move downloaded file into place replacing the old file. 2004 | mv "$tmpfile" "$fname" || return 1 2005 | 2006 | # "Return" filename 2007 | echo "$fname" 2008 | 2009 | return 0 2010 | } 2011 | 2012 | 2013 | # Load module by name or filename 2014 | # Arguments: 2015 | # "require"|"try" 2016 | # filename 2017 | # [ module arguments ] 2018 | function mkl_module_load { 2019 | local try=$1 2020 | shift 2021 | local fname=$1 2022 | shift 2023 | local modname=${fname#*configure.} 2024 | local bypath=1 2025 | 2026 | # Check if already loaded 2027 | if mkl_in_list "$MKL_MODULES" "$modname"; then 2028 | return 0 2029 | fi 2030 | 2031 | if [[ $fname = $modname ]]; then 2032 | # Module specified by name, find the file. 2033 | bypath=0 2034 | for fname in configure.$modname \ 2035 | ${MKLOVE_DIR}/modules/configure.$modname ; do 2036 | [[ -s $fname ]] && break 2037 | done 2038 | fi 2039 | 2040 | # Calling module 2041 | local cmod=$MKL_MODULE 2042 | [[ -z $cmod ]] && cmod="base" 2043 | 2044 | if [[ ! -s $fname ]]; then 2045 | # Attempt to download module, if permitted 2046 | if [[ $MKL_NO_DOWNLOAD != 0 || $bypath == 1 ]]; then 2047 | mkl_err "Module $modname not found at $fname (required by $cmod) and downloads disabled" 2048 | if [[ $try = "require" ]]; then 2049 | mkl_fail "$modname" "none" "fail" \ 2050 | "Module $modname not found (required by $cmod) and downloads disabled" 2051 | fi 2052 | return 1 2053 | fi 2054 | 2055 | fname=$(mkl_module_download "$modname") 2056 | if [[ $? -ne 0 ]]; then 2057 | mkl_err "Module $modname not found (required by $cmod)" 2058 | if [[ $try = "require" ]]; then 2059 | mkl_fail "$modname" "none" "fail" \ 2060 | "Module $modname not found (required by $cmod)" 2061 | return 1 2062 | fi 2063 | fi 2064 | 2065 | # Now downloaded, try loading the module again. 2066 | mkl_module_load $try "$fname" "$@" 2067 | return $? 2068 | fi 2069 | 2070 | # Set current module 2071 | local save_MKL_MODULE=$MKL_MODULE 2072 | MKL_MODULE=$modname 2073 | 2074 | mkl_dbg "Loading module $modname (required by $cmod) from $fname" 2075 | 2076 | # Source module file (positional arguments are available to module) 2077 | source $fname 2078 | 2079 | # Restore current module (might be recursive) 2080 | MKL_MODULE=$save_MKL_MODULE 2081 | 2082 | # Add module to list of modules 2083 | mkl_var_append MKL_MODULES $modname 2084 | 2085 | # Rename module's special functions so we can call them separetely later. 2086 | mkl_func_rename "options" "${modname}_options" 2087 | mkl_func_rename "install_source" "${modname}_install_source" 2088 | mkl_func_rename "manual_checks" "${modname}_manual_checks" 2089 | mkl_func_push MKL_CHECKS "$modname" "checks" 2090 | mkl_func_push MKL_GENERATORS "$modname" "generate" 2091 | mkl_func_push MKL_CLEANERS "$modname" "clean" 2092 | } 2093 | 2094 | 2095 | # Require and load module 2096 | # Must only be called from module file outside any function. 2097 | # Arguments: 2098 | # [ --try ] Dont fail if module doesn't exist 2099 | # module1 2100 | # [ "must" "pass" ] 2101 | # [ module arguments ... ] 2102 | function mkl_require { 2103 | local try="require" 2104 | if [[ $1 = "--try" ]]; then 2105 | local try="try" 2106 | shift 2107 | fi 2108 | 2109 | local mod=$1 2110 | shift 2111 | local override_action= 2112 | 2113 | # Check for cyclic dependencies 2114 | if mkl_in_list "$MKL_LOAD_STACK" "$mod"; then 2115 | mkl_err "Cyclic dependency detected while loading $mod module:" 2116 | local cmod= 2117 | local lmod=$mod 2118 | for cmod in $MKL_LOAD_STACK ; do 2119 | mkl_err " $lmod required by $cmod" 2120 | lmod=$cmod 2121 | done 2122 | mkl_fail base "" fail "Cyclic dependency detected while loading module $mod" 2123 | return 1 2124 | fi 2125 | 2126 | mkl_var_prepend MKL_LOAD_STACK "$mod" 2127 | 2128 | 2129 | if [[ "$1 $2" == "must pass" ]]; then 2130 | shift 2131 | shift 2132 | override_action="fail" 2133 | fi 2134 | 2135 | if [[ ! -z $override_action ]]; then 2136 | mkl_meta_set "MOD__$mod" "override_action" "$override_action" 2137 | fi 2138 | 2139 | 2140 | mkl_module_load $try $mod "$@" 2141 | local ret=$? 2142 | 2143 | mkl_var_shift MKL_LOAD_STACK 2144 | 2145 | return $ret 2146 | } 2147 | 2148 | 2149 | 2150 | ########################################################################### 2151 | # 2152 | # 2153 | # Usage options 2154 | # 2155 | # 2156 | ########################################################################### 2157 | 2158 | 2159 | MKL_USAGE="Usage: ./configure [OPTIONS...] 2160 | 2161 | mklove configure script - mklove, not autoconf 2162 | Copyright (c) 2014-2019 Magnus Edenhill - https://github.com/edenhill/mklove 2163 | " 2164 | 2165 | function mkl_usage { 2166 | echo "$MKL_USAGE" 2167 | local name=$(mkl_meta_get description name) 2168 | 2169 | if [[ ! -z ${name} ]]; then 2170 | echo " $name - $(mkl_meta_get description oneline) 2171 | $(mkl_meta_get description copyright) 2172 | " 2173 | fi 2174 | 2175 | local og 2176 | for og in $MKL_USAGE_GROUPS ; do 2177 | og="MKL_USAGE_GROUP__$og" 2178 | echo "${!og}" 2179 | done 2180 | 2181 | echo "Honoured environment variables: 2182 | CC, CPP, CXX, CFLAGS, CPPFLAGS, CXXFLAGS, LDFLAGS, LIBS, 2183 | LD, NM, OBJDUMP, STRIP, RANLIB, PKG_CONFIG, PKG_CONFIG_PATH, 2184 | STATIC_LIB_=.../libname.a 2185 | 2186 | " 2187 | 2188 | } 2189 | 2190 | 2191 | 2192 | # Add usage option informative text 2193 | # Arguments: 2194 | # text 2195 | function mkl_usage_info { 2196 | MKL_USAGE="$MKL_USAGE 2197 | $1" 2198 | } 2199 | 2200 | 2201 | # Add option to usage output 2202 | # Arguments: 2203 | # option group ("Standard", "Cross-Compilation", etc..) 2204 | # variable name 2205 | # option ("--foo", "--foo=*", "--foo=args_required") 2206 | # help 2207 | # default (optional) 2208 | # assignvalue (optional, default:"y") 2209 | # function block (optional) 2210 | # 2211 | # If option takes the form --foo=* then arguments are optional. 2212 | function mkl_option { 2213 | local optgroup=$1 2214 | local varname=$2 2215 | 2216 | # Fixed width between option name and help in usage output 2217 | local pad=" " 2218 | if [[ ${#3} -lt ${#pad} ]]; then 2219 | pad=${pad:0:$(expr ${#pad} - ${#3})} 2220 | else 2221 | pad="" 2222 | fi 2223 | 2224 | # Add to usage output 2225 | local optgroup_safe=$(mkl_env_esc $optgroup) 2226 | if ! mkl_in_list "$MKL_USAGE_GROUPS" "$optgroup_safe" ; then 2227 | mkl_env_append MKL_USAGE_GROUPS "$optgroup_safe" 2228 | mkl_env_set "MKL_USAGE_GROUP__$optgroup_safe" "$optgroup options: 2229 | " 2230 | fi 2231 | 2232 | local defstr="" 2233 | [[ ! -z $5 ]] && defstr=" [$5]" 2234 | mkl_env_append "MKL_USAGE_GROUP__$optgroup_safe" " $3 $pad $4$defstr 2235 | " 2236 | 2237 | local optname="${3#--}" 2238 | local safeopt= 2239 | local optval="" 2240 | if [[ $3 == *=* ]]; then 2241 | optname="${optname%=*}" 2242 | optval="${3#*=}" 2243 | if [[ $optval == '*' ]]; then 2244 | # Avoid globbing of --foo=* optional arguments 2245 | optval='\*' 2246 | fi 2247 | fi 2248 | 2249 | safeopt=$(mkl_env_esc $optname) 2250 | 2251 | mkl_meta_set "MKL_OPT_ARGS" "$safeopt" "$optval" 2252 | 2253 | # 2254 | # Optional variable scoping by prefix: "env:", "mk:", "def:" 2255 | # 2256 | local setallvar="mkl_allvar_set ''" 2257 | local setmkvar="mkl_mkvar_set ''" 2258 | 2259 | if [[ $varname = env:* ]]; then 2260 | # Set environment variable (during configure runtime only) 2261 | varname=${varname#*:} 2262 | setallvar=mkl_env_set 2263 | setmkvar=mkl_env_set 2264 | elif [[ $varname = mk:* ]]; then 2265 | # Set Makefile.config variable 2266 | varname=${varname#*:} 2267 | setallvar="mkl_mkvar_append ''" 2268 | setmkvar="mkl_mkvar_append ''" 2269 | elif [[ $varname = def:* ]]; then 2270 | # Set config.h define 2271 | varname=${varname#*:} 2272 | setallvar="mkl_define_set ''" 2273 | setmkvar="mkl_define_set ''" 2274 | fi 2275 | 2276 | 2277 | if [[ ! -z $7 ]]; then 2278 | # Function block specified. 2279 | eval "function opt_$safeopt { $7 }" 2280 | else 2281 | # Add default implementation of function simply setting the value. 2282 | # Application may override this by redefining the function after calling 2283 | # mkl_option. 2284 | if [[ $optval = "PATH" ]]; then 2285 | # PATH argument: make it an absolute path. 2286 | # Only set the make variable (not config.h) 2287 | eval "function opt_$safeopt { $setmkvar $varname \"\$(mkl_abspath \$(mkl_render \$1))\"; }" 2288 | else 2289 | # Standard argument: simply set the value 2290 | if [[ -z "$6" ]]; then 2291 | eval "function opt_$safeopt { $setallvar $varname \"\$1\"; }" 2292 | else 2293 | eval "function opt_$safeopt { $setallvar $varname \"$6\"; }" 2294 | fi 2295 | fi 2296 | fi 2297 | 2298 | # If default value is provided and does not start with "$" (variable ref) 2299 | # then set it right away. 2300 | # $ variable refs are set after all checks have run during the 2301 | # generating step. 2302 | if [[ ${#5} != 0 ]] ; then 2303 | if [[ $5 = *\$* ]]; then 2304 | mkl_var_append "MKL_LATE_VARS" "opt_$safeopt:$5" 2305 | else 2306 | opt_$safeopt $5 2307 | fi 2308 | fi 2309 | 2310 | if [[ ! -z $varname ]]; then 2311 | # Add variable to list 2312 | MKL_CONFVARS="$MKL_CONFVARS $varname" 2313 | fi 2314 | 2315 | } 2316 | 2317 | 2318 | 2319 | # Adds a toggle (--enable-X, --disable-X) option. 2320 | # Arguments: 2321 | # option group ("Standard", ..) 2322 | # variable name (WITH_FOO) 2323 | # option (--enable-foo, --enable-foo=*, or --enable-foo=req) 2324 | # help ("foo.." ("Enable" and "Disable" will be prepended)) 2325 | # default (y or n) 2326 | 2327 | function mkl_toggle_option { 2328 | 2329 | # Add option argument 2330 | mkl_option "$1" "$2" "$3" "$4" "$5" 2331 | 2332 | # Add corresponding "--disable-foo" option for "--enable-foo". 2333 | local disname="${3/--enable/--disable}" 2334 | local dishelp="${4/Enable/Disable}" 2335 | mkl_option "$1" "$2" "$disname" "$dishelp" "" "n" 2336 | } 2337 | 2338 | # Adds a toggle (--enable-X, --disable-X) option with builtin checker. 2339 | # This is the library version. 2340 | # Arguments: 2341 | # option group ("Standard", ..) 2342 | # config name (foo, must be same as pkg-config name) 2343 | # variable name (WITH_FOO) 2344 | # action (fail or disable) 2345 | # option (--enable-foo) 2346 | # help (defaults to "Enable ") 2347 | # linker flags (-lfoo) 2348 | # default (y or n) 2349 | 2350 | function mkl_toggle_option_lib { 2351 | 2352 | local help="$6" 2353 | [[ -z "$help" ]] && help="Enable $2" 2354 | 2355 | # Add option argument 2356 | mkl_option "$1" "$3" "$5" "$help" "$8" 2357 | 2358 | # Add corresponding "--disable-foo" option for "--enable-foo". 2359 | local disname="${5/--enable/--disable}" 2360 | local dishelp="${help/Enable/Disable}" 2361 | mkl_option "$1" "$3" "$disname" "$dishelp" "" "n" 2362 | 2363 | # Create checks 2364 | eval "function _tmp_func { mkl_lib_check \"$2\" \"$3\" \"$4\" CC \"$7\"; }" 2365 | mkl_func_push MKL_CHECKS "$MKL_MODULE" _tmp_func 2366 | } 2367 | --------------------------------------------------------------------------------