瀏覽代碼

./configure --option

hewei.it 4 年之前
父節點
當前提交
30317590c7
共有 6 個文件被更改,包括 462 次插入53 次删除
  1. 1 0
      .gitignore
  2. 12 9
      BUILD.md
  3. 29 0
      config.ini
  4. 2 16
      config.mk
  5. 109 28
      configure
  6. 309 0
      scripts/shini.sh

+ 1 - 0
.gitignore

@@ -53,6 +53,7 @@ dist
 test
 *_test
 build
+config.mk
 hconfig.h
 html/uploads
 

+ 12 - 9
BUILD.md

@@ -6,7 +6,7 @@
 gcc4.8+, msvc2015 or later
 
 ## Makefile
-options modify [config.mk](config.mk)
+options modify [config.ini](config.ini)
 ```
 ./configure
 make
@@ -103,23 +103,26 @@ int hio_enable_ssl(hio_t* io);
 https is the best example.
 ```
 sudo apt install openssl libssl-dev # ubuntu
-make clean
-make WITH_OPENSSL=yes
+./configure --with-openssl
+make clean && make
 bin/httpd -s restart -d
+bin/curl -v http://localhost:8080
 bin/curl -v https://localhost:8443
-curl -v https://localhost:8443 --insecure
 ```
 
 ### compile WITH_CURL
 ```
-make WITH_CURL=yes DEFINES="CURL_STATICLIB"
+./configure --with-curl
+make clean && make
+bin/httpd -s restart -d
+bin/curl -v http://localhost:8080
 ```
 
 ### compile WITH_NGHTTP2
 ```
 sudo apt install libnghttp2-dev # ubuntu
-make clean
-make WITH_NGHTTP2=yes
-bin/httpd -d
-bin/curl -v localhost:8080 --http2
+./configure --with-nghttp2
+make clean && make
+bin/httpd -s restart -d
+bin/curl -v http://localhost:8080 --http2
 ```

+ 29 - 0
config.ini

@@ -0,0 +1,29 @@
+# modules
+# include icmp dns ftp smtp
+WITH_PROTOCOL=no
+
+WITH_HTTP=yes
+WITH_HTTP_SERVER=yes
+WITH_HTTP_CLIENT=yes
+
+# WITH_CONSUL need WITH_HTTP_CLIENT=yes
+WITH_CONSUL=no
+
+# features
+# base/hsocket.c: replace gethostbyname with getaddrinfo
+ENABLE_IPV6=no
+# base/hsocket.h: Unix Domain Socket
+ENABLE_UDS=no
+# base/RAII.cpp: Windows MiniDumpWriteDump
+ENABLE_WINDUMP=no
+# http/http_content.h: KeyValue,QueryParams,MultiPart
+USE_MULTIMAP=no
+
+# dependencies
+# for http/client
+WITH_CURL=no
+# for http2
+WITH_NGHTTP2=no
+# for SSL/TLS
+WITH_OPENSSL=no
+WITH_MBEDTLS=no

+ 2 - 16
config.mk

@@ -1,29 +1,15 @@
-# modules
-# include icmp dns ftp smtp
-WITH_PROTOCOL=no
 
+WITH_PROTOCOL=no
 WITH_HTTP=yes
 WITH_HTTP_SERVER=yes
 WITH_HTTP_CLIENT=yes
-
-# WITH_CONSUL need WITH_HTTP_CLIENT=yes
 WITH_CONSUL=no
-
-# features
-# base/hsocket.c: replace gethostbyname with getaddrinfo
 ENABLE_IPV6=no
-# base/hsocket.h: Unix Domain Socket
 ENABLE_UDS=no
-# base/RAII.cpp: Windows MiniDumpWriteDump
 ENABLE_WINDUMP=no
-# http/http_content.h: KeyValue,QueryParams,MultiPart
 USE_MULTIMAP=no
-
-# dependencies
-# for http/client
 WITH_CURL=no
-# for http2
 WITH_NGHTTP2=no
-# for SSL/TLS
 WITH_OPENSSL=no
 WITH_MBEDTLS=no
+CONFIG_DATE=20210402

+ 109 - 28
configure

@@ -1,15 +1,90 @@
 #!/bin/bash
 
-confile=hconfig.h
-# start confile
-cat << END > $confile
-#ifndef HV_CONFIG_H_
-#define HV_CONFIG_H_
+. "$(dirname "$0")/scripts/shini.sh"
+
+print_help() {
+    shini_parse "config.ini"
+    cat << END
+Usage: ./configure [--option] ...
+
+options:
+  --with-MODULE
+  --without-MODULE
+  --enable-FEATURE
+  --disable-FEATURE
+
+modules:
+  --with-protocol       compile protocol module?        (DEFAULT: $WITH_PROTOCOL)
+  --with-http           compile http module?            (DEFAULT: $WITH_HTTP)
+  --with-http-client    compile http client module?     (DEFAULT: $WITH_HTTP_CLIENT)
+  --with-http-server    compile http server module?     (DEFAULT: $WITH_HTTP_SERVER)
+  --with-consul         compile consul module? default: (DEFAULT: $WITH_CONSUL)
+
+features:
+  --enable-ipv6         enable IPv6?                    (DEFAULT: $ENABLE_IPV6)
+  --enable-uds          enable Unix Domain Socket?      (DEFAULT: $ENABLE_UDS)
+  --enable-windump      enable Windows coredump?        (DEFAULT: $ENABLE_WINDUMP)
+
+dependencies:
+  --with-curl           compile with curl?              (DEFAULT: $WITH_CURL)
+  --with-nghttp2        compile with nghttp2?           (DEFAULT: $WITH_NGHTTP2)
+  --with-openssl        compile with openssl?           (DEFAULT: $WITH_OPENSSL)
+  --with-mbedtls        compile with mbedtls?           (DEFAULT: $WITH_MBEDTLS)
 
 END
+}
+
+mkdir tmp 2>/dev/null
+cp config.ini tmp/config.mk
+while [ -n "$1" ]
+do
+    opt="$1"
+    KEY=""
+    VAL=yes
+    case $opt in
+        --help)
+            print_help
+            exit 0
+            ;;
+        --with-*)
+            KEY="WITH_${opt:7}"
+            ;;
+        --without-*)
+            KEY="WITH_${opt:10}"
+            VAL=no
+            ;;
+        --enable-*)
+            KEY="ENABLE_${opt:9}"
+            ;;
+        --disable-*)
+            KEY="ENABLE_${opt:10}"
+            VAL=no
+            ;;
+        *)
+            print_help
+            exit 255
+            ;;
+    esac
+
+    if [ -n $KEY ]; then
+        FEATURE=$(echo "$KEY" | tr "a-z-" "A-Z_")
+        shini_write "tmp/config.mk" "" "$FEATURE" "$VAL"
+    fi
+
+    shift 1
+done
+
+# config.mk
+echo "[config.mk]"
+if [ -f tmp/config.mk ]; then
+    mv tmp/config.mk config.mk
+    shini_write "config.mk" "" "CONFIG_DATE" "$(date +%Y%m%d)"
+fi
+cat config.mk
+echo ""
 
 # Checks for compiler
-echo "checking for compiler..."
+echo -e "\nchecking for compiler..."
 if [ $CROSS_COMPILE ]; then
     CC=${CROSS_COMPILE}gcc
     CXX=${CROSS_COMPILE}g++
@@ -25,7 +100,34 @@ echo "CC  = $CC"
 echo "CXX = $CXX"
 echo "$CC_VERSION"
 
-# shell functions
+# Checks for os
+echo -e "\nchecking for os..."
+HOST_OS=`uname -s`
+HOST_ARCH=`uname -m`
+TARGET_PLATFORM=`$CC -v 2>&1 | grep Target | sed 's/Target: //'`
+TARGET_ARCH=`echo $TARGET_PLATFORM | awk -F'-' '{print $1}'`
+
+case $TARGET_PLATFORM in
+    *mingw*) TARGET_OS=Windows ;;
+    *android*) TARGET_OS=Android ;;
+    *darwin*) TARGET_OS=Darwin ;;
+    *) TARGET_OS=Linux ;;
+esac
+
+echo "HOST_OS         = $HOST_OS"
+echo "HOST_ARCH       = $HOST_ARCH"
+echo "TARGET_PLATFORM = $TARGET_PLATFORM"
+echo "TARGET_OS       = $TARGET_OS"
+echo "TARGET_ARCH     = $TARGET_ARCH"
+
+# hconfig.h
+echo -e "\n>> hconfig.h"
+confile=hconfig.h
+cat << END > $confile
+#ifndef HV_CONFIG_H_
+#define HV_CONFIG_H_
+
+END
 
 write_define() {
 cat << END >> hconfig.h
@@ -36,7 +138,6 @@ cat << END >> hconfig.h
 END
 }
 
-mkdir tmp 2>/dev/null
 check_header() {
 echo -n "checking for $header... "
 rm tmp/check 2>/dev/null
@@ -99,26 +200,6 @@ END
 fi
 }
 
-# Checks for os
-echo "checking for os..."
-HOST_OS=`uname -s`
-HOST_ARCH=`uname -m`
-TARGET_PLATFORM=`$CC -v 2>&1 | grep Target | sed 's/Target: //'`
-TARGET_ARCH=`echo $TARGET_PLATFORM | awk -F'-' '{print $1}'`
-
-case $TARGET_PLATFORM in
-    *mingw*) TARGET_OS=Windows ;;
-    *android*) TARGET_OS=Android ;;
-    *darwin*) TARGET_OS=Darwin ;;
-    *) TARGET_OS=Linux ;;
-esac
-
-echo "HOST_OS         = $HOST_OS"
-echo "HOST_ARCH       = $HOST_ARCH"
-echo "TARGET_PLATFORM = $TARGET_PLATFORM"
-echo "TARGET_OS       = $TARGET_OS"
-echo "TARGET_ARCH     = $TARGET_ARCH"
-
 # Checks for programs
 
 # Checks for libraries

+ 309 - 0
scripts/shini.sh

@@ -0,0 +1,309 @@
+# shini - compatible INI library for sh
+#
+# This code is released freely under the MIT license - see the shipped LICENSE document.
+# For the latest version etc, please see https://github.com/wallyhall/shini
+#
+
+# Solely for the purpose of portable performance, this script breaks good practice to
+# avoid forking subshells.  One such good practice is avoiding global variables.
+# This variable is used to carry non-numeric results from functions to the caller.
+# Alternatively an echo and "$(...)" approach could be used, but is significantly slower.
+
+shini_setup()
+{
+    if [ -n "$ZSH_VERSION" ]; then
+        RESTORE_OPTS=$(set +o)
+        # Enable BASH_REMATCH for zsh
+        setopt KSH_ARRAYS BASH_REMATCH
+    fi
+}
+
+shini_teardown()
+{
+    [ -n "$ZSH_VERSION" ] && eval "$RESTORE_OPTS"
+}
+
+shini_function_exists()
+{
+    type "$1" > /dev/null 2>&1
+    return $?
+}
+
+shini_regex_match()
+{
+    # $KSH_VERSION (I'm told) only exists on ksh 93 and above, which supports regex matching.
+    if [ -n "$BASH_VERSINFO" ] && [ "$BASH_VERSINFO" -ge 3 ] || \
+       [ -n "$ZSH_VERSION" ] || \
+       [ -n "$KSH_VERSION" ]; then
+        [[ "$1" =~ $2 ]] && return 0 || return 1
+    fi
+
+    printf '%s' "$1" | grep -qe "$2"
+    return $?
+}
+
+shini_regex_replace()
+{
+    if [ -n "$BASH_VERSINFO" ] && [ "${BASH_VERSINFO}" -ge 3 ] || \
+       [ -n "$ZSH_VERSION" ]; then
+        [[ "$1" =~ $2 ]] && shini_retval=${BASH_REMATCH[1]} || shini_retval="$1"
+        return 0
+    fi
+
+    shini_retval="$(printf '%s' "$1" | sed -E "s/$2/\1/")"  # If you have isses on older systems,
+    # it may be the non-newer POSIX compliant sed.
+    # -E should be enabling extended regex mode portably.
+}
+
+# @param inifile Filename of INI file to parse
+# @param postfix Function postfix for callbacks (optional)
+# @param extra Extra argument for callbacks (optional)
+shini_parse()
+{
+    shini_parse_section "$1" '' "$2" "$3" "$4" "$5"
+}
+
+# @param inifile Filename of INI file to parse
+# @param section Section to parse (or empty string for entire file)
+# @param postfix Function postfix for callbacks (optional)
+# @param extra Extra argument for callbacks (optional)
+shini_parse_section()
+{
+    shini_setup
+    # ********
+
+    RX_KEY='[a-zA-Z0-9_\-\.]'
+    RX_VALUE="[^;\"]"
+    RX_SECTION='[a-zA-Z0-9_\-]'
+    RX_WS='[ 	]'
+    RX_QUOTE='"'
+    RX_HEX='[0-9A-F]'
+    POSTFIX=''
+    SKIP_TO_SECTION=''
+    EXTRA1=''
+    EXTRA2=''
+    EXTRA3=''
+    SECTION_FOUND=-1
+	
+	if [ $# -ge 2 ] && [ ! -z "$2" ]; then
+        SKIP_TO_SECTION="$2"
+    fi
+	
+    if [ $# -ge 3 ] && [ ! -z "$3" ]; then
+        POSTFIX="_$3"
+    fi
+	
+    if [ $# -ge 4 ] && ! [ -z "$4" ]; then
+        EXTRA1="$4"
+    fi
+	
+    if [ $# -ge 5 ] && [ ! -z "$5" ]; then
+        EXTRA2="$5"
+    fi
+	
+    if [ $# -ge 6 ] && [ ! -z "$6" ]; then
+        EXTRA3="$6"
+    fi
+	
+    if ! shini_function_exists "__shini_parsed${POSTFIX}"; then
+        printf 'shini: __shini_parsed%s function not declared.\n' "${POSTFIX}" 1>&2
+        exit 255
+    fi
+
+    if [ $# -lt 1 ]; then
+        if shini_function_exists "__shini_no_file_passed{$POSTFIX}"; then
+            "__shini_no_file_passed${POSTFIX}" "$EXTRA1" "$EXTRA2" "$EXTRA3"
+        else
+            printf 'shini: Argument 1 needs to specify the INI file to parse.\n' 1>&2
+            exit 254
+        fi
+    fi
+    INI_FILE="$1"
+
+    if [ ! -r "$INI_FILE" ]; then
+        if shini_function_exists "__shini_file_unreadable${POSTFIX}"; then
+            "__shini_file_unreadable${POSTFIX}" "$INI_FILE" "$EXTRA1" "$EXTRA2" "$EXTRA3"
+        else
+            printf 'shini: Unable to read INI file:\n  `%s`\n' "$INI_FILE" 1>&2
+            exit 253
+        fi
+    fi
+
+    # Iterate INI file line by line
+    LINE_NUM=0
+    SECTION=''
+    while read LINE || [ -n "$LINE" ]; do  # -n $LINE catches final line if not empty
+        # Check for new sections
+        if shini_regex_match "$LINE" "^${RX_WS}*\[${RX_SECTION}${RX_SECTION}*\]${RX_WS}*$"; then
+            shini_regex_replace "$LINE" "^${RX_WS}*\[(${RX_SECTION}${RX_SECTION}*)\]${RX_WS}*$" "\1"
+            SECTION=$shini_retval
+
+            if [ "$SKIP_TO_SECTION" != '' ]; then
+                # stop once specific section is finished
+                [ $SECTION_FOUND -eq 0 ] && break;
+                
+                # mark the specified section as found
+                [ "$SKIP_TO_SECTION" = "$SECTION" ] && SECTION_FOUND=0;
+            fi
+
+            if shini_function_exists "__shini_parsed_section${POSTFIX}"; then
+                "__shini_parsed_section${POSTFIX}" "$SECTION" "$EXTRA1" "$EXTRA2" "$EXTRA3"
+            fi
+			
+            LINE_NUM=$((LINE_NUM+1))
+	    continue
+        fi
+        
+        # Skip over sections we don't care about, if a specific section was specified
+        [ "$SKIP_TO_SECTION" != '' ] && [ $SECTION_FOUND -ne 0 ] && LINE_NUM=$((LINE_NUM+1)) && continue;
+		
+        # Check for new values
+        if shini_regex_match "$LINE" "^${RX_WS}*${RX_KEY}${RX_KEY}*${RX_WS}*="; then
+            shini_regex_replace "$LINE" "^${RX_WS}*(${RX_KEY}${RX_KEY}*)${RX_WS}*=.*$"
+            KEY=$shini_retval
+            
+            shini_regex_replace "$LINE" "^${RX_WS}*${RX_KEY}${RX_KEY}*${RX_WS}*=${RX_WS}*${RX_QUOTE}{0,1}(${RX_VALUE}*)${RX_QUOTE}{0,1}(${RX_WS}*\;.*)*$"
+            VALUE=$shini_retval
+			
+            if shini_regex_match "$LINE" "^0x${RX_HEX}${RX_HEX}*$"; then
+                VALUE=$(printf '%d' "$VALUE")
+            fi
+			
+            "__shini_parsed${POSTFIX}" "$SECTION" "$KEY" "$VALUE" "$EXTRA1" "$EXTRA2" "$EXTRA3"
+						
+            if shini_function_exists "__shini_parsed_comment${POSTFIX}"; then
+                if shini_regex_match "$LINE" ";"; then
+                    shini_regex_replace "$LINE" "^.*\;(.*)$"
+                    COMMENT=$shini_retval
+                    
+                    "__shini_parsed_comment${POSTFIX}" "$COMMENT" "$EXTRA1" "$EXTRA2" "$EXTRA3"
+                fi
+            fi
+
+            LINE_NUM=$((LINE_NUM+1))
+            continue
+        fi
+		
+        # Announce parse errors
+        if [ "$LINE" != '' ] &&
+          ! shini_regex_match "$LINE" "^${RX_WS}*;.*$" &&
+          ! shini_regex_match "$LINE" "^${RX_WS}*$"; then
+            if shini_function_exists "__shini_parse_error${POSTFIX}"; then
+                "__shini_parse_error${POSTFIX}" $LINE_NUM "$LINE" "$EXTRA1" "$EXTRA2" "$EXTRA3"
+            else
+                printf 'shini: Unable to parse line %d:\n  `%s`\n' $LINE_NUM "$LINE"
+            fi
+        fi
+		
+        LINE_NUM=$((LINE_NUM+1))
+    done < "$INI_FILE"
+
+    # ********
+    shini_teardown
+}
+
+# @param inifile Filename of INI file to write to
+# @param section Section of INI file to write to
+# @param variable Variable name to add/update/delete
+# @param value Value to add/update, do not specify to delete
+shini_write()
+{
+    shini_setup
+    # ********
+
+    # This is not yet optimised (early write support only) - 
+    # We actually re-parse the entire file, looking for the location in which to
+    # write the new value, writing out everything we parse as-is meanwhile.
+
+    # Declare the following if you want particular behaviour (like skipping
+    # broken INI file content or handling an unreadable file etc).
+    #  __shini_no_file_passed__writer()
+    #  __shini_file_unreadable__writer()
+    #  __shini_parse_error__writer()
+    
+    # Writer callbacks, used for writing the INI file content
+    __shini_parsed_section__writer()
+    {
+        # Validate the last section wasn't the target section
+        if [ "$LAST_SECTION" = "$WRITE_SECTION" ]; then
+            # If it was, and the value wasn't written already, write it
+            if [ $VALUE_WRITTEN -eq 0 ]; then
+                printf "\n%s=%s" "$WRITE_KEY" "$WRITE_VALUE" >> "$INI_FILE_TEMP"
+                VALUE_WRITTEN=1
+            fi
+        fi
+        printf "\n[%s]" "$1" >> "$INI_FILE_TEMP"
+        
+        LAST_SECTION="$1"
+    }
+    
+    __shini_parsed_comment__writer()
+    {
+        printf ";%s" "$1" >> "$INI_FILE_TEMP"
+    }
+    
+    __shini_parsed__writer()
+    {
+        if [ "$1" = "$WRITE_SECTION" ]; then
+            if [ "$2" = "$WRITE_KEY" ]; then
+                if [ ! -z "$WRITE_VALUE" ]; then
+                    printf "\n%s=%s" "$WRITE_KEY" "$WRITE_VALUE" >> "$INI_FILE_TEMP"
+                fi
+                VALUE_WRITTEN=1
+                return
+            fi
+        fi
+        
+        printf "\n%s=%s" "$2" "$3" >> "$INI_FILE_TEMP"
+    }
+    
+    if [ $# -lt 3 ]; then
+        if shini_function_exists "__shini_no_file_passed"; then
+            __shini_no_file_passed
+        else
+            printf 'shini: Argument 1 needs to specify the INI file to write.\n' 1>&2
+            exit 254
+        fi
+    fi
+    
+    INI_FILE="$1"
+    INI_FILE_TEMP="$(mktemp -t shini_XXXXXX)"       
+    
+    WRITE_SECTION="$2"
+    WRITE_KEY="$3"
+    WRITE_VALUE="$4"
+    LAST_SECTION=""
+    VALUE_WRITTEN=0
+    
+    shini_parse "$1" "_writer" "$2" "$3" "$4"
+    # Still not written out yet
+    if [ $VALUE_WRITTEN -eq 0 ]; then
+        # Check if final existing section was target one, add it if not
+        if [ "$LAST_SECTION" != "$WRITE_SECTION" ]; then
+            printf "\n[%s]" "$WRITE_SECTION" >> "$INI_FILE_TEMP"
+        fi
+        # Write value at end of file
+        printf "\n%s=%s" "$WRITE_KEY" "$WRITE_VALUE" >> "$INI_FILE_TEMP"
+    fi
+    
+    mv "$INI_FILE_TEMP" "$INI_FILE"
+    
+    # ********
+    shini_teardown
+}
+
+# default usage
+__shini_parsed()
+{
+    eval $2=$3
+}
+
+__shini_parse_error()
+{
+    error_line=$1
+}
+
+__shini_parse_error__writer()
+{
+    error_line=$1
+}