|
- #!/bin/sh
- # A script-only build utility like autotools
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http:##www.apache.org#licenses#LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- #
- # Copyright (C) 2022-present, TBOOX Open Source Group.
- #
- # @author ruki
- # @homepage https://github.com/xmake-io/xmake.sh
- #
-
- #-----------------------------------------------------------------------------
- # some constants
- #
- xmake_sh_projectdir=$(X= cd -- "$(dirname -- "$0")" && pwd -P)
- xmake_sh_buildir="build"
- xmake_sh_version="1.0.5"
- xmake_sh_verbose=false
- xmake_sh_diagnosis=false
- xmake_sh_copyright="Copyright (C) 2022-present Ruki Wang, tboox.org, xmake.io."
- xmake_sh_makefile="${xmake_sh_projectdir}/makefile"
-
- #-----------------------------------------------------------------------------
- # some helper functions
- #
- raise() {
- echo "$@" 1>&2 ; exit 1
- }
-
- vprint() {
- if "${xmake_sh_verbose}"; then
- echo "$@"
- fi
- }
-
- dprint() {
- if "${xmake_sh_diagnosis}"; then
- echo "$@"
- fi
- }
-
- # show and escape string instead of `echo -e`, because sh does not support it
- print() {
- printf "${@}\n"
- }
-
- wprint() {
- if "${xmake_sh_verbose}"; then
- printf "warning: ${@}\n"
- fi
- }
-
- # test empty string
- test_z() {
- if test "x${1}" = "x"; then
- return 0
- fi
- return 1
- }
-
- # test non-empty string
- test_nz() {
- if test "x${1}" != "x"; then
- return 0
- fi
- return 1
- }
-
- # test string is equal
- test_eq() {
- if test "x${1}" = "x${2}"; then
- return 0
- fi
- return 1
- }
-
- # test string is not equal
- test_nq() {
- if test "x${1}" != "x${2}"; then
- return 0
- fi
- return 1
- }
-
- string_toupper() {
- _ret=$(echo "$1" | tr '[a-z]' '[A-Z]')
- }
-
- string_tolower() {
- _ret=$(echo "$1" | tr '[A-Z]' '[a-z]')
- }
-
- string_replace() {
- _ret=$(echo "$1" | sed "s/${2}/${3}/g")
- }
-
- # we avoid use `cut` command, because it's slow
- string_split() {
- local str="${1}"
- local sep="${2}"
- local idx="${3}"
- local oldifs="${IFS}"
- IFS="${sep}"
- set -- ${str}
- if test_nz "${idx}"; then
- case "${idx}" in
- 1) _ret="$1";;
- 2) _ret="$2";;
- 3) _ret="$3";;
- 4) _ret="$4";;
- 5) _ret="$5";;
- 6) _ret="$6";;
- esac
- else
- _ret="$1"
- _ret2="$2"
- _ret3="$3"
- _ret4="$4"
- _ret5="$5"
- _ret6="$6"
- fi
- IFS="${oldifs}"
- }
-
- # does contain sub-string?
- # e.g.
- # str="src/*.cpp"
- # string_contains "$str" "src"
- string_contains() {
- case "${1}" in
- *${2}*) return 0;;
- *) return 1;;
- esac
- return 1
- }
-
- # does contain "*"?
- string_contains_star() {
- case "${1}" in
- *\**) return 0;; # bash
- *'*'*) return 0;; # csh
- *) return 1;;
- esac
- return 1
- }
-
- # does contain "**"?
- string_contains_star2() {
- case "${1}" in
- *\*\**) return 0;; # bash
- *'**'*) return 0;; # csh
- *) return 1;;
- esac
- return 1
- }
-
- # does startswith sub-string?
- # e.g.
- # str="src/*.cpp"
- # string_startswith "$str" "src"
- string_startswith() {
- case "${1}" in
- ${2}*) return 0;;
- *) return 1;;
- esac
- return 1
- }
-
- # duplicate characters
- # e.g. string_dupch 10 "." => ...........
- string_dupch() {
- local count=${1}
- local ch=${2}
- printf %${count}s | tr " " "${ch}"
- }
-
- # replace file content
- _io_replace_file() {
- local infile="${1}"
- local outfile="${2}"
- local patterns="${3}"
- sed "/./ {${patterns}}" "${infile}" > "${outfile}"
- }
-
- # try remove file or directory
- _os_tryrm() {
- if test -f "${1}"; then
- rm "${1}"
- elif test -d "${1}"; then
- rm -r "${1}"
- fi
- }
-
- # get temporary file
- _os_tmpfile() {
- _ret=$(mktemp)
- }
-
- # try run program
- _os_runv() {
- if ${xmake_sh_diagnosis}; then
- ${@}
- else
- ${@} >/dev/null 2>&1
- fi
- local ok=$?
- if test "${ok}" -ne "0"; then
- return 1
- fi
- return 0
- }
-
- # try run program and get output
- _os_iorunv() {
- _os_tmpfile
- local tmpfile="${_ret}"
- ${@} >"${tmpfile}" 2>&1
- local ok=$?
- if test "${ok}" -ne "0"; then
- _ret=""
- else
- local result=$(cat "${tmpfile}")
- _ret="${result}"
- fi
- _os_tryrm "${tmpfile}"
- }
-
- # find file in the given directory
- # e.g. _os_find . xmake.sh
- _os_find() {
- local dir="${1}"
- local name="${2}"
- local depth="${3}"
- if test_nz "${depth}"; then
- if is_host "macosx"; then
- _ret=$(find "${dir}" -depth "${depth}" -type f -name "${name}")
- else
- _ret=$(find "${dir}" -maxdepth "${depth}" -mindepth "${depth}" -type f -name "${name}")
- fi
- else
- _ret=$(find "${dir}" -type f -name "${name}")
- fi
- }
-
- # get date, "%Y%m%d%H%M" -> 202212072222
- # Use deterministic timestamp from SOURCE_DATE_EPOCH if available
- # https://reproducible-builds.org/docs/source-date-epoch/
- _os_date() {
- if test_z "${SOURCE_DATE_EPOCH}"; then
- _ret=$(date +"${1}")
- elif is_host "macosx" "freebsd" "bsd"; then
- _ret=$(date -u -r "$SOURCE_DATE_EPOCH" +"${1}")
- else
- _ret=$(date -u -d "@$SOURCE_DATE_EPOCH" +"${1}")
- fi
- }
-
- # we avoid use `basename`, because it's slow
- path_filename() {
- local path="${1}"
- if test_eq "${path}" "/"; then
- _ret="/"
- else
- _ret="${path##*/}"
- fi
- }
-
- path_extension() {
- path_filename "${1}"; local filename="${_ret}"
- _ret=".${filename##*.}"
- }
-
- path_basename() {
- path_filename "${1}"; local filename="${_ret}"
- _ret="${filename%.*}"
- }
-
- # we avoid use `dirname -- ${1}`, because it's too slow
- path_directory() {
- local path="${1}"
- if test_z "${path}"; then
- raise "invalid empty path in path_directory()."
- fi
- path="${path%/}"
- local dir="${path%/*}"
- if string_startswith "${path}" "/"; then
- if test_z "${dir}"; then
- dir="/"
- fi
- else
- dir="${dir#/}"
- if test_z "${dir}"; then
- dir="."
- fi
- fi
- _ret="${dir}"
- }
-
- # e.g. path_filename_fromdir "/tmp/file" "/tmp" -> "file"
- path_filename_fromdir() {
- _ret="${1#${2}/}"
- }
-
- path_is_absolute() {
- if string_startswith "${1}" "/"; then
- return 0
- fi
- return 1
- }
-
- # get relative path, e.g $(path_relative ${rootdir} ${absolute_path}`
- path_relative() {
- local source="${1}"
- local target="${2}"
- if test_z "${source}" || test_z "${target}"; then
- raise "invalid empty path in path_relative()"
- fi
-
- # patch missing "./"
- source=${source#./}
- source=${source#.}
- target=${target#./}
- target=${target#.}
- if test_z "${source}"; then
- _ret="${target}"
- return
- fi
-
- # find common path
- local result=""
- local common_part=$source
- while test_eq "${target#$common_part}" "${target}"; do
- # no match, means that candidate common part is not correct
- # go up one level (reduce common part)
- path_directory "${common_part}"; common_part="${_ret}"
- # and record that we went back, with correct / handling
- if test_z "${result}"; then
- result=".."
- else
- result="../${result}"
- fi
- done
-
- if test_eq "${common_part}" "/"; then
- # special case for root (no common path)
- result="${result}/"
- fi
-
- # since we now have identified the common part,
- # compute the non-common part
- local forward_part="${target#$common_part}"
-
- # and now stick all parts together
- if test_nz "${result}" && test_nz "${forward_part}"; then
- result="${result}${forward_part}"
- elif test_nz "${forward_part}"; then
- result="${forward_part#*/}"
- fi
-
- # same directory?
- if test_z "${result}" && test_eq "${source}" "${target}"; then
- result="."
- fi
-
- _ret="${result}"
- }
-
- path_sourcekind() {
- local sourcekind=""
- case "${1}" in
- *.cpp) sourcekind="cxx";;
- *.cc) sourcekind="cxx";;
- *.c) sourcekind="cc";;
- *.ixx) sourcekind="cxx";;
- *.mm) sourcekind="mxx";;
- *.m) sourcekind="mm";;
- *.S) sourcekind="as";;
- *.s) sourcekind="as";;
- *.asm) sourcekind="as";;
- *) raise "unknown sourcekind for ${1}" ;;
- esac
- _ret="${sourcekind}"
- }
-
- path_toolname() {
- local toolname=""
- case "${1}" in
- *-gcc) toolname="gcc";;
- */gcc) toolname="gcc";;
- gcc) toolname="gcc";;
- gcc-*) toolname="gcc";;
- */gcc-*) toolname="gcc";;
- *-g++) toolname="gxx";;
- */g++) toolname="gxx";;
- g++) toolname="gxx";;
- g++-*) toolname="gxx";;
- */g++-*) toolname="gxx";;
- xcrun*clang++) toolname="clangxx";;
- xcrun*clang) toolname="clang";;
- *-clang++) toolname="clangxx";;
- */clang++) toolname="clangxx";;
- clang++) toolname="clangxx";;
- clang++-*) toolname="clangxx";;
- */clang++-*) toolname="clangxx";;
- *-clang) toolname="clang";;
- */clang) toolname="clang";;
- clang) toolname="clang";;
- clang-*) toolname="clang";;
- */clang-*) toolname="clang";;
- */emcc) toolname="emcc";;
- emcc) toolname="emcc";;
- */em++) toolname="emxx";;
- em++) toolname="emxx";;
- *-ar) toolname="ar";;
- */ar) toolname="ar";;
- ar) toolname="ar";;
- */emar) toolname="emar";;
- emar) toolname="emar";;
- cc) toolname="gcc";;
- */cc) toolname="gcc";;
- c++) toolname="gxx";;
- */c++) toolname="gxx";;
- *) raise "unknown tool ${1}";;
- esac
- _ret="${toolname}"
- }
-
- # get flag name from toolkind, e.g. cc => cflags, cxx => cxxflags
- _get_flagname() {
- local toolkind="${1}"
- local flagname=""
- case "${toolkind}" in
- cc) flagname="cflags";;
- cxx) flagname="cxxflags";;
- as) flagname="asflags";;
- mm) flagname="mflags";;
- mxx) flagname="mxxflags";;
- ar) flagname="arflags";;
- sh) flagname="shflags";;
- ld) flagname="ldflags";;
- *) raise "unknown toolkind(${toolkind})!" ;;
- esac
- _ret="${flagname}"
- }
-
- # is enabled? true, yes, y
- _is_enabled() {
- local value=${1}
- if test_eq "${value}" "true"; then
- return 0
- elif test_eq "${value}" "yes"; then
- return 0
- elif test_eq "${value}" "y"; then
- return 0
- fi
- return 1
- }
-
- # deduplicate string list
- # .e.g "hello world hello how are you world" -> hello world how are you
- _dedup() {
- _ret=$(echo "${1}" | awk '{for (i = 1; i <= NF; ++i) if (!seen[$i]++) printf $i " "}')
- }
-
- # deduplicate string list from the reverse order
- # .e.g "hello world hello how are you world" -> hello how are you world
- _dedup_reverse() {
- local result=""
- local list=""
- local item=""
- list=$(echo "${1}" | awk '{for (i = NF; i > 0; --i) if (!seen[$i]++) printf $i " "}')
- for item in ${list}; do
- result="${item} ${result}"
- done
- _ret="${result}"
- }
-
- #-----------------------------------------------------------------------------
- # map functions
- #
-
- # define map, @note we can not use bash/declare to define map, because sh does not support it.
- #
- # _map "options"
- # _map_set "options" "key1" "value1"
- # _map_set "options" "key2" "value2"
- # _map_set "options" "key2" "value3"
- # _map_set "options" "key3" "value3"
- # _map_set "options" "key4" "__empty__"
- # _map_set "options" "key4" "__empty__"
- # _map_count "options"; _count="${_ret}"
- # _map_keys "options"; _keys="${_ret}"
- # echo ${_count}
- # for key in ${_keys}; do
- # _map_get "options" ${key}; value="{_ret}"
- # echo ${key} "->" ${value}
- # done
- #
- # echo "------"
- # _map_remove "options" "key3"
- # _map_count "options"; _count="${_ret}"
- # _map_keys "options"; _keys="${_ret}"
- # echo ${_count}
- # for key in ${_keys}; do
- # _map_get "options" ${key}; value="{_ret}"
- # echo ${key} "->" ${value}
- # done
- #
- _map() {
- local name=${1}
- # eval _map_${name}_count=0
- # eval _map_${name}_keys=""
- }
-
- # because the shell is slow, we have to temporarily
- # disable some of the map features for performance.
- #
- #_map_count() {
- # local name=${1}
- # local count=$(eval echo \$_map_${name}_count)
- # _ret="${count}"
- #}
-
- _map_get() {
- local name="${1}"
- local key="${2}"
- _ret=$(eval echo \$_map_${name}_value_${key})
- if test_eq "${_ret}" "__empty__"; then
- _ret=""
- fi
- }
-
- _map_has() {
- local name="${1}"
- local key="${2}"
- local value=""
- value=$(eval echo \$_map_${name}_value_${key})
- if test_nz "${value}"; then
- return 0
- fi
- return 1
- }
-
- _map_set() {
- local name="${1}"
- local key="${2}"
- local value="${3}"
- # if ! _map_has ${name} ${key}; then
- # _map_count "options"; local count="${_ret}"
- # eval _map_${name}_count=$((${count} + 1))
- # local keys=$(eval echo \$_map_${name}_keys)
- # keys="${keys} ${key}"
- # eval _map_${name}_keys=\${keys}
- # fi
- eval _map_${name}_value_${key}=\${value}
- }
-
- #_map_remove() {
- # local name="${1}"
- # local key="${2}"
- # if _map_has ${name} ${key}; then
- # _map_count "options"; local count="${_ret}"
- # eval _map_${name}_count=$((${count} - 1))
- # eval _map_${name}_value_${key}=""
- # local keys=$(eval echo \$_map_${name}_keys)
- # local keys_new=""
- # local k=""
- # for k in ${keys}; do
- # if test_nq "${k}" "${key}"; then
- # keys_new="${keys_new} ${k}"
- # fi
- # done
- # eval _map_${name}_keys=\${keys_new}
- # fi
- #}
-
- #_map_keys() {
- # local name="${1}"
- # local keys=$(eval echo \$_map_${name}_keys)
- # _ret="${keys}"
- #}
-
- #-----------------------------------------------------------------------------
- # detect default environments
- #
-
- # detect hosts
- os_host=`uname`
- string_tolower ${os_host}; os_host="${_ret}"
- if echo "${os_host}" | grep cygwin >/dev/null 2>&1; then
- os_host="cygwin"
- fi
- if echo "${os_host}" | grep msys >/dev/null 2>&1; then
- os_host="msys"
- fi
- if echo "${os_host}" | grep mingw >/dev/null 2>&1; then
- os_host="msys"
- fi
- if echo "${os_host}" | grep darwin >/dev/null 2>&1; then
- os_host="macosx"
- fi
- if echo "${os_host}" | grep linux >/dev/null 2>&1; then
- os_host="linux"
- fi
- if echo "${os_host}" | grep freebsd >/dev/null 2>&1; then
- os_host="freebsd"
- fi
- if echo "${os_host}" | grep bsd >/dev/null 2>&1; then
- os_host="bsd"
- fi
- if echo "${os_host}" | grep Haiku >/dev/null 2>&1; then
- os_host="haiku"
- fi
-
- # determining host
- # e.g.
- # if is_host "linux" "macosx"; then
- # ...
- # fi
- is_host() {
- local host=""
- for host in $@; do
- if test_eq "${os_host}" "${host}"; then
- return 0
- fi
- done
- return 1
- }
-
- # detect host architecture
- os_arch=`uname -m | tr '[A-Z]' '[a-z]'`
- if test_eq "${os_arch}" "i686"; then
- os_arch="i386"
- elif test_eq "${os_arch}" "aarch64" || test_eq "${os_arch}" "arm64"; then
- os_arch="arm64"
- elif string_contains "${os_arch}" "armv7"; then
- os_arch="armv7"
- elif string_contains "${os_arch}" "arm"; then
- os_arch="arm"
- fi
-
- # set the default target platform
- _target_plat_default=${os_host}
- if is_host "msys"; then
- _target_plat_default="mingw"
- elif is_host "freebsd"; then
- _target_plat_default="bsd"
- elif test_nz "${EMSDK}"; then
- _target_plat_default="wasm"
- fi
-
- # set the default target architecture
- _target_arch_default=${os_arch}
- if is_host "msys" && test_nz "${MSYSTEM_CARCH}"; then
- _target_arch_default="${MSYSTEM_CARCH}"
- elif test_nz "${TERMUX_ARCH}"; then
- _target_arch_default="${TERMUX_ARCH}"
- elif test_nz "${EMSDK}"; then
- _target_arch_default="wasm32"
- fi
- if test_eq "${_target_arch_default}" "i686"; then
- _target_arch_default="i386"
- elif test_eq "${_target_arch_default}" "aarch64" || test_eq "${_target_arch_default}" "arm64"; then
- _target_arch_default="arm64"
- elif string_contains "${_target_arch_default}" "armv7"; then
- _target_arch_default="armv7"
- elif string_contains "${_target_arch_default}" "arm"; then
- _target_arch_default="arm"
- fi
-
- # set the default target mode
- _target_mode_default="release"
-
- # set the default target kind
- _target_kind_default="static"
-
- # set the default project generator and build program
- if is_host "freebsd" "bsd"; then
- project_generator="gmake"
- _make_program_default="gmake"
- _ninja_program_default="ninja"
- elif is_host "msys" "cygwin"; then
- project_generator="gmake"
- _make_program_default="make.exe"
- _ninja_program_default="ninja.exe"
- else
- project_generator="gmake"
- _make_program_default="make"
- _ninja_program_default="ninja"
- fi
-
- # set the default directories
- if test -d "/usr/local"; then
- _install_prefix_default="/usr/local"
- elif test -d "/usr"; then
- _install_prefix_default="/usr"
- fi
- _install_bindir_default="\${prefix}/bin"
- _install_libdir_default="\${prefix}/lib"
- _install_includedir_default="\${prefix}/include"
-
- # determining target platform
- # e.g.
- # if is_plat "linux" "macosx"; then
- # ...
- # fi
- is_plat() {
- local plat=""
- for plat in $@; do
- if test_eq "${_target_plat}" "${plat}"; then
- return 0
- fi
- done
- return 1
- }
-
- # determining target architecture
- # e.g.
- # if is_arch "x86_64" "i386"; then
- # ...
- # fi
- is_arch() {
- local arch=""
- for arch in $@; do
- if test_eq "${_target_arch}" "${arch}"; then
- return 0
- fi
- done
- return 1
- }
-
- # determining target mode
- # e.g.
- # if is_mode "release"; then
- # ...
- # fi
- is_mode() {
- local mode=""
- for mode in $@; do
- if test_eq "${_target_mode}" "${mode}"; then
- return 0
- fi
- done
- return 1
- }
-
- # determining target kind
- # e.g.
- # if is_kind "release"; then
- # ...
- # fi
- is_kind() {
- local kind=""
- for kind in $@; do
- if test_eq "${_target_kind}" "${kind}"; then
- return 0
- fi
- done
- return 1
- }
-
- # determining target toolchain
- # e.g.
- # if is_toolchain "clang"; then
- # ...
- # fi
- is_toolchain() {
- local toolchain=""
- for toolchain in $@; do
- if test_eq "${_target_toolchain}" "${toolchain}"; then
- return 0
- fi
- done
- return 1
- }
-
- #-----------------------------------------------------------------------------
- # project configuration apis
- #
-
- # set project name
- set_project() {
- _xmake_sh_project_name="${1}"
- }
-
- # include the given xmake.sh file or directory
- # e.g. includes "src" "tests"
- includes() {
- local path=""
- for path in $@; do
- if test -f "${path}"; then
- path_directory "${path}"; xmake_sh_scriptdir="${_ret}"
- . "${path}"
- else
- local xmake_sh_scriptdir_cur=${xmake_sh_scriptdir}
- if test "x${xmake_sh_scriptdir}" != "x"; then
- xmake_sh_scriptdir="${xmake_sh_scriptdir_cur}/${path}"
- . "${xmake_sh_scriptdir}/xmake.sh"
- else
- . "${xmake_sh_projectdir}/${path}/xmake.sh"
- fi
- xmake_sh_scriptdir=${xmake_sh_scriptdir_cur}
- fi
- done
- }
-
- #-----------------------------------------------------------------------------
- # some helper functions
- #
-
- # split flags
- _split_flags() {
- string_replace "${1}" ":" " "
- }
-
- # get abstract flag for gcc/clang
- _get_abstract_flag_for_gcc_clang() {
- local toolkind="${1}"
- local toolname="${2}"
- local itemname="${3}"
- local value="${4}"
- local flag=""
- case "${itemname}" in
- defines)
- string_replace "${value}" '"' '\\\"'; value="${_ret}"
- flag="-D${value}"
- ;;
- undefines) flag="-U${value}";;
- includedirs) flag="-I${value}";;
- linkdirs) flag="-L${value}";;
- links) flag="-l${value}";;
- syslinks) flag="-l${value}";;
- frameworks) flag="-framework ${value}";;
- frameworkdirs) flag="-F${value}";;
- rpathdirs)
- if is_plat "macosx"; then
- string_replace "${value}" "\$ORIGIN" "@loader_path"; value="${_ret}"
- flag="-Xlinker -rpath -Xlinker ${value}"
- else
- # escape $ORIGIN in makefile, TODO we need also handle it for ninja
- string_replace "${value}" "@loader_path" '$$ORIGIN'; value="${_ret}"
- if is_plat "bsd"; then
- flag="-Wl,-zorigin -Wl,-rpath='${value}'"
- else
- flag="-Wl,-rpath='${value}'"
- fi
- fi
- ;;
- symbols)
- if test_eq "${value}" "debug"; then
- flag="-g"
- elif test_eq "${value}" "hidden"; then
- flag="-fvisibility=hidden"
- fi
- ;;
- strip)
- if test_eq "${value}" "debug"; then
- flag="-Wl,-S"
- elif test_eq "${value}" "all"; then
- if is_plat "macosx"; then
- flag="-Wl,-x -Wl,-dead_strip"
- else
- flag="-s"
- fi
- fi
- ;;
- warnings)
- if test_eq "${value}" "all" || test_eq "${value}" "more" || test_eq "${value}" "less"; then
- flag="-Wall"
- elif test_eq "${value}" "allextra"; then
- flag="-Wall -Wextra"
- elif test_eq "${value}" "error"; then
- flag="-Werror"
- elif test_eq "${value}" "everything"; then
- flag="-Wall -Wextra"
- elif test_eq "${value}" "none"; then
- flag="-w"
- fi
- ;;
- optimizes)
- if test_eq "${value}" "fast"; then
- flag="-O1"
- elif test_eq "${value}" "faster"; then
- flag="-O2"
- elif test_eq "${value}" "fastest"; then
- flag="-O3"
- elif test_eq "${value}" "smallest"; then
- if test_eq "${toolname}" "clang" || test_eq "${toolname}" "clangxx"; then
- flag="-Oz"
- else
- flag="-Os"
- fi
- elif test_eq "${value}" "aggressive"; then
- flag="-Ofast"
- elif test_eq "${value}" "none"; then
- flag="-O0"
- fi
- ;;
- languages)
- if test_eq "${toolkind}" "cc" || test_eq "${toolkind}" "mm"; then
- case "${value}" in
- ansi) flag="-ansi";;
- c89) flag="-std=c89";;
- gnu89) flag="-std=gnu89";;
- c99) flag="-std=c99";;
- gnu99) flag="-std=gnu99";;
- c11) flag="-std=c11";;
- gnu11) flag="-std=gnu11";;
- c17) flag="-std=c17";;
- gnu17) flag="-std=gnu17";;
- esac
- elif test_eq "${toolkind}" "cxx" || test_eq "${toolkind}" "mxx"; then
- case "${value}" in
- cxx98) flag="-std=c++98";;
- c++98) flag="-std=c++98";;
- gnuxx98) flag="-std=gnu++98";;
- gnu++98) flag="-std=gnu++98";;
-
- cxx11) flag="-std=c++11";;
- c++11) flag="-std=c++11";;
- gnuxx11) flag="-std=gnu++11";;
- gnu++11) flag="-std=gnu++11";;
-
- cxx14) flag="-std=c++14";;
- c++14) flag="-std=c++14";;
- gnuxx14) flag="-std=gnu++14";;
- gnu++14) flag="-std=gnu++14";;
-
- cxx17) flag="-std=c++17";;
- c++17) flag="-std=c++17";;
- gnuxx17) flag="-std=gnu++17";;
- gnu++17) flag="-std=gnu++17";;
-
- cxx1z) flag="-std=c++1z";;
- c++1z) flag="-std=c++1z";;
- gnuxx1z) flag="-std=gnu++1z";;
- gnu++1z) flag="-std=gnu++1z";;
-
- cxx2a) flag="-std=c++2a";;
- c++2a) flag="-std=c++2a";;
- gnuxx2a) flag="-std=gnu++2a";;
- gnu++2a) flag="-std=gnu++2a";;
-
- cxx20) flag="-std=c++20";;
- c++20) flag="-std=c++20";;
- gnuxx20) flag="-std=gnu++20";;
- gnu++20) flag="-std=gnu++20";;
- cxx*) raise "unknown language value(${value})!" ;;
- c++*) raise "unknown language value(${value})!" ;;
- esac
- fi
- ;;
- *) raise "unknown itemname(${itemname})!" ;;
- esac
- _ret="${flag}"
- }
-
- # get abstract flags
- _get_abstract_flags() {
- local toolkind="${1}"
- local toolname="${2}"
- local itemname="${3}"
- local values="${4}"
- local flags=""
- local value=""
- for value in ${values}; do
- local flag=""
- case "${toolname}" in
- gcc) _get_abstract_flag_for_gcc_clang "${toolkind}" "${toolname}" "${itemname}" "${value}"; flag="${_ret}";;
- gxx) _get_abstract_flag_for_gcc_clang "${toolkind}" "${toolname}" "${itemname}" "${value}"; flag="${_ret}";;
- clang) _get_abstract_flag_for_gcc_clang "${toolkind}" "${toolname}" "${itemname}" "${value}"; flag="${_ret}";;
- clangxx) _get_abstract_flag_for_gcc_clang "${toolkind}" "${toolname}" "${itemname}" "${value}"; flag="${_ret}";;
- emcc) _get_abstract_flag_for_gcc_clang "${toolkind}" "${toolname}" "${itemname}" "${value}"; flag="${_ret}";;
- emxx) _get_abstract_flag_for_gcc_clang "${toolkind}" "${toolname}" "${itemname}" "${value}"; flag="${_ret}";;
- *) raise "unknown toolname(${toolname})!" ;;
- esac
- if test_nz "${flag}"; then
- flags="${flags} ${flag}"
- fi
- done
- _ret="${flags}"
- }
-
- #-----------------------------------------------------------------------------
- # option configuration apis
- #
-
- # define option
- option() {
- local name="${1}"
- local description="${2}"
- local default=${3}
- _xmake_sh_option_current="${name}"
- if ! ${_loading_options}; then
- if test_nz "${description}"; then
- _xmake_sh_option_current=""
- fi
- return
- fi
- if ! _map_has "options" "${name}_name"; then
- _xmake_sh_options="${_xmake_sh_options} ${name}"
- fi
- _map_set "options" "${name}_name" "${name}"
- _map_set "options" "${name}_description" "${description}"
- _map_set "options" "${name}_default" "${default}"
- # we end option if it's just one line
- if test_nz "${description}"; then
- _xmake_sh_option_current=""
- fi
- return 0
- }
- option_end() {
- _xmake_sh_option_current=""
- }
- _map "options"
-
- # has the given option?
- _has_option() {
- local name=${1}
- if _map_has "options" "${name}_name"; then
- return 0
- fi
- return 1
- }
-
- # get the given option item
- _get_option_item() {
- local name=${1}
- local key=${2}
- _map_get "options" "${name}_${key}"
- }
-
- # set the given option item
- _set_option_item() {
- local name=${1}
- local key=${2}
- shift
- shift
- if test_nz "${name}"; then
- _map_set "options" "${name}_${key}" "${@}"
- else
- raise "please call set_${key}(${@}) in the option scope!"
- fi
- }
-
- # add values to the given option item
- _add_option_item() {
- local name=${1}
- local key=${2}
- shift
- shift
- if test_nz "${name}"; then
- _map_get "options" "${name}_${key}"; local values="${_ret}"
- values="${values} ${@}"
- _map_set "options" "${name}_${key}" "${values}"
- else
- raise "please call add_${key}(${@}) in the option scope!"
- fi
- }
-
- # get the give option value
- _get_option_value() {
- local name=${1}
- _get_option_item "${name}" "value"
- if test "x${_ret}" = "x"; then
- _get_option_item "${name}" "default"
- fi
- }
-
- # set the give option value
- _set_option_value() {
- local name=${1}
- local value=${2}
- _set_option_item "${name}" "value" "${value}"
- }
-
- # this option need checking?
- _option_need_checking() {
- local name="${1}"
- _get_option_item "${name}" "default"; local default="${_ret}"
- if test_nz "${default}"; then
- return 1
- fi
- _get_option_item "${name}" "cfuncs"; local cfuncs="${_ret}"
- _get_option_item "${name}" "cxxfuncs"; local cxxfuncs="${_ret}"
- _get_option_item "${name}" "cincludes"; local cincludes="${_ret}"
- _get_option_item "${name}" "cxxincludes"; local cxxincludes="${_ret}"
- _get_option_item "${name}" "ctypes"; local ctypes="${_ret}"
- _get_option_item "${name}" "cxxtypes"; local cxxtypes="${_ret}"
- _get_option_item "${name}" "csnippets"; local csnippets="${_ret}"
- _get_option_item "${name}" "cxxsnippets"; local cxxsnippets="${_ret}"
- _get_option_item "${name}" "links"; local links="${_ret}"
- _get_option_item "${name}" "syslinks"; local syslinks="${_ret}"
- if test_nz "${cfuncs}" || test_nz "${cxxfuncs}" ||
- test_nz "${cincludes}" || test_nz "${cxxincludes}" ||
- test_nz "${ctypes}" || test_nz "${cxxtypes}" ||
- test_nz "${csnippets}" || test_nz "${cxxsnippets}" ||
- test_nz "${links}" || test_nz "${syslinks}"; then
- return 0
- fi
- return 1
- }
-
- # get options for the help menu
- _get_options_for_menu() {
- local options=""
- local name=""
- for name in ${_xmake_sh_options}; do
- _get_option_item "${name}" "showmenu"; local showmenu="${_ret}"
- if _is_enabled "${showmenu}"; then
- options="${options} ${name}"
- elif test_z "${showmenu}" && ! _option_need_checking "${name}"; then
- options="${options} ${name}"
- fi
- done
- _ret="${options}"
- }
-
- # get options for checking
- _get_options_for_checking() {
- local options=""
- local name=""
- for name in ${_xmake_sh_options}; do
- _get_option_item "${name}" "showmenu"; local showmenu="${_ret}"
- if test_z "${showmenu}" && _option_need_checking "${name}"; then
- options="${options} ${name}"
- fi
- done
- _ret="${options}"
- }
-
- # get abstract flags in option
- _get_option_abstract_flags() {
- local name="${1}"
- local toolkind="${2}"
- local toolname="${3}"
- local itemname="${4}"
- local values="${5}"
- if test_z "${values}"; then
- _get_option_item "${name}" "${itemname}"; values="${_ret}"
- fi
- _get_abstract_flags "${toolkind}" "${toolname}" "${itemname}" "${values}"
- }
-
- # is config for option
- is_config() {
- if ! ${_loading_targets}; then
- return 1
- fi
- local name=${1}
- local value=${2}
- _get_option_value "${name}"; local value_cur="${_ret}"
- if test_eq "${value_cur}" "${value}"; then
- return 0
- fi
- return 1
- }
-
- # has config for option
- has_config() {
- if ! ${_loading_targets}; then
- return 1
- fi
- local name=${1}
- _get_option_value "${name}"; local value_cur="${_ret}"
- if _is_enabled ${value_cur}; then
- return 0
- fi
- return 1
- }
-
- # set config for option, we can use it to modify option status when loading targets
- set_config() {
- local name=${1}
- local value=${2}
- _set_option_value "${name}" "${value}"
- }
-
- # set showmenu in option
- set_showmenu() {
- if ! ${_loading_options}; then
- return
- fi
- local show="${1}"
- _set_option_item "${_xmake_sh_option_current}" "showmenu" "${show}"
- }
-
- # set description in option
- set_description() {
- if ! ${_loading_options}; then
- return
- fi
- local description="${1}"
- _set_option_item "${_xmake_sh_option_current}" "description" "${description}"
- }
-
- # add cfuncs in option
- add_cfuncs() {
- if ! ${_loading_options}; then
- return
- fi
- _add_option_item "${_xmake_sh_option_current}" "cfuncs" "${@}"
- }
-
- # add cxxfuncs in option
- add_cxxfuncs() {
- if ! ${_loading_options}; then
- return
- fi
- _add_option_item "${_xmake_sh_option_current}" "cxxfuncs" "${@}"
- }
-
- # add cincludes in option
- add_cincludes() {
- if ! ${_loading_options}; then
- return
- fi
- _add_option_item "${_xmake_sh_option_current}" "cincludes" "${@}"
- }
-
- # add cxxincludes in option
- add_cxxincludes() {
- if ! ${_loading_options}; then
- return
- fi
- _add_option_item "${_xmake_sh_option_current}" "cxxincludes" "${@}"
- }
-
- # add ctypes in option
- add_ctypes() {
- if ! ${_loading_options}; then
- return
- fi
- _add_option_item "${_xmake_sh_option_current}" "ctypes" "${@}"
- }
-
- # add cxxtypes in option
- add_cxxtypes() {
- if ! ${_loading_options}; then
- return
- fi
- _add_option_item "${_xmake_sh_option_current}" "cxxtypes" "${@}"
- }
-
- # add csnippets in option
- add_csnippets() {
- if ! ${_loading_options}; then
- return
- fi
- local csnippets="${1}"
- _add_option_item "${_xmake_sh_option_current}" "csnippets" "${csnippets}"
- }
-
- # add cxxsnippets in option
- add_cxxsnippets() {
- if ! ${_loading_options}; then
- return
- fi
- local cxxsnippets="${1}"
- _add_option_item "${_xmake_sh_option_current}" "cxxsnippets" "${cxxsnippets}"
- }
-
- # before_check in option
- before_check() {
- if ! ${_loading_options}; then
- return
- fi
- local funcname="${1}"
- _add_option_item "${_xmake_sh_option_current}" "before_check" "${funcname}"
- }
-
- #-----------------------------------------------------------------------------
- # target configuration apis
- #
-
- # define target
- target() {
- local name="${1}"
- _xmake_sh_target_current="${name}"
- if ! ${_loading_targets}; then
- return
- fi
- if ! _map_has "targets" "${name}_name"; then
- _xmake_sh_targets="${_xmake_sh_targets} ${name}"
- fi
- _map_set "targets" "${name}_name" "${name}"
- return 0
- }
- target_end() {
- _xmake_sh_target_current=""
- }
- _map "targets"
-
- # has the given target?
- _has_target() {
- local name=${1}
- if _map_has "targets" "${name}_name"; then
- return 0
- fi
- return 1
- }
-
- # has the given target item
- _has_target_item() {
- local name=${1}
- local key=${2}
- if _map_has "targets" "${name}_${key}"; then
- return 0
- elif _map_has "targets" "__root_${key}"; then
- return 0
- fi
- return 1
- }
-
- # get the given target item
- _get_target_item() {
- local name=${1}
- local key=${2}
- _map_get "targets" "${name}_${key}"
- local values="${_ret}"
- if _map_has "targets" "__root_${key}"; then
- _map_get "targets" "__root_${key}"; local root_values="${_ret}"
- if test_nz "${values}"; then
- values="${root_values} ${values}"
- else
- values="${root_values}"
- fi
- fi
- _ret="${values}"
- }
-
- # set the given target item
- _set_target_item() {
- local name=${1}
- local key=${2}
- shift
- shift
- if test_nz "${name}"; then
- _map_set "targets" "${name}_${key}" "${@}"
- else
- _map_set "targets" "__root_${key}" "${@}"
- fi
- }
-
- # add values to the given target item
- _add_target_item() {
- local name=${1}
- local key=${2}
- shift
- shift
- if test_nz "${name}"; then
- _map_get "targets" "${name}_${key}"; local values="${_ret}"
- values="${values} ${@}"
- _map_set "targets" "${name}_${key}" "${values}"
- else
- _map_get "targets" "__root_${key}"; local values="${_ret}"
- values="${values} ${@}"
- _map_set "targets" "__root_${key}" "${values}"
- fi
- }
-
- # is default?
- _is_target_default() {
- local name="${1}"
- if _has_target_item "${name}" "default"; then
- _get_target_item "${target}" "default"; local default="${_ret}"
- if _is_enabled ${default}; then
- return 0
- fi
- return 1
- fi
- return 0
- }
-
- # get target basename
- _get_target_basename() {
- local name="${1}"
- _get_target_item "${name}" "basename"; local basename="${_ret}"
- if test_z "${basename}"; then
- basename="${name}"
- fi
- _ret="${basename}"
- }
-
- # get target extension
- _get_target_extension() {
- local name="${1}"
- local extension=""
- if _has_target_item "${name}" "extension"; then
- _get_target_item "${name}" "extension"; extension="${_ret}"
- elif is_plat "mingw"; then
- _get_target_item "${name}" "kind"; local kind="${_ret}"
- if test "x${kind}" = "xbinary"; then
- extension=".exe"
- elif test "x${kind}" = "xstatic"; then
- extension=".a"
- elif test "x${kind}" = "xshared"; then
- extension=".dll"
- fi
- else
- _get_target_item "${name}" "kind"; local kind="${_ret}"
- if test "x${kind}" = "xstatic"; then
- extension=".a"
- elif test "x${kind}" = "xshared"; then
- if is_plat "macosx"; then
- extension=".dylib"
- else
- extension=".so"
- fi
- fi
- fi
- _ret="${extension}"
- }
-
- # get target prefixname
- _get_target_prefixname() {
- local name="${1}"
- local prefixname=""
- if _has_target_item "${name}" "prefixname"; then
- _get_target_item "${name}" "prefixname"; prefixname="${_ret}"
- elif is_plat "mingw"; then
- _get_target_item "${name}" "kind"; local kind="${_ret}"
- if test "x${kind}" = "xstatic"; then
- prefixname="lib"
- elif test "x${kind}" = "xshared"; then
- prefixname="lib"
- fi
- else
- _get_target_item "${name}" "kind"; local kind="${_ret}"
- if test "x${kind}" = "xstatic"; then
- prefixname="lib"
- elif test "x${kind}" = "xshared"; then
- prefixname="lib"
- fi
- fi
- _ret="${prefixname}"
- }
-
- # get target filename
- _get_target_filename() {
- local name="${1}"
- _get_target_item "${name}" "filename"; local filename="${_ret}"
- if test_z "${filename}"; then
- _get_target_basename "${name}"; local basename="${_ret}"
- _get_target_extension "${name}"; local extension="${_ret}"
- _get_target_prefixname "${name}"; local prefixname="${_ret}"
- filename="${prefixname}${basename}${extension}"
- fi
- _ret="${filename}"
- }
-
- # get target soname
- # @see https://github.com/tboox/tbox/issues/214
- #
- # set_version "1.0.1" "" "1" -> libfoo.so.1, libfoo.1.dylib
- # set_version "1.0.1" "" "A" -> libfoo.so.A, libfoo.A.dylib
- _get_target_soname() {
- local soname=""
- local name="${1}"
- _get_target_item "${name}" "kind"; local targetkind="${_ret}"
- if test_eq "${targetkind}" "shared" && is_plat "macosx" "linux" "bsd"; then
- _get_target_item "${name}" "version"; local version="${_ret}"
- _get_target_item "${name}" "version_soname"; local version_soname="${_ret}"
- if test_nz "${version}" && test_nz "${version_soname}"; then
- _get_target_filename "${name}"; soname="${_ret}"
- _get_target_extension "${name}"; local extension="${_ret}"
- if test_eq "${extension}" ".dylib"; then
- path_basename "${soname}"; local basename="${_ret}"
- soname="${basename}.${version_soname}${extension}"
- else
- soname="${soname}.${version_soname}"
- fi
- fi
- fi
- _ret="${soname}"
- }
-
- # get target directory
- _get_targetdir() {
- local name="${1}"
- _get_target_item "${name}" "targetdir"; local targetdir="${_ret}"
- if test_z "${targetdir}"; then
- targetdir="${xmake_sh_buildir}/${_target_plat}/${_target_arch}/${_target_mode}"
- fi
- _ret="${targetdir}"
- }
-
- # get target object directory
- _get_target_objectdir() {
- local name="${1}"
- _get_target_item "${name}" "objectdir"; local objectdir="${_ret}"
- if test_z "${objectdir}"; then
- objectdir="${xmake_sh_buildir}/.objs/${name}/${_target_plat}/${_target_arch}/${_target_mode}"
- fi
- _ret="${objectdir}"
- }
-
- # get target file path
- _get_target_file() {
- local name="${1}"
- _get_target_filename "${name}"; local filename="${_ret}"
- _get_targetdir "${name}"; local targetdir="${_ret}"
- local targetfile="${targetdir}/${filename}"
- _ret="${targetfile}"
- }
-
- # get target librarydeps
- _get_target_librarydeps_impl() {
- local name="${1}"
- local librarydeps=""
- local dep=""
- _get_target_item "${name}" "deps"; local deps="${_ret}"
- for dep in ${deps}; do
- _get_target_item "${dep}" "kind"; local dep_kind="${_ret}"
- if test_eq "${dep_kind}" "static" || test_eq "${dep_kind}" "shared"; then
- librarydeps="${librarydeps} ${dep}"
- _get_target_librarydeps_impl "${dep}"; local dep_librarydeps="${_ret}"
- if test_nz "${dep_librarydeps}"; then
- librarydeps="${librarydeps} ${dep_librarydeps}"
- fi
- fi
- done
- _ret="${librarydeps}"
- }
-
- _get_target_librarydeps() {
- local name="${1}"
- _get_target_item "${name}" "librarydeps"; local librarydeps="${_ret}"
- if test_z "${librarydeps}" && test_nq "${librarydeps}" "__none__"; then
- _get_target_librarydeps_impl "${name}"; librarydeps="${_ret}"
- if test_nz "${librarydeps}"; then
- _dedup_reverse "${librarydeps}"; librarydeps="${_ret}"
- _set_target_item "${name}" "librarydeps" "${librarydeps}"
- else
- _set_target_item "${name}" "librarydeps" "__none__"
- fi
- fi
- if test_eq "${librarydeps}" "__none__"; then
- librarydeps=""
- fi
- _ret="${librarydeps}"
- }
-
- # get sourcefiles in target
- _get_target_sourcefiles() {
- local name="${1}"
- _get_target_item "${name}" "files"
- }
-
- # get objectfile in target
- _get_target_objectfile() {
- local name="${1}"
- local sourcefile="${2}"
- local extension=".o"
- if is_plat "mingw"; then
- extension=".obj"
- fi
- _get_target_objectdir "${name}"; local objectdir="${_ret}"
- local objectfile="${objectdir}/${sourcefile}${extension}"
- _ret="${objectfile}"
- }
-
- # get objectfiles in target
- _get_target_objectfiles() {
- local name="${1}"
- _get_target_sourcefiles "${name}"; local sourcefiles="${_ret}"
- local objectfiles=""
- local sourcefile=""
- for sourcefile in ${sourcefiles}; do
- _get_target_objectfile "${name}" "${sourcefile}"; local objectfile="${_ret}"
- objectfiles="${objectfiles} ${objectfile}"
- done
- _ret="${objectfiles}"
- }
-
- # get abstract flags in target
- _get_target_abstract_flags() {
- local name="${1}"
- local toolkind="${2}"
- local toolname="${3}"
- local itemname="${4}"
- local values="${5}"
- if test_z "${values}"; then
-
- # get values from target
- _get_target_item "${name}" "${itemname}"; values="${_ret}"
-
- # get values from target deps
- _get_target_librarydeps "${name}"; local deps="${_ret}"
- local dep=""
- for dep in ${deps}; do
- _get_target_item "${dep}" "kind"; local dep_kind="${_ret}"
- if test_eq "${dep_kind}" "static" || test_eq "${dep_kind}" "shared"; then
- _get_target_item "${dep}" "${itemname}_public"; local depvalues="${_ret}"
- if test_nz "${depvalues}"; then
- values="${values} ${depvalues}"
- fi
- fi
- done
- fi
- if test_nz "${values}"; then
- _get_abstract_flags "${toolkind}" "${toolname}" "${itemname}" "${values}"
- else
- _ret=""
- fi
- }
-
- # get toolchain flags for ar in target
- _get_target_toolchain_flags_for_ar() {
- _ret="-cr"
- }
-
- # get toolchain flags for gcc in target
- _get_target_toolchain_flags_for_gcc() {
- local name="${1}"
- local toolkind="${2}"
- local flags=""
- if is_arch "i386"; then
- flags="${flags} -m32"
- fi
- _get_target_item "${name}" "kind"; local targetkind="${_ret}"
- if test_eq "${targetkind}" "shared"; then
- if test_eq "${toolkind}" "sh"; then
- flags="${flags} -shared -fPIC"
- elif test_eq "${toolkind}" "cc" || test_eq "${toolkind}" "cxx"; then
- flags="${flags} -fPIC"
- fi
- # @see https://github.com/tboox/tbox/issues/214
- if test_eq "${toolkind}" "sh"; then
- _get_target_soname "${name}"; local soname="${_ret}"
- if test_nz "${soname}"; then
- if is_plat "macosx"; then
- flags="${flags} -Wl,-install_name,${soname}"
- else
- flags="${flags} -Wl,-soname,${soname}"
- fi
- fi
- fi
- fi
- _ret="${flags}"
- }
-
- # get toolchain flags for clang in target
- _get_target_toolchain_flags_for_clang() {
- local name="${1}"
- local toolkind="${2}"
- local flags="-Qunused-arguments"
- if is_arch "i386"; then
- flags="${flags} -m32"
- fi
- _get_target_item "${name}" "kind"; local targetkind="${_ret}"
- if test_eq "${targetkind}" "shared"; then
- if test_eq "${toolkind}" "sh"; then
- flags="${flags} -shared -fPIC"
- elif test_eq "${toolkind}" "cc" || test_eq "${toolkind}" "cxx"; then
- flags="${flags} -fPIC"
- fi
- # @see https://github.com/tboox/tbox/issues/214
- if test_eq "${toolkind}" "sh"; then
- _get_target_soname "${name}"; local soname="${_ret}"
- if test_nz "${soname}"; then
- if is_plat "macosx"; then
- flags="${flags} -Wl,-install_name,${soname}"
- else
- flags="${flags} -Wl,-soname,${soname}"
- fi
- fi
- fi
- fi
- if is_plat "macosx"; then
- _os_iorunv "xcrun" "-sdk" "macosx" "--show-sdk-path"; local sdkdir="${_ret}"
- if test_nz "${sdkdir}"; then
- flags="${flags} -isysroot \"${sdkdir}\""
- fi
- fi
- _ret="${flags}"
- }
-
- # get toolchain flags in target
- _get_target_toolchain_flags() {
- local name="${1}"
- local toolkind="${2}"
- local toolname="${3}"
- local flags=""
- case "${toolname}" in
- gcc) _get_target_toolchain_flags_for_gcc "${name}" "${toolkind}"; flags="${_ret}";;
- gxx) _get_target_toolchain_flags_for_gcc "${name}" "${toolkind}"; flags="${_ret}";;
- clang) _get_target_toolchain_flags_for_clang "${name}" "${toolkind}"; flags="${_ret}";;
- clangxx) _get_target_toolchain_flags_for_clang "${name}" "${toolkind}"; flags="${_ret}";;
- emcc) _get_target_toolchain_flags_for_clang "${name}" "${toolkind}"; flags="${_ret}";;
- emxx) _get_target_toolchain_flags_for_clang "${name}" "${toolkind}"; flags="${_ret}";;
- ar) _get_target_toolchain_flags_for_ar "${name}" "${toolkind}"; flags="${_ret}";;
- emar) _get_target_toolchain_flags_for_ar "${name}" "${toolkind}"; flags="${_ret}";;
- *) raise "unknown toolname(${toolname})!" ;;
- esac
- _ret="${flags}"
- }
-
- # get compiler flags in target
- _get_target_compiler_flags() {
- local name="${1}"
- local toolkind="${2}"
- _get_toolchain_toolset "${_target_toolchain}" "${toolkind}"; local program="${_ret}"
- path_toolname "${program}"; local toolname="${_ret}"
- local result=""
-
- # get toolchain flags
- _get_target_toolchain_flags "${name}" "${toolkind}" "${toolname}"; local toolchain_flags="${_ret}"
- if test_nz "${toolchain_flags}"; then
- result="${result} ${toolchain_flags}"
- fi
-
- # get abstract flags
- local itemnames="symbols optimizes warnings languages defines undefines includedirs frameworkdirs frameworks"
- local itemname=""
- for itemname in ${itemnames}; do
- _get_target_abstract_flags "${name}" "${toolkind}" "${toolname}" "${itemname}"; local flags="${_ret}"
- if test_nz "${flags}"; then
- result="${result} ${flags}"
- fi
- done
-
- # get raw flags, e.g. add_cflags, add_cxxflags
- _get_flagname "${toolkind}"; local flagname="${_ret}"
- _get_target_item "${name}" "${flagname}"; local flags="${_ret}"
- # get flags from target deps
- _get_target_librarydeps "${name}"; local deps="${_ret}"
- local dep=""
- for dep in ${deps}; do
- _get_target_item "${dep}" "kind"; local dep_kind="${_ret}"
- if test_eq "${dep_kind}" "static" || test_eq "${dep_kind}" "shared"; then
- _get_target_item "${dep}" "${flagname}_public"; local depflags="${_ret}"
- if test_nz "${depflags}"; then
- flags="${flags} ${depflags}"
- fi
- fi
- done
- if test_nz "${flags}"; then
- result="${result} ${flags}"
- fi
- if test_eq "${flagname}" "cflags" || test_eq "${flagname}" "cxxflags"; then
- _get_target_item "${name}" "cxflags"; flags="${_ret}"
- if test_nz "${flags}"; then
- result="${result} ${flags}"
- fi
- elif test_eq "${flagname}" "mflags" || test_eq "${flagname}" "mxxflags"; then
- _get_target_item "${name}" "mxflags"; flags="${_ret}"
- if test_nz "${flags}"; then
- result="${result} ${flags}"
- fi
- fi
-
- # get flags from environments, e.g. $CFLAGS, $CXXFLAGS
- if test_nz "${CPPFLAGS}"; then
- result="${result} ${CPPFLAGS}"
- fi
- if test_eq "${flagname}" "cflags" && test_nz "${CFLAGS}"; then
- result="${result} ${CFLAGS}"
- fi
- if test_eq "${flagname}" "cxxflags" && test_nz "${CXXFLAGS}"; then
- result="${result} ${CXXFLAGS}"
- fi
- if test_eq "${flagname}" "mflags" && test_nz "${MFLAGS}"; then
- result="${result} ${MFLAGS}"
- fi
- if test_eq "${flagname}" "mxxflags" && test_nz "${MXXFLAGS}"; then
- result="${result} ${MXXFLAGS}"
- fi
- _ret="${result}"
- }
-
- # get linker flags in target
- _get_target_linker_flags() {
- local name="${1}"
- local toolkind="${2}"
- _get_toolchain_toolset "${_target_toolchain}" "${toolkind}"; local program="${_ret}"
- path_toolname "${program}"; local toolname="${_ret}"
- local result=""
-
- # get toolchain flags
- _get_target_toolchain_flags "${name}" "${toolkind}" "${toolname}"; local toolchain_flags="${_ret}"
- if test_nz "${toolchain_flags}"; then
- result="${result} ${toolchain_flags}"
- fi
-
- # get flags from target deps
- _get_target_librarydeps "${name}"; local deps="${_ret}"
- local dep=""
- for dep in ${deps}; do
- _get_target_item "${dep}" "kind"; local dep_kind="${_ret}"
- if test_eq "${dep_kind}" "static" || test_eq "${dep_kind}" "shared"; then
- _get_targetdir "${dep}"; local dep_targetdir="${_ret}"
- _get_target_basename "${dep}"; local dep_basename="${_ret}"
- _get_target_abstract_flags "${dep}" "${toolkind}" "${toolname}" "linkdirs" "${dep_targetdir}"; local linkdirs_flags="${_ret}"
- _get_target_abstract_flags "${dep}" "${toolkind}" "${toolname}" "links" "${dep_basename}"; local links_flags="${_ret}"
- if test_eq "${dep_kind}" "shared"; then
- local rpathdir="@loader_path"
- _get_targetdir "${name}"; local targetdir="${_ret}"
- path_relative "${targetdir}" "${dep_targetdir}"; local subdir="${_ret}"
- if test_nz "${subdir}"; then
- rpathdir="${rpathdir}/${subdir}"
- fi
- _get_target_abstract_flags "${dep}" "${toolkind}" "${toolname}" "rpathdirs" "${rpathdir}"; local rpathdirs_flags="${_ret}"
- result="${result} ${rpathdirs_flags}"
- fi
- result="${result} ${linkdirs_flags} ${links_flags}"
- fi
- done
-
- # get abstract flags
- local itemnames="strip frameworkdirs linkdirs links rpathdirs frameworks syslinks"
- local itemname=""
- for itemname in ${itemnames}; do
- _get_target_abstract_flags "${name}" "${toolkind}" "${toolname}" "${itemname}"; local flags="${_ret}"
- if test_nz "${flags}"; then
- result="${result} ${flags}"
- fi
- done
-
- # get raw flags, e.g. add_ldflags, add_shflags
- _get_flagname "${toolkind}"; local flagname="${_ret}"
- _get_target_item "${name}" "${flagname}"; local flags="${_ret}"
- # get flags from target deps
- for dep in ${deps}; do
- _get_target_item "${dep}" "kind"; local dep_kind="${_ret}"
- if test_eq "${dep_kind}" "static" || test_eq "${dep_kind}" "shared"; then
- _get_target_item "${dep}" "${flagname}_public"; local depflags="${_ret}"
- if test_nz "${depflags}"; then
- flags="${flags} ${depflags}"
- fi
- fi
- done
- if test_nz "${flags}"; then
- result="${result} ${flags}"
- fi
-
- # get flags from environments, e.g. $LDFLAGS
- if test_eq "${flagname}" "ldflags" && test_nz "${LDFLAGS}"; then
- result="${result} ${LDFLAGS}"
- fi
- if test_eq "${flagname}" "shflags" && test_nz "${LDFLAGS}"; then
- result="${result} ${LDFLAGS}"
- fi
- _ret="${result}"
- }
-
- # get archiver flags in target
- _get_target_archiver_flags() {
- local name="${1}"
- local toolkind="${2}"
- _get_toolchain_toolset "${_target_toolchain}" "${toolkind}"; local program="${_ret}"
- path_toolname "${program}"; local toolname="${_ret}"
- local result=""
-
- # get toolchain flags
- _get_target_toolchain_flags "${name}" "${toolkind}" "${toolname}"; local toolchain_flags="${_ret}"
- if test_nz "${toolchain_flags}"; then
- result="${result} ${toolchain_flags}"
- fi
-
- # get raw flags, e.g. add_arflags
- _get_flagname "${toolkind}"; local flagname="${_ret}"
- _get_target_item "${name}" "${flagname}"; local flags="${_ret}"
- if test_nz "${flags}"; then
- result="${result} ${flags}"
- fi
-
- _ret="${result}"
- }
-
- # get target flags
- _get_target_flags() {
- local name="${1}"
- local toolkind="${2}"
- local flags=""
- if test_eq "${toolkind}" "sh"; then
- _get_target_linker_flags "${name}" "${toolkind}"; flags="${_ret}"
- elif test_eq "${toolkind}" "ld"; then
- _get_target_linker_flags "${name}" "${toolkind}"; flags="${_ret}"
- elif test_eq "${toolkind}" "ar"; then
- _get_target_archiver_flags "${name}" "${toolkind}"; flags="${_ret}"
- else
- _get_target_compiler_flags "${name}" "${toolkind}"; flags="${_ret}"
- fi
- _ret="${flags}"
- }
-
- # add file paths in target
- _add_target_filepaths() {
- local key="$1"
- shift
- # we need avoid escape `*` automatically in for-loop
- local file=""
- string_replace "${@}" "\*" "?"; local list="${_ret}"
- if test_eq "${key}" "files"; then
- for file in ${list}; do
- path_sourcekind "${file}"; local sourcekind="${_ret}"
- _targets_toolkinds="${_targets_toolkinds} ${sourcekind}"
- done
- fi
- for file in ${list}; do
- string_replace "${file}" "?" "*"; file="${_ret}"
- if ! path_is_absolute "${file}"; then
- file="${xmake_sh_scriptdir}/${file}"
- fi
- local files=""
- if string_contains_star2 "${file}"; then
- path_directory "${file}"; local dir="${_ret}"
- path_filename_fromdir "${file}" "${dir}"; local name="${_ret}"
- _os_find "${dir}" "${name}"; files="${_ret}"
- elif string_contains_star "${file}"; then
- path_directory "${file}"; local dir="${_ret}"
- path_filename_fromdir "${file}" "${dir}"; local name="${_ret}"
- _os_find "${dir}" "${name}" 1; files="${_ret}"
- else
- files="${file}"
- fi
- for file in ${files}; do
- path_relative "${xmake_sh_projectdir}" "${file}"; file="${_ret}"
- _add_target_item "${_xmake_sh_target_current}" "${key}" "${file}"
- done
- done
- }
-
- # add install paths in target
- _add_target_installpaths() {
- local key="$1"
- local filepattern="${2}"
- local prefixdir="${3}"
- local filename=${4}
-
- # get root directory, e.g. "src/foo/(*.h)" -> "src/foo"
- local rootdir=""
- if string_contains "${filepattern}" "("; then
- string_split "${filepattern}" "(" 1; rootdir="${_ret}"
- rootdir=${rootdir%/}
- if ! path_is_absolute "${rootdir}"; then
- rootdir="${xmake_sh_scriptdir}/${rootdir}"
- fi
- path_relative "${xmake_sh_projectdir}" "${rootdir}"; rootdir="${_ret}"
- rootdir=${rootdir%/}
- fi
-
- # remove (), e.g. "src/(*.h)" -> "src/*.h"
- string_replace ${filepattern} "(" ""; filepattern="${_ret}"
- string_replace ${filepattern} ")" ""; filepattern="${_ret}"
-
- # get real path
- if ! path_is_absolute "${filepattern}"; then
- filepattern="${xmake_sh_scriptdir}/${filepattern}"
- fi
- local files=""
- if string_contains_star2 "${filepattern}"; then
- path_directory "${filepattern}"; local dir="${_ret}"
- path_filename_fromdir "${filepattern}" "${dir}"; local name="${_ret}"
- _os_find "${dir}" "${name}"; files="${_ret}"
- elif string_contains_star "${filepattern}"; then
- path_directory "${filepattern}"; local dir="${_ret}"
- path_filename_fromdir "${filepattern}" "${dir}"; local name="${_ret}"
- _os_find "${dir}" "${name}" 1; files="${_ret}"
- else
- files="${filepattern}"
- fi
- for file in ${files}; do
- path_relative "${xmake_sh_projectdir}" "${file}"; file="${_ret}"
- _add_target_item "${_xmake_sh_target_current}" "${key}" "${file}:${rootdir}:${prefixdir}:${filename}"
- done
- }
-
- # set target file path
- _set_target_filepath() {
- local key="${1}"
- local path="${2}"
- if ! path_is_absolute "${path}"; then
- path="${xmake_sh_scriptdir}/${path}"
- fi
- path_relative ${xmake_sh_projectdir} "${path}"; path="${_ret}"
- _set_target_item "${_xmake_sh_target_current}" "${key}" "${path}"
- }
-
- # set kind in target
- set_kind() {
- if ! ${_loading_targets}; then
- return
- fi
- local kind=${1}
- _set_target_item "${_xmake_sh_target_current}" "kind" "${kind}"
- case "${kind}" in
- binary) _targets_toolkinds="${_targets_toolkinds} ld";;
- static) _targets_toolkinds="${_targets_toolkinds} ar";;
- shared) _targets_toolkinds="${_targets_toolkinds} sh";;
- *) raise "unknown target kind ${kind}";;
- esac
- }
-
- # set version in target
- set_version() {
- if ! ${_loading_targets}; then
- return
- fi
- local version="${1}"
- local version_build="${2}"
- local version_soname="${3}"
- _set_target_item "${_xmake_sh_target_current}" "version" "${version}"
- _set_target_item "${_xmake_sh_target_current}" "version_build" "${version_build}"
- _set_target_item "${_xmake_sh_target_current}" "version_soname" "${version_soname}"
- }
-
- # set default in target
- set_default() {
- local default=${1}
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _set_target_item "${_xmake_sh_target_current}" "default" "${default}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _set_option_item "${_xmake_sh_option_current}" "default" "${default}"
- fi
- }
-
- # set configvar in target
- set_configvar() {
- if ! ${_loading_targets}; then
- return
- fi
- local name="${1}"
- local value="${2}"
- _set_target_item "${_xmake_sh_target_current}" "configvar_${name}" "${value}"
- _add_target_item "${_xmake_sh_target_current}" "configvars" "${name}"
- }
-
- # set filename in target
- set_filename() {
- if ! ${_loading_targets}; then
- return
- fi
- local filename="${1}"
- _set_target_item "${_xmake_sh_target_current}" "filename" "${filename}"
- }
-
- # set basename in target
- set_basename() {
- if ! ${_loading_targets}; then
- return
- fi
- local basename="${1}"
- _set_target_item "${_xmake_sh_target_current}" "basename" "${basename}"
- }
-
- # set extension in target
- set_extension() {
- if ! ${_loading_targets}; then
- return
- fi
- local extension=${1}
- _set_target_item "${_xmake_sh_target_current}" "extension" "${extension}"
- }
-
- # set prefixname in target
- set_prefixname() {
- if ! ${_loading_targets}; then
- return
- fi
- local prefixname=${1}
- _set_target_item "${_xmake_sh_target_current}" "prefixname" "${prefixname}"
- }
-
- # set target directory
- set_targetdir() {
- if ! ${_loading_targets}; then
- return
- fi
- _set_target_filepath "targetdir" "${1}"
- }
-
- # set target object directory
- set_objectdir() {
- if ! ${_loading_targets}; then
- return
- fi
- _set_target_filepath "objectdir" "${1}"
- }
-
- # set target config directory
- set_configdir() {
- if ! ${_loading_targets}; then
- return
- fi
- _set_target_filepath "configdir" "${1}"
- }
-
- # set target install directory
- set_installdir() {
- if ! ${_loading_targets}; then
- return
- fi
- _set_target_filepath "installdir" "${1}"
- }
-
- # add deps in target
- add_deps() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_item "${_xmake_sh_target_current}" "deps" "${@}"
- }
-
- # add files in target
- add_files() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_filepaths "files" "$@"
- }
-
- # add install files in target
- add_installfiles() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_installpaths "installfiles" "$@"
- }
-
- # add header files in target
- add_headerfiles() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_installpaths "headerfiles" "$@"
- }
-
- # add config files in target
- add_configfiles() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_filepaths "configfiles" "$@"
- }
-
- # add defines in target
- add_defines() {
- local define=""
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- local public=false
- for define in $@; do
- if test_nq "${define}" "{public}"; then
- _add_target_item "${_xmake_sh_target_current}" "defines" "${define}"
- else
- public=true
- fi
- done
- if ${public}; then
- for define in $@; do
- if test_nq "${define}" "{public}"; then
- _add_target_item "${_xmake_sh_target_current}" "defines_public" "${define}"
- fi
- done
- fi
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "defines" "${@}"
- fi
- }
-
- # add undefines in target
- add_undefines() {
- local undefine=""
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- local public=false
- for undefine in $@; do
- if test_nq "${undefine}" "{public}"; then
- _add_target_item "${_xmake_sh_target_current}" "undefines" "${undefine}"
- else
- public=true
- fi
- done
- if ${public}; then
- for undefine in $@; do
- if test_nq "${undefine}" "{public}"; then
- _add_target_item "${_xmake_sh_target_current}" "undefines_public" "${undefine}"
- fi
- done
- fi
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "undefines" "${@}"
- fi
- }
-
- # add includedirs in target
- add_includedirs() {
- local public=false
- local dir=""
- for dir in $@; do
- if test_nq "${dir}" "{public}"; then
- if ! path_is_absolute "${dir}"; then
- dir="${xmake_sh_scriptdir}/${dir}"
- fi
- if string_startswith "${dir}" "${xmake_sh_projectdir}"; then
- path_relative ${xmake_sh_projectdir} "${dir}"; dir="${_ret}"
- fi
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _add_target_item "${_xmake_sh_target_current}" "includedirs" "${dir}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "includedirs" "${dir}"
- fi
- else
- public=true
- fi
- done
- if ${public}; then
- for dir in $@; do
- if test_nq "${dir}" "{public}"; then
- if ! path_is_absolute "${dir}"; then
- dir="${xmake_sh_scriptdir}/${dir}"
- fi
- if string_startswith "${dir}" "${xmake_sh_projectdir}"; then
- path_relative ${xmake_sh_projectdir} "${dir}"; dir="${_ret}"
- fi
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _add_target_item "${_xmake_sh_target_current}" "includedirs_public" "${dir}"
- fi
- fi
- done
- fi
- }
-
- # add links in target
- add_links() {
- local link=""
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- local public=false
- for link in $@; do
- if test_nq "${link}" "{public}"; then
- _add_target_item "${_xmake_sh_target_current}" "links" "${link}"
- else
- public=true
- fi
- done
- if ${public}; then
- for link in $@; do
- if test_nq "${link}" "{public}"; then
- _add_target_item "${_xmake_sh_target_current}" "links_public" "${link}"
- fi
- done
- fi
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "links" "${@}"
- fi
- }
-
- # add syslinks in target
- add_syslinks() {
- local syslink=""
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- local public=false
- for syslink in $@; do
- if test_nq "${syslink}" "{public}"; then
- _add_target_item "${_xmake_sh_target_current}" "syslinks" "${syslink}"
- else
- public=true
- fi
- done
- if ${public}; then
- for syslink in $@; do
- if test_nq "${syslink}" "{public}"; then
- _add_target_item "${_xmake_sh_target_current}" "syslinks_public" "${syslink}"
- fi
- done
- fi
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "syslinks" "${@}"
- fi
- }
-
- # add linkdirs in target
- add_linkdirs() {
- local dir=""
- local public=false
- for dir in $@; do
- if test_nq "${dir}" "{public}"; then
- if ! path_is_absolute "${dir}"; then
- dir="${xmake_sh_scriptdir}/${dir}"
- fi
- if string_startswith "${dir}" "${xmake_sh_projectdir}"; then
- path_relative ${xmake_sh_projectdir} "${dir}"; dir="${_ret}"
- fi
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _add_target_item "${_xmake_sh_target_current}" "linkdirs" "${dir}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "linkdirs" "${dir}"
- fi
- else
- public=true
- fi
- done
- if ${public}; then
- for dir in $@; do
- if test_nq "${dir}" "{public}"; then
- if ! path_is_absolute "${dir}"; then
- dir="${xmake_sh_scriptdir}/${dir}"
- fi
- if string_startswith "${dir}" "${xmake_sh_projectdir}"; then
- path_relative ${xmake_sh_projectdir} "${dir}"; dir="${_ret}"
- fi
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _add_target_item "${_xmake_sh_target_current}" "linkdirs_public" "${dir}"
- fi
- fi
- done
- fi
- }
-
- # add rpathdirs in target
- add_rpathdirs() {
- if ! ${_loading_targets}; then
- return
- fi
- local dir=""
- for dir in $@; do
- if ! path_is_absolute "${dir}"; then
- dir="${xmake_sh_scriptdir}/${dir}"
- fi
- path_relative ${xmake_sh_projectdir} "${dir}"; dir="${_ret}"
- _add_target_item "${_xmake_sh_target_current}" "rpathdirs" "${dir}"
- done
- }
-
- # add frameworks in target
- add_frameworks() {
- local framework=""
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- local public=false
- for framework in $@; do
- if test_nq "${framework}" "{public}"; then
- _add_target_item "${_xmake_sh_target_current}" "frameworks" "${framework}"
- else
- public=true
- fi
- done
- if ${public}; then
- for framework in $@; do
- if test_nq "${framework}" "{public}"; then
- _add_target_item "${_xmake_sh_target_current}" "frameworks_public" "${framework}"
- fi
- done
- fi
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "frameworks" "${@}"
- fi
- }
-
- # add frameworkdirs in target
- add_frameworkdirs() {
- local dir=""
- for dir in $@; do
- if ! path_is_absolute "${dir}"; then
- dir="${xmake_sh_scriptdir}/${dir}"
- fi
- path_relative ${xmake_sh_projectdir} "${dir}"; dir="${_ret}"
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _add_target_item "${_xmake_sh_target_current}" "frameworkdirs" "${dir}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "frameworkdirs" "${dir}"
- fi
- done
- }
-
- # set strip in target
- set_strip() {
- if ! ${_loading_targets}; then
- return
- fi
- local strip=${1}
- _set_target_item "${_xmake_sh_target_current}" "strip" "${strip}"
- }
-
- # set symbols in target
- set_symbols() {
- if ! ${_loading_targets}; then
- return
- fi
- local symbols="${1}"
- _set_target_item "${_xmake_sh_target_current}" "symbols" "${symbols}"
- }
-
- # set languages in target
- set_languages() {
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _set_target_item "${_xmake_sh_target_current}" "languages" "${@}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _set_option_item "${_xmake_sh_option_current}" "languages" "${@}"
- fi
- }
-
- # set warnings in target
- set_warnings() {
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _set_target_item "${_xmake_sh_target_current}" "warnings" "${@}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _set_option_item "${_xmake_sh_option_current}" "warnings" "${@}"
- fi
- }
-
- # set optimizes in target
- set_optimizes() {
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _set_target_item "${_xmake_sh_target_current}" "optimizes" "${@}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _set_option_item "${_xmake_sh_option_current}" "optimizes" "${@}"
- fi
- }
-
- # add cflags in target
- add_cflags() {
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _add_target_item "${_xmake_sh_target_current}" "cflags" "${@}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "cflags" "${@}"
- fi
- }
-
- # add cxflags in target
- add_cxflags() {
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _add_target_item "${_xmake_sh_target_current}" "cxflags" "${@}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "cxflags" "${@}"
- fi
- }
-
- # add cxxflags in target
- add_cxxflags() {
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _add_target_item "${_xmake_sh_target_current}" "cxxflags" "${@}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "cxxflags" "${@}"
- fi
- }
-
- # add asflags in target
- add_asflags() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_item "${_xmake_sh_target_current}" "asflags" "${@}"
- }
-
- # add mflags in target
- add_mflags() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_item "${_xmake_sh_target_current}" "mflags" "${@}"
- }
-
- # add mxflags in target
- add_mxflags() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_item "${_xmake_sh_target_current}" "mxflags" "${@}"
- }
-
- # add mxxflags in target
- add_mxxflags() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_item "${_xmake_sh_target_current}" "mxxflags" "${@}"
- }
-
- # add ldflags in target
- add_ldflags() {
- if ${_loading_targets} && test_z "${_xmake_sh_option_current}"; then
- _add_target_item "${_xmake_sh_target_current}" "ldflags" "${@}"
- elif ${_loading_options} && test_nz "${_xmake_sh_option_current}"; then
- _add_option_item "${_xmake_sh_option_current}" "ldflags" "${@}"
- fi
- }
-
- # add shflags in target
- add_shflags() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_item "${_xmake_sh_target_current}" "shflags" "${@}"
- }
-
- # add arflags in target
- add_arflags() {
- if ! ${_loading_targets}; then
- return
- fi
- _add_target_item "${_xmake_sh_target_current}" "arflags" "${@}"
- }
-
- # add options in target
- add_options() {
- if ! ${_loading_targets}; then
- return
- fi
- local name=""
- local public=false
- for name in $@; do
- if test_nq "${name}" "{public}"; then
- public=true
- break
- fi
- done
- for name in $@; do
- if has_config "${name}"; then
- local itemname=""
- local itemnames="includedirs linkdirs links defines cflags cxflags cxxflags ldflags"
- for itemname in ${itemnames}; do
- _get_option_item "${name}" "${itemname}"; local values="${_ret}"
- if test_nz "${values}"; then
- _add_target_item "${_xmake_sh_target_current}" "${itemname}" "${values}"
- if $public; then
- _add_target_item "${_xmake_sh_target_current}" "${itemname}_public" "${values}"
- fi
- fi
- done
- fi
- done
- }
-
- # before_install in target
- before_install() {
- if ! ${_loading_targets}; then
- return
- fi
- local funcname="${1}"
- _add_target_item "${_xmake_sh_target_current}" "before_install" "${funcname}"
- }
-
- # after_install in target
- after_install() {
- if ! ${_loading_targets}; then
- return
- fi
- local funcname="${1}"
- _add_target_item "${_xmake_sh_target_current}" "after_install" "${funcname}"
- }
-
- #-----------------------------------------------------------------------------
- # toolchain configuration apis
- #
-
- # define toolchain
- toolchain() {
- local name="${1}"
- _xmake_sh_toolchain_current="${name}"
- if ! ${_loading_toolchains}; then
- return
- fi
- _xmake_sh_toolchains="${_xmake_sh_toolchains} ${name}"
- _map_set "toolchains" "${name}_name" "${name}"
- return 0
- }
- toolchain_end() {
- _xmake_sh_toolchain_current=""
- }
- _map "toolchains"
-
- # has the given toolchain?
- _has_toolchain() {
- local name=${1}
- if _map_has "toolchains" "${name}_name"; then
- return 0
- fi
- return 1
- }
-
- # get the given toolchain item
- _get_toolchain_item() {
- local name=${1}
- local key=${2}
- _map_get "toolchains" "${name}_${key}"
- }
-
- # set the given toolchain item
- _set_toolchain_item() {
- local name=${1}
- local key=${2}
- local value=${3}
- if test_nz "${name}"; then
- _map_set "toolchains" "${name}_${key}" "${value}"
- else
- raise "please set toolchain in the toolchain scope!"
- fi
- }
-
- # get the give toolchain toolset
- _get_toolchain_toolset() {
- local name=${1}
- local kind=${2}
- _get_toolchain_item "${name}" "toolset_${kind}"
- }
-
- # set the give toolchain toolset
- _set_toolchain_toolset() {
- local name=${1}
- local kind=${2}
- local programs="${3}"
- _set_toolchain_item "${name}" "toolset_${kind}" "${programs}"
- }
-
- # add the give toolchain toolset
- _add_toolchain_toolset() {
- local name=${1}
- local kind=${2}
- local program="${3}"
- _get_toolchain_item "${name}" "toolset_${kind}"; local programs="${_ret}"
- if test_nz "${programs}"; then
- programs="${programs}:${program}"
- else
- programs="${program}"
- fi
- _set_toolchain_item "${name}" "toolset_${kind}" "${programs}"
- }
-
- # set toolset in toolchain
- set_toolset() {
- if ! ${_loading_toolchains}; then
- return
- fi
- local kind=${1}
- shift
- local idx=0
- while test $# != 0; do
- local program="${1}"
- local key="${kind}"
- if test_nq "${idx}" "0"; then
- key="${key}_${idx}"
- fi
- _set_toolchain_toolset "${_xmake_sh_toolchain_current}" "${key}" "${program}"
- idx=$((idx+1))
- shift
- done
- }
-
- #-----------------------------------------------------------------------------
- # load options
- #
-
- # load options and toolchains
- _load_options_and_toolchains() {
- _loading_options=true
- _loading_toolchains=true
- _loading_targets=false
- local file=${xmake_sh_projectdir}/xmake.sh
- if test -f "${file}"; then
- includes "${file}"
- else
- # include all xmake.sh files in next sub-directories
- local files=`find ${xmake_sh_projectdir} -maxdepth 2 -mindepth 2 -name "xmake.sh"`
- for file in ${files}; do
- includes "${file}"
- done
- fi
- }
- _load_options_and_toolchains
-
- # show option usage
- _show_options_usage() {
- _get_options_for_menu; local options="${_ret}"
- for name in ${options}; do
- _get_option_item "${name}" "description"; local description="${_ret}"
- _get_option_item "${name}" "default"; local default="${_ret}"
- string_toupper ${name}; local head="--${name}="${_ret}""
- local headsize=${#head}
- local tail="${description}"
- if test "x${default}" != "x"; then
- local defval=${default}
- if test "x${defval}" = "xtrue"; then
- defval="yes"
- elif test "x${defval}" = "xfalse"; then
- defval="no"
- fi
- tail="${tail} (default: ${defval})"
- fi
- local width=24
- local padding_width=$((${width} - ${headsize}))
- local padding=$(string_dupch ${padding_width} " ")
- echo " ${head}${padding}${tail}"
- done
- }
-
- # show configure usage
- _show_usage() {
- echo '
- Usage: '"$0"' [<options>...]
- Options: [defaults in brackets after descriptions]
- Common options:
- --help Print this message.
- --version Only print version information.
- --verbose Display more information.
- --diagnosis Display lots of diagnosis information.
-
- --generator=GENERATOR Set the project generator. (default: '"${project_generator}"')
- - gmake
- - ninja
- --make=MAKE Set the make program. (default: '"${_make_program_default}"')
- --ninja=NINJA Set the Ninja program. (default: '"${_ninja_program_default}"')
- --plat=PLAT Compile for the given platform. (default: '"${_target_plat_default}"')
- - msys
- - cross
- - bsd
- - mingw
- - macosx
- - linux
- --arch=ARCH Compile for the given architecture. (default: '"${_target_arch_default}"')
- - msys: i386 x86_64
- - cross: i386 x86_64 arm arm64 mips mips64 riscv riscv64 loong64 s390x ppc ppc64 sh4
- - bsd: i386 x86_64
- - mingw: i386 x86_64 arm arm64
- - macosx: x86_64 arm64
- - linux: i386 x86_64 armv7 armv7s arm64-v8a mips mips64 mipsel mips64el
- --mode=MODE Set the given compilation mode. (default: '"${_target_mode_default}"')
- - release
- - debug
- --kind=KIND Set the given target kind. (default: '"${_target_kind_default}"')
- - static
- - shared
- - binary
- --toolchain=TOOLCHAIN Set toolchain name.
- - clang
- - gcc
- --buildir=DIR Set build directory. (default: '"${xmake_sh_buildir}"')
-
- Autoconf options:
- --build=BUILD Configure for building on BUILD [guessed]
- --host=HOST Cross-compile to build programs to run on HOST [BUILD]
- --prefix=PREFIX Set install files directory in tree rooted at PREFIX. (default: '"${_install_prefix_default}"')
- --bindir=DIR Set install binaries directory in PREFIX/DIR. (default: '"${_install_bindir_default}"')
- --libdir=DIR Set install libraries directory in PREFIX/DIR. (default: '"${_install_libdir_default}"')
- --includedir=DIR Set install includes directory in PREFIX/DIR. (default: '"${_install_includedir_default}"')
-
- Project options:
- '"$(_show_options_usage)"'
- '
- exit 1
- }
-
- # show xmake.sh version
- _show_version() {
- echo "xmake.sh v${xmake_sh_version}, A script-only build utility like autotools"
- echo "${xmake_sh_copyright}"
- echo ' _ _ '
- echo " __ ___ __ __ __ _| | ______ ___| |__ "
- echo " \ \/ / | \/ |/ _ | |/ / __ \ / __| '_ \ "
- echo " > < | \__/ | /_| | < ___/_\__ \ | | | "
- echo " /_/\_\_|_| |_|\__ \|_|\_\____(_)___/_| |_| "
- echo ' by ruki, xmake.io'
- echo ' '
- echo ' 👉 Manual: https://xmake.io/#/getting_started '
- echo ' 🙏 Donate: https://xmake.io/#/sponsor '
- echo ' '
- exit 2
- }
-
- # --foo=yes => foo
- _parse_argument_name() {
- _ret=$(echo "${1#*--}" | sed "s/${2-=[^=]*}$//")
- string_replace "${_ret}" "-" "_"
- }
-
- # --foo=yes => yes
- _parse_argument_value() {
- _ret=$(echo "$1" | sed "s/^${2-[^=]*=}//")
- }
-
- # parse input arguments
- _handle_option() {
- _parse_argument_name ${1}; local name="${_ret}"
- _parse_argument_value ${1}; local value="${_ret}"
- if test_eq "${name}" "help"; then
- _show_usage
- return 0
- elif test_eq "${name}" "version"; then
- _show_version
- return 0
- elif test_eq "${name}" "verbose"; then
- xmake_sh_verbose=true
- return 0
- elif test_eq "${name}" "diagnosis"; then
- xmake_sh_diagnosis=true
- return 0
- elif test_eq "${name}" "plat"; then
- _target_plat=${value}
- return 0
- elif test_eq "${name}" "arch"; then
- _target_arch=${value}
- return 0
- elif test_eq "${name}" "mode"; then
- _target_mode=${value}
- return 0
- elif test_eq "${name}" "kind"; then
- _target_kind=${value}
- return 0
- elif test_eq "${name}" "toolchain"; then
- _target_toolchain=${value}
- return 0
- elif test_eq "${name}" "generator"; then
- project_generator=${value}
- return 0
- elif test_eq "${name}" "make"; then
- _make_program=${value}
- return 0
- elif test_eq "${name}" "ninja"; then
- _ninja_program=${value}
- return 0
- elif test_eq "${name}" "prefix"; then
- _install_prefix_default="${value}"
- return 0
- elif test_eq "${name}" "bindir"; then
- _install_bindir_default="${value}"
- return 0
- elif test_eq "${name}" "libdir"; then
- _install_libdir_default="${value}"
- return 0
- elif test_eq "${name}" "includedir"; then
- _install_includedir_default="${value}"
- return 0
- elif test_eq "${name}" "buildir"; then
- xmake_sh_buildir="${value}"
- return 0
- elif test_eq "${name}" "build"; then
- _autoconf_build_type="${value}"
- return 0
- elif test_eq "${name}" "host"; then
- _autoconf_host_type="${value}"
- return 0
- elif _has_option "${name}"; then
- _set_option_value "${name}" "${value}"
- return 0
- fi
- return 1
- }
- while test $# != 0; do
- if ! _handle_option ${1}; then
- wprint "unknown option: $1"
- fi
- shift
- done
-
- #-----------------------------------------------------------------------------
- # handle some autoconf configurations
- #
-
- # parse triplet
- # https://github.com/xmake-io/xmake/issues/3869
- # e.g. i686-linux-gnu, aarch64-apple-darwin, x86_64-w64-mingw32, i686-redhat-linux-gnu
- _parse_triplet() {
- local triplet="${1}"
- string_split "${triplet}" "-"
- }
-
- _get_arch_from_cpu() {
- local cpu="${1}"
- case "${cpu}" in
- i686) _ret="i386";;
- i386) _ret="i386";;
- x86_64) _ret="x86_64";;
- aarch64) _ret="arm64";;
- arm64) _ret="arm64";;
- arm*) _ret="arm";;
- *) _ret="${cpu}";;
- esac
- }
-
- _get_plat_from_vendor_os() {
- local vendor="${1}"
- local os="${2}"
- case "${vendor}" in
- linux)
- if string_contains "${os}" "android"; then
- _ret="android"
- else
- _ret="linux"
- fi
- ;;
- apple)
- if test_eq "${os}" "darwin"; then
- _ret="macosx"
- fi
- ;;
- w64) _ret="mingw";;
- *) _ret="${os}";;
- esac
- }
-
- _handle_autoconf_configs() {
- if test_z "${_autoconf_host_type}"; then
- _autoconf_host_type="${_autoconf_build_type}"
- fi
-
- if test_nz "${_autoconf_build_type}"; then
- _parse_triplet "${_autoconf_build_type}"; local cpu="${_ret}"; local vendor="${_ret2}"; local os="${_ret3}"
- _get_arch_from_cpu "${cpu}"
- if test_nz "${_ret}"; then
- os_arch="${_ret}"
- else
- wprint "unknown cpu: ${cpu} in --build=${value}"
- fi
- _get_plat_from_vendor_os "${vendor}" "${os}"
- if test_nz "${_ret}"; then
- os_host="${_ret}"
- else
- wprint "unknown vendor-os: ${vendor}-${os} in --build=${value}"
- fi
- fi
-
- if test_nz "${_autoconf_host_type}"; then
- _parse_triplet "${_autoconf_host_type}"; local cpu="${_ret}"; local vendor="${_ret2}"; local os="${_ret3}"
- _get_arch_from_cpu "${cpu}"
- if test_nz "${_ret}"; then
- _target_arch_default="${_ret}"
- else
- wprint "unknown cpu: ${cpu} in --host=${value}"
- fi
- _get_plat_from_vendor_os "${vendor}" "${os}"
- if test_nz "${_ret}"; then
- _target_plat_default="${_ret}"
- else
- wprint "unknown vendor-os: ${vendor}-${os} in --build=${value}"
- fi
- fi
- }
- _handle_autoconf_configs
-
- #-----------------------------------------------------------------------------
- # detect platform and toolchains
- #
-
- # envs toolchain
- toolchain "envs"
- set_toolset "as" "$CC" "$CXX" "$AS"
- set_toolset "cc" "$CC"
- set_toolset "cxx" "$CC" "$CXX"
- set_toolset "mm" "$CC" "$CXX"
- set_toolset "mxx" "$CC" "$CXX"
- set_toolset "ld" "$CXX" "$CC" "$LD"
- set_toolset "sh" "$CXX" "$CC" "$LD"
- set_toolset "ar" "$AR" "ar"
- toolchain_end
-
- # clang toolchain
- toolchain "clang"
- set_toolset "as" "clang"
- set_toolset "cc" "clang"
- set_toolset "cxx" "clang" "clang++"
- set_toolset "mm" "clang"
- set_toolset "mxx" "clang" "clang++"
- set_toolset "ld" "clang++" "clang"
- set_toolset "sh" "clang++" "clang"
- set_toolset "ar" "ar"
- toolchain_end
-
- # gcc toolchain
- toolchain "gcc"
- set_toolset "as" "gcc"
- set_toolset "cc" "gcc"
- set_toolset "cxx" "gcc" "g++"
- set_toolset "mm" "gcc"
- set_toolset "mxx" "gcc" "g++"
- set_toolset "ld" "g++" "gcc"
- set_toolset "sh" "g++" "gcc"
- set_toolset "ar" "ar"
- toolchain_end
-
- # mingw toolchain (x86_64)
- toolchain "x86_64_w64_mingw32"
- set_toolset "as" "x86_64-w64-mingw32-gcc"
- set_toolset "cc" "x86_64-w64-mingw32-gcc"
- set_toolset "cxx" "x86_64-w64-mingw32-gcc" "x86_64-w64-mingw32-g++"
- set_toolset "mm" "x86_64-w64-mingw32-gcc"
- set_toolset "mxx" "x86_64-w64-mingw32-gcc" "x86_64-w64-mingw32-g++"
- set_toolset "ld" "x86_64-w64-mingw32-g++" "x86_64-w64-mingw32-gcc"
- set_toolset "sh" "x86_64-w64-mingw32-g++" "x86_64-w64-mingw32-gcc"
- set_toolset "ar" "x86_64-w64-mingw32-ar" "ar"
- toolchain_end
-
- # mingw toolchain (i686)
- toolchain "i686_w64_mingw32"
- set_toolset "as" "i686-w64-mingw32-gcc"
- set_toolset "cc" "i686-w64-mingw32-gcc"
- set_toolset "cxx" "i686-w64-mingw32-gcc" "i686-w64-mingw32-g++"
- set_toolset "mm" "i686-w64-mingw32-gcc"
- set_toolset "mxx" "i686-w64-mingw32-gcc" "i686-w64-mingw32-g++"
- set_toolset "ld" "i686-w64-mingw32-g++" "i686-w64-mingw32-gcc"
- set_toolset "sh" "i686-w64-mingw32-g++" "i686-w64-mingw32-gcc"
- set_toolset "ar" "i686-w64-mingw32-ar" "ar"
- toolchain_end
-
- # aarch64 toolchain (aarch64)
- toolchain "aarch64_linux_gnu"
- set_toolset "as" "aarch64-linux-gnu-gcc"
- set_toolset "cc" "aarch64-linux-gnu-gcc"
- set_toolset "cxx" "aarch64-linux-gnu-gcc" "aarch64-linux-gnu-g++"
- set_toolset "mm" "aarch64-linux-gnu-gcc"
- set_toolset "mxx" "aarch64-linux-gnu-gcc" "aarch64-linux-gnu-g++"
- set_toolset "ld" "aarch64-linux-gnu-g++" "aarch64-linux-gnu-gcc"
- set_toolset "sh" "aarch64-linux-gnu-g++" "aarch64-linux-gnu-gcc"
- set_toolset "ar" "aarch64-linux-gnu-ar" "ar"
- toolchain_end
-
- # emcc toolchain (wasm32)
- toolchain "emcc"
- set_toolset "as" "emcc"
- set_toolset "cc" "emcc"
- set_toolset "cxx" "emcc" "em++"
- set_toolset "mm" "emcc"
- set_toolset "mxx" "emcc" "em++"
- set_toolset "ld" "em++" "emcc"
- set_toolset "sh" "em++" "emcc"
- set_toolset "ar" "emar" "ar"
- toolchain_end
-
- # check platform
- _check_platform() {
- if test "x${_target_plat}" = "x"; then
- _target_plat=${_target_plat_default}
- fi
- if test "x${_target_arch}" = "x"; then
- _target_arch=${_target_arch_default}
- fi
- if test "x${_target_mode}" = "x"; then
- _target_mode=${_target_mode_default}
- fi
- if test "x${_target_kind}" = "x"; then
- _target_kind=${_target_kind_default}
- fi
- echo "checking for platform ... ${_target_plat}"
- echo "checking for architecture ... ${_target_arch}"
- }
-
- # get toolchain compile command for gcc/clang
- _toolchain_compcmd_for_gcc_clang() {
- local program="${1}"
- local objectfile="${2}"
- local sourcefile="${3}"
- local flags="${4}"
- _ret="${program} -c ${flags} -o ${objectfile} ${sourcefile}"
- }
-
- # get toolchain link command for gcc/clang
- _toolchain_linkcmd_for_gcc_clang() {
- local toolkind="${1}"
- local program="${2}"
- local binaryfile="${3}"
- local objectfiles="${4}"
- local flags="${5}"
- if test_eq "${toolkind}" "sh"; then
- flags="-shared -fPIC ${flags}"
- fi
- _ret="${program} -o ${binaryfile} ${objectfiles} ${flags}"
- }
-
- # get toolchain link command for ar
- _toolchain_linkcmd_for_ar() {
- local toolkind="${1}"
- local program="${2}"
- local binaryfile="${3}"
- local objectfiles="${4}"
- local flags="${5}"
- _ret="${program} ${flags} ${binaryfile} ${objectfiles}"
- }
-
- # get toolchain compile command
- _toolchain_compcmd() {
- local sourcekind="${1}"
- local objectfile="${2}"
- local sourcefile="${3}"
- local flags="${4}"
- _get_toolchain_toolset "${_target_toolchain}" "${sourcekind}"; local program="${_ret}"
- path_toolname "${program}"; local toolname="${_ret}"
- local compcmd=""
- case "${toolname}" in
- gcc) _toolchain_compcmd_for_gcc_clang "${program}" "${objectfile}" "${sourcefile}" "${flags}"; compcmd="${_ret}";;
- gxx) _toolchain_compcmd_for_gcc_clang "${program}" "${objectfile}" "${sourcefile}" "${flags}"; compcmd="${_ret}";;
- clang) _toolchain_compcmd_for_gcc_clang "${program}" "${objectfile}" "${sourcefile}" "${flags}"; compcmd="${_ret}";;
- clangxx) _toolchain_compcmd_for_gcc_clang "${program}" "${objectfile}" "${sourcefile}" "${flags}"; compcmd="${_ret}";;
- emcc) _toolchain_compcmd_for_gcc_clang "${program}" "${objectfile}" "${sourcefile}" "${flags}"; compcmd="${_ret}";;
- emxx) _toolchain_compcmd_for_gcc_clang "${program}" "${objectfile}" "${sourcefile}" "${flags}"; compcmd="${_ret}";;
- *) raise "unknown toolname(${toolname})!" ;;
- esac
- _ret="${compcmd}"
- }
-
- # get toolchain link command
- _toolchain_linkcmd() {
- local toolkind="${1}"
- local binaryfile="${2}"
- local objectfiles="${3}"
- local flags="${4}"
- _get_toolchain_toolset "${_target_toolchain}" "${toolkind}"; local program="${_ret}"
- path_toolname "${program}"; local toolname="${_ret}"
- case "${toolname}" in
- gcc) _toolchain_linkcmd_for_gcc_clang "${toolkind}" "${program}" "${binaryfile}" "${objectfiles}" "${flags}"; linkcmd="${_ret}";;
- gxx) _toolchain_linkcmd_for_gcc_clang "${toolkind}" "${program}" "${binaryfile}" "${objectfiles}" "${flags}"; linkcmd="${_ret}";;
- clang) _toolchain_linkcmd_for_gcc_clang "${toolkind}" "${program}" "${binaryfile}" "${objectfiles}" "${flags}"; linkcmd="${_ret}";;
- clangxx) _toolchain_linkcmd_for_gcc_clang "${toolkind}" "${program}" "${binaryfile}" "${objectfiles}" "${flags}"; linkcmd="${_ret}";;
- emcc) _toolchain_linkcmd_for_gcc_clang "${toolkind}" "${program}" "${binaryfile}" "${objectfiles}" "${flags}"; linkcmd="${_ret}";;
- emxx) _toolchain_linkcmd_for_gcc_clang "${toolkind}" "${program}" "${binaryfile}" "${objectfiles}" "${flags}"; linkcmd="${_ret}";;
- ar) _toolchain_linkcmd_for_ar "${toolkind}" "${program}" "${binaryfile}" "${objectfiles}" "${flags}"; linkcmd="${_ret}";;
- emar) _toolchain_linkcmd_for_ar "${toolkind}" "${program}" "${binaryfile}" "${objectfiles}" "${flags}"; linkcmd="${_ret}";;
- *) raise "unknown toolname(${toolname})!" ;;
- esac
- _ret="${linkcmd}"
- }
-
- # try make
- _toolchain_try_make() {
- local program="${1}"
- if _os_runv "${program}" "--version"; then
- return 0
- fi
- return 1
- }
-
- # try ninja
- _toolchain_try_ninja() {
- local program="${1}"
- if _os_runv "${program}" "--version"; then
- return 0
- fi
- return 1
- }
-
- # try gcc
- _toolchain_try_gcc() {
- if test "x${_toolchain_try_gcc_result}" = "xok"; then
- return 0
- elif test "x${_toolchain_try_gcc_result}" = "xno"; then
- return 1
- fi
-
- local kind="${1}"
- local program="${2}"
- if _os_runv "${program}" "--version"; then
- _toolchain_try_gcc_result="ok"
- return 0
- fi
- _toolchain_try_gcc_result="no"
- return 1
- }
-
- # try g++
- _toolchain_try_gxx() {
- if test "x${_toolchain_try_gxx_result}" = "xok"; then
- return 0
- elif test "x${_toolchain_try_gxx_result}" = "xno"; then
- return 1
- fi
-
- local kind="${1}"
- local program="${2}"
- if _os_runv "${program}" "--version"; then
- _toolchain_try_gxx_result="ok"
- return 0
- fi
- _toolchain_try_gxx_result="no"
- return 1
- }
-
- # try clang
- _toolchain_try_clang() {
- if test "x${_toolchain_try_clang_result}" = "xok"; then
- return 0
- elif test "x${_toolchain_try_clang_result}" = "xno"; then
- return 1
- fi
-
- local kind="${1}"
- local program="${2}"
- if _os_runv "${program}" "--version"; then
- _toolchain_try_clang_result="ok"
- return 0
- fi
- _toolchain_try_clang_result="no"
- return 1
- }
-
- # try clang++
- _toolchain_try_clangxx() {
- if test "x${_toolchain_try_clangxx_result}" = "xok"; then
- return 0
- elif test "x${_toolchain_try_clangxx_result}" = "xno"; then
- return 1
- fi
-
- local kind="${1}"
- local program="${2}"
- if _os_runv "${program}" "--version"; then
- _toolchain_try_clangxx_result="ok"
- return 0
- fi
- _toolchain_try_clangxx_result="no"
- return 1
- }
-
- # try ar
- _toolchain_try_ar() {
- local kind="${1}"
- local program="${2}"
-
- # generate the source file
- _os_tmpfile
- local tmpfile="${_ret}"
- local objectfile="${tmpfile}.o"
- local libraryfile="${tmpfile}.a"
- echo "" > "${objectfile}"
-
- # try linking it
- local ok=false
- if _os_runv "${program}" "-cr" "${libraryfile}" "${objectfile}"; then
- ok=true
- fi
-
- # remove files
- _os_tryrm "${objectfile}"
- _os_tryrm "${libraryfile}"
- if ${ok}; then
- return 0
- fi
- return 1
- }
-
- # try program
- _toolchain_try_program() {
- local toolchain="${1}"
- local kind="${2}"
- local program="${3}"
- local ok=false
- path_toolname "${program}"; local toolname="${_ret}"
- case "${toolname}" in
- gcc) _toolchain_try_gcc "${kind}" "${program}" && ok=true;;
- gxx) _toolchain_try_gxx "${kind}" "${program}" && ok=true;;
- clang) _toolchain_try_clang "${kind}" "${program}" && ok=true;;
- clangxx) _toolchain_try_clangxx "${kind}" "${program}" && ok=true;;
- emcc) _toolchain_try_clang "${kind}" "${program}" && ok=true;;
- emxx) _toolchain_try_clangxx "${kind}" "${program}" && ok=true;;
- ar) _toolchain_try_ar "${kind}" "${program}" && ok=true;;
- emar) _toolchain_try_ar "${kind}" "${program}" && ok=true;;
- *) raise "unknown toolname(${toolname})!" ;;
- esac
- if ${ok}; then
- vprint "checking for ${program} ... ok"
- return 0
- fi
- vprint "checking for ${program} ... no"
- return 1
- }
-
- # try toolset
- _toolchain_try_toolset() {
- local toolchain=${1}
- local kind=${2}
- local description=${3}
- local indices="0 1 2 3 4 5"
- for idx in ${indices}; do
- local key="${kind}"
- if test_nq "${idx}" "0"; then
- key="${key}_${idx}"
- fi
- _get_toolchain_toolset "${toolchain}" "${key}"; local program="${_ret}"
- if test_nz "${program}"; then
- if _toolchain_try_program "${toolchain}" "${kind}" "${program}"; then
- _set_toolchain_toolset "${toolchain}" "${kind}" "${program}"
- echo "checking for the ${description} (${kind}) ... ${program}"
- return 0
- fi
- fi
- done
- return 1
- }
-
- # try toolchain
- _toolchain_try() {
- local toolchain=${1}
- vprint "checking for $toolchain toolchain ..."
- if _toolchain_try_toolset "${toolchain}" "cc" "c compiler" &&
- _toolchain_try_toolset "${toolchain}" "cxx" "c++ compiler" &&
- _toolchain_try_toolset "${toolchain}" "as" "assembler" &&
- _toolchain_try_toolset "${toolchain}" "mm" "objc compiler" &&
- _toolchain_try_toolset "${toolchain}" "mxx" "objc++ compiler" &&
- _toolchain_try_toolset "${toolchain}" "ld" "linker" &&
- _toolchain_try_toolset "${toolchain}" "ar" "static library archiver" &&
- _toolchain_try_toolset "${toolchain}" "sh" "shared library linker"; then
- return 0
- fi
- return 1
- }
-
- # detect make
- _toolchain_detect_make() {
- if test "x${_make_program}" = "x"; then
- _make_program=${_make_program_default}
- fi
- if _toolchain_try_make "${_make_program}"; then
- echo "checking for make ... ok"
- else
- echo "checking for make ... no"
- raise "make not found!"
- fi
- }
-
- # detect ninja
- _toolchain_detect_ninja() {
- if test "x${_ninja_program}" = "x"; then
- _ninja_program=${_ninja_program_default}
- fi
- if _toolchain_try_ninja "${_ninja_program}"; then
- echo "checking for ninja ... ok"
- else
- echo "checking for ninja ... no"
- raise "ninja not found!"
- fi
- }
-
- # detect build backend
- _toolchain_detect_backend() {
- if test "x${project_generator}" = "xgmake"; then
- _toolchain_detect_make
- elif test "x${project_generator}" = "xninja"; then
- _toolchain_detect_ninja
- fi
- }
-
- # detect toolchain
- _toolchain_detect() {
- # detect build backend
- _toolchain_detect_backend
-
- # detect toolchains
- local toolchains="${1}"
- if test "x${toolchains}" = "x"; then
- if is_plat "macosx"; then
- toolchains="envs clang gcc"
- elif is_plat "mingw"; then
- if is_arch "i386"; then
- toolchains="i686_w64_mingw32"
- else
- toolchains="x86_64_w64_mingw32"
- fi
- elif is_plat "wasm"; then
- toolchains="emcc"
- elif is_plat "linux" && ! is_arch "${os_arch}"; then
- toolchains="envs"
- if is_arch "arm64"; then
- toolchains="${toolchains} aarch64_linux_gnu"
- fi
- else
- toolchains="envs gcc clang"
- fi
- fi
- for toolchain in ${toolchains}; do
- if _toolchain_try "$toolchain"; then
- _target_toolchain=${toolchain}
- break
- fi
- done
- }
-
- # check toolchain
- _check_toolchain() {
- local toolchain=${_target_toolchain}
- _target_toolchain=""
- _toolchain_detect ${toolchain}
-
- if test "x${_target_toolchain}" != "x"; then
- echo "checking for toolchain ... ${_target_toolchain}"
- else
- echo "checking for toolchain ... no"
- raise "toolchain not found!"
- fi
- }
-
- # get function code
- #
- # sigsetjmp
- # sigsetjmp((void*)0, 0)
- #
- _get_funccode() {
- local func="${1}"
- local code=""
- if string_contains "${func}" "("; then
- code="${func}"
- else
- code="typedef void (*func_t)(); volatile func_t p${func} = (func_t)${func}; while (p${func}) {break;};"
- fi
- _ret="${code}"
- }
-
- # generate cxsnippets source code
- _generate_cxsnippets_sourcecode() {
- local funcs="${1}"
- local includes="${2}"
- local types="${3}"
- local snippets="${4}"
-
- local snippet_includes=""
- for include in $includes; do
- snippet_includes="${snippet_includes}#include \"${include}\"\n"
- done
-
- local snippet_types=""
- for type in $types; do
- string_replace "${type}" '[^a-zA-Z]' "_"; local typevar="${_ret}"
- snippet_types="${snippet_types}typedef ${type} __type_${typevar};\n"
- done
-
- local snippet_funcs=""
- for func in $funcs; do
- _get_funccode "${func}"; func="${_ret}"
- snippet_funcs="${snippet_funcs}${func}\n "
- done
-
- local snippets_code=""
- if test_nz "${snippet_includes}"; then
- snippets_code="${snippets_code}${snippet_includes}\n"
- fi
- if test_nz "${snippet_types}"; then
- snippets_code="${snippets_code}${snippet_types}\n"
- fi
- if test_nz "${snippets}"; then
- snippets_code="${snippets_code}${snippets}\n"
- fi
-
- _ret='
- '"${snippets_code}"'int main(int argc, char** argv) {
- '"${snippet_funcs}"'
- return 0;
- }'
- }
-
- # check cxsnippets
- _check_cxsnippets() {
- local name="${1}"
- local kind="${2}"
- _get_option_item "${name}" "${kind}funcs"; local funcs="${_ret}"
- _get_option_item "${name}" "${kind}includes"; local includes="${_ret}"
- _get_option_item "${name}" "${kind}types"; local types="${_ret}"
- _get_option_item "${name}" "${kind}snippets"; local snippets="${_ret}"
- if test_z "${funcs}" && test_z "${includes}" &&
- test_z "${types}" && test_z "${snippets}"; then
- return 0
- fi
-
- # get c/c++ extension
- local extension=".c"
- local sourcekind="cc"
- if test_eq "${kind}" "cxx"; then
- extension=".cpp"
- sourcekind="cxx"
- fi
-
- # generate source code
- _generate_cxsnippets_sourcecode "${funcs}" "${includes}" "${types}" "${snippets}"; local sourcecode="${_ret}"
- dprint "${sourcecode}"
-
- # generate the source file
- _os_tmpfile
- local tmpfile="${_ret}"
- local sourcefile="${tmpfile}${extension}"
- local objectfile="${tmpfile}.o"
- local binaryfile="${tmpfile}.bin"
- print "${sourcecode}" > "${sourcefile}"
-
- # try compiling it
- local ok=false
- if ! ${ok}; then
- local compflags=""
- _get_toolchain_toolset "${_target_toolchain}" "${sourcekind}"; local program="${_ret}"
- path_toolname "${program}"; local toolname="${_ret}"
- local itemnames="languages warnings optimizes defines undefines includedirs"
- for itemname in ${itemnames}; do
- _get_option_abstract_flags "${name}" "${sourcekind}" "${toolname}" "${itemname}"; local flags="${_ret}"
- if test_nz "${flags}"; then
- _split_flags "${flags}"; flags="${_ret}"
- compflags="${compflags} ${flags}"
- fi
- done
- local flagnames="cxflags"
- if test_eq "${sourcekind}" "cxx"; then
- flagnames="${flagnames} cxxflags"
- else
- flagnames="${flagnames} cflags"
- fi
- for flagname in $flagnames; do
- _get_option_item "${name}" "${flagname}"; local flags="${_ret}"
- if test_nz "${flags}"; then
- compflags="${compflags} ${flags}"
- fi
- done
- if test_eq "${sourcekind}" "cxx"; then
- if test_nz "${CXXFLAGS}"; then
- compflags="${compflags} ${CXXFLAGS}"
- fi
- else
- if test_nz "${CFLAGS}"; then
- compflags="${compflags} ${CFLAGS}"
- fi
- fi
- if test_nz "${CPPFLAGS}"; then
- compflags="${compflags} ${CPPFLAGS}"
- fi
- _toolchain_compcmd "${sourcekind}" "${objectfile}" "${sourcefile}" "${compflags}"; local compcmd="${_ret}"
- if ${xmake_sh_diagnosis}; then
- print "> ${compcmd}"
- fi
- if _os_runv ${compcmd}; then
- ok=true
- fi
- fi
-
- # try linking it
- _get_option_item "${name}" "links"; local links="${_ret}"
- _get_option_item "${name}" "syslinks"; local syslinks="${_ret}"
- _get_option_item "${name}" "ldflags"; local ldflags="${_ret}"
- if test_nz "${syslinks}"; then
- links="${links} ${syslinks}"
- fi
- if ${ok} && (test_nz "${links}" || test_nz "${ldflags}"); then
- local toolkind="ld"
- _get_toolchain_toolset "${_target_toolchain}" "${toolkind}"; local program="${_ret}"
- path_toolname "${program}"; local toolname="${_ret}"
- local itemnames="linkdirs links syslinks"
- local linkflags=""
- for itemname in ${itemnames}; do
- _get_option_abstract_flags "${name}" "${toolkind}" "${toolname}" "${itemname}"; local flags="${_ret}"
- if test_nz "${flags}"; then
- _split_flags "${flags}"; flags="${_ret}"
- linkflags="${linkflags} ${flags}"
- fi
- done
- _get_option_item "${name}" "ldflags"; local flags="${_ret}"
- if test_nz "${flags}"; then
- linkflags="${linkflags} ${flags}"
- fi
- if test_nz "${LDFLAGS}"; then
- linkflags="${linkflags} ${LDFLAGS}"
- fi
- _toolchain_linkcmd "${toolkind}" "${binaryfile}" "${objectfile}" "${linkflags}"; local linkcmd="${_ret}"
- if ${xmake_sh_diagnosis}; then
- print "> ${linkcmd}"
- fi
- if _os_runv ${linkcmd}; then
- ok=true
- else
- ok=false
- fi
- fi
-
- # trace
- if ${xmake_sh_verbose} || ${xmake_sh_diagnosis}; then
- if test_nz "${includes}"; then
- print "> checking for ${kind} includes(${includes})"
- fi
- if test_nz "${types}"; then
- print "> checking for ${kind} types(${types})"
- fi
- if test_nz "${funcs}"; then
- print "> checking for ${kind} funcs(${funcs})"
- fi
- if test_nz "${links}"; then
- print "> checking for ${kind} links(${links})"
- fi
- fi
-
- # remove files
- _os_tryrm "${sourcefile}"
- _os_tryrm "${objectfile}"
- _os_tryrm "${binaryfile}"
- if ${ok}; then
- return 0
- fi
- return 1
- }
-
- # check csnippets
- _check_csnippets() {
- local name="${1}"
- if _check_cxsnippets "${name}" "c"; then
- return 0
- fi
- return 1
- }
-
- # check cxxsnippets
- _check_cxxsnippets() {
- local name="${1}"
- if _check_cxsnippets "${name}" "cxx"; then
- return 0
- fi
- return 1
- }
-
- # check option
- _check_option() {
- local name="${1}"
- _get_option_value "${name}"; local value="${_ret}"
- _get_option_item "${name}" "default"; local default="${_ret}"
- if test_nz "${value}"; then
- if _is_enabled "${value}"; then
- return 0
- else
- return 1
- fi
- elif test_nz "${default}"; then
- if _is_enabled "${default}"; then
- return 0
- else
- return 1
- fi
- else
- _get_option_item "${name}" "before_check"; local before_check="${_ret}"
- if test_nz "${before_check}"; then
- eval ${before_check}
- fi
- if _check_csnippets "${name}" && _check_cxxsnippets "${name}"; then
- return 0
- fi
- fi
- return 1
- }
-
- # check options
- _check_options() {
- _get_options_for_checking; local options="${_ret}"
- for name in $options; do
- if _check_option "$name"; then
- echo "checking for ${name} .. ok"
- _set_option_value "${name}" true
- else
- echo "checking for ${name} .. no"
- _set_option_value "${name}" false
- fi
- done
- }
-
- # check all
- _check_all() {
- _check_platform
- _check_toolchain
- _check_options
- }
- _check_all
-
- #-----------------------------------------------------------------------------
- # init builtin variables, e.g. add_headerfiles "${buildir}/config.h"
- #
- projectdir="${xmake_sh_projectdir}"
- if path_is_absolute "${xmake_sh_buildir}"; then
- buildir="${xmake_sh_buildir}"
- else
- buildir="${xmake_sh_projectdir}/${xmake_sh_buildir}"
- fi
- plat="${_target_plat}"
- arch="${_target_arch}"
- mode="${_target_mode}"
- kind="${_target_kind}"
-
- #-----------------------------------------------------------------------------
- # load project targets
- #
-
- # load targets
- _load_targets() {
- echo "analyzing project configuration .."
- _loading_options=false
- _loading_toolchains=false
- _loading_targets=true
- _xmake_sh_option_current=""
- _xmake_sh_target_current=""
- _xmake_sh_toolchain_current=""
- local file=${xmake_sh_projectdir}/xmake.sh
- if test -f "${file}"; then
- includes "${file}"
- else
- # include all xmake.sh files in next sub-directories
- _os_find "${xmake_sh_projectdir}" "xmake.sh" 2; local files="${_ret}"
- for file in ${files}; do
- includes "${file}"
- done
- fi
- }
- _load_targets
-
- # get toolset kinds for all targets
- # e.g. cc cxx as mm mxx ld sh ar
- _get_targets_toolkinds() {
- if test_z "${_targets_toolkinds_dedup}"; then
- _dedup "${_targets_toolkinds}"; _targets_toolkinds_dedup="${_ret}"
- fi
- _ret="${_targets_toolkinds_dedup}"
- }
-
- #-----------------------------------------------------------------------------
- # generate configfiles
- #
-
- # vprint config variable in `${name}`
- _vprint_configvar_value() {
- local name="${1}"
- local value="${2}"
- vprint " > replace ${name} -> ${value}"
- }
-
- # vprint config variable in `${define name}`
- _vprint_configvar_define() {
- local name="${1}"
- local value="${2}"
- if test_z "${value}"; then
- vprint " > replace ${name} -> /* #undef ${name} */"
- elif test_eq "${value}" "1" || test_eq "${value}" "true"; then
- vprint " > replace ${name} -> #define ${name} 1"
- elif test_eq "${value}" "0" || test_eq "${value}" "false"; then
- vprint " > replace ${name} -> /*#define ${name} 0*/"
- else
- vprint " > replace ${name} -> #define ${name} ${value}"
- fi
- }
-
- # replace config variable in `${define name}`
- _replace_configvar_define() {
- local name="${1}"
- local value="${2}"
- if test_z "${value}"; then
- _ret="s/\${define ${name}}/\/*#undef ${name}*\//g"
- elif test_eq "${value}" "1" || test_eq "${value}" "true"; then
- _ret="s/\${define ${name}}/#define ${name} 1/g"
- elif test_eq "${value}" "0" || test_eq "${value}" "false"; then
- _ret="s/\${define ${name}}/\/*#define ${name} 0*\//g"
- else
- _ret="s/\${define ${name}}/#define ${name} ${value}/g"
- fi
- }
-
- # replace config variable in `${name}`
- _replace_configvar_value() {
- local name="${1}"
- local value="${2}"
- _ret="s@\${${name}}@${value}@g"
- }
-
- # generate configfile for the given target
- _generate_configfile() {
- local target="${1}"
- local configfile_in="${2}"
- _get_target_item "${target}" "configdir"; local configdir="${_ret}"
- if test_z "${configdir}"; then
- path_directory configfile_in; configdir="${_ret}"
- fi
- if ! test -d "${configdir}"; then
- mkdir -p "${configdir}"
- fi
- path_basename "${configfile_in}"; local filename="${_ret}"
- local configfile="${configdir}/${filename}"
- echo "generating ${configfile} .."
-
- # replace builtin variables
- local patterns=""
- local target_os=""
- if is_plat "mingw"; then
- target_os="windows"
- else
- target_os="${_target_plat}"
- fi
- string_toupper ${target_os}; target_os="${_ret}"
- _vprint_configvar_value "OS" "${target_os}"
- _replace_configvar_value "OS" "${target_os}"; patterns="${_ret};${patterns}"
-
- # replace version
- _get_target_item "${target}" "version"; local version="${_ret}"
- _get_target_item "${target}" "version_build"; local version_build="${_ret}"
- string_split "${version}" "."
- local version_major="${_ret}"
- local version_minor="${_ret2}"
- local version_alter="${_ret3}"
- if test_nz "${version}"; then
- _vprint_configvar_value "VERSION" "${version}"
- _replace_configvar_value "VERSION" "${version}"; patterns="${_ret};${patterns}"
- fi
- if test_nz "${version_major}"; then
- _vprint_configvar_value "VERSION_MAJOR" "${version_major}"
- _replace_configvar_value "VERSION_MAJOR" "${version_major}"; patterns="${_ret};${patterns}"
- fi
- if test_nz "${version_minor}"; then
- _vprint_configvar_value "VERSION_MINOR" "${version_minor}"
- _replace_configvar_value "VERSION_MINOR" "${version_minor}"; patterns="${_ret};${patterns}"
- fi
- if test_nz "${version_alter}"; then
- _vprint_configvar_value "VERSION_ALTER" "${version_alter}"
- _replace_configvar_value "VERSION_ALTER" "${version_alter}"; patterns="${_ret};${patterns}"
- fi
- if test_nz "${version_build}"; then
- _os_date "${version_build}"; version_build="${_ret}"
- _vprint_configvar_value "VERSION_BUILD" "${version_build}"
- _replace_configvar_value "VERSION_BUILD" "${version_build}"; patterns="${_ret};${patterns}"
- fi
-
- # replace git variables
- local content=""
- content=$(cat "${configfile_in}")
- if string_contains "${content}" "GIT_"; then
- _os_iorunv "git" "describe" "--tags"; local git_tag="${_ret}"
- _vprint_configvar_value "GIT_TAG" "${git_tag}"
- _replace_configvar_value "GIT_TAG" "${git_tag}"; patterns="${_ret};${patterns}"
-
- _os_iorunv "git" "describe" "--tags" "--long"; local git_tag_long="${_ret}"
- _vprint_configvar_value "GIT_TAG_LONG" "${git_tag_long}"
- _replace_configvar_value "GIT_TAG_LONG" "${git_tag_long}"; patterns="${_ret};${patterns}"
-
- _os_iorunv "git" "rev-parse" "--abbrev-ref" "HEAD"; local git_branch="${_ret}"
- _vprint_configvar_value "GIT_BRANCH" "${git_branch}"
- _replace_configvar_value "GIT_BRANCH" "${git_branch}"; patterns="${_ret};${patterns}"
-
- _os_iorunv "git" "rev-parse" "--short" "HEAD"; local git_commit="${_ret}"
- _vprint_configvar_value "GIT_COMMIT" "${git_commit}"
- _replace_configvar_value "GIT_COMMIT" "${git_commit}"; patterns="${_ret};${patterns}"
-
- _os_iorunv "git" "rev-parse" "HEAD"; local git_commit_long="${_ret}"
- _vprint_configvar_value "GIT_COMMIT_LONG" "${git_commit_long}"
- _replace_configvar_value "GIT_COMMIT_LONG" "${git_commit_long}"; patterns="${_ret};${patterns}"
-
- _os_iorunv "log" "-1" "--date=format:%Y%m%d%H%M%S" "--format=%ad"; local git_commit_date="${_ret}"
- _vprint_configvar_value "GIT_COMMIT_DATE" "${git_commit_date}"
- _replace_configvar_value "GIT_COMMIT_DATE" "${git_commit_date}"; patterns="${_ret};${patterns}"
- fi
-
- # replace configvars in target
- local count=0
- local configfile_dst="${configfile}"
- _os_tmpfile; local tmpfile="${_ret}"
- cp "${configfile_in}" "${tmpfile}"
- _get_target_item "${target}" "configvars"; local configvars="${_ret}"
- for name in ${configvars}; do
- _get_target_item "${target}" "configvar_${name}"; local value="${_ret}"
- _vprint_configvar_define "${name}" "${value}"
- _vprint_configvar_value "${name}" "${value}"
- _replace_configvar_define "${name}" "${value}"; patterns="${_ret};${patterns}"
- _replace_configvar_value "${name}" "${value}"; patterns="${_ret};${patterns}"
- count=$((count + 1))
-
- # do replace
- if test_eq "$count" "10"; then
- _io_replace_file "${tmpfile}" "${configfile}" "${patterns}"
- local swapfile="${tmpfile}"
- tmpfile="${configfile}"
- configfile="${swapfile}"
- patterns=""
- count=0
- fi
- done
-
- # do replace (left)
- if test_nz "${patterns}"; then
- _io_replace_file "${tmpfile}" "${configfile}" "${patterns}"
- local swapfile="${tmpfile}"
- tmpfile="${configfile}"
- configfile="${swapfile}"
- patterns=""
- count=0
- fi
-
- # replace fallback
- patterns='s/${define \(.*\)}/\/*#undef \1*\//g;'
- _io_replace_file "${tmpfile}" "${configfile}" "${patterns}"
- if test_nq "${configfile}" "${configfile_dst}"; then
- cp "${configfile}" "${configfile_dst}"
- fi
- echo "${configfile_dst} is generated!"
- }
-
- # generate configfiles
- _generate_configfiles() {
- for target in ${_xmake_sh_targets}; do
- _get_target_item "${target}" "configfiles"; local configfiles="${_ret}"
- for configfile in ${configfiles}; do
- _generate_configfile "${target}" "${configfile}"
- done
- done
- }
- _generate_configfiles
-
- #-----------------------------------------------------------------------------
- # generate gmake file
- #
-
- _gmake_begin() {
- echo "generating makefile .."
- }
-
- _gmake_add_header() {
- echo "# this is the build file for this project
- # it is autogenerated by the xmake.sh build system.
- # do not edit by hand.
- " > "${xmake_sh_makefile}"
- }
-
- _gmake_add_switches() {
- echo "ifneq (\$(VERBOSE),1)" >> "${xmake_sh_makefile}"
- echo "VV=@" >> "${xmake_sh_makefile}"
- echo "endif" >> "${xmake_sh_makefile}"
- echo "" >> "${xmake_sh_makefile}"
- echo "ifeq (\$(PREFIX),)" >> "${xmake_sh_makefile}"
- echo "PREFIX=${_install_prefix_default}" >> "${xmake_sh_makefile}"
- echo "endif" >> "${xmake_sh_makefile}"
- echo "" >> "${xmake_sh_makefile}"
- echo "INSTALLDIR:=\$(DESTDIR)" >> "${xmake_sh_makefile}"
- echo "ifneq (\$(PREFIX),)" >> "${xmake_sh_makefile}"
- echo "ifneq (\$(INSTALLDIR),)" >> "${xmake_sh_makefile}"
- echo "PREFIX_:=\$(patsubst /%,%,\$(PREFIX))" >> "${xmake_sh_makefile}"
- echo "INSTALLDIR:=\$(INSTALLDIR)/\$(PREFIX_)" >> "${xmake_sh_makefile}"
- echo "else" >> "${xmake_sh_makefile}"
- echo "INSTALLDIR:=\$(PREFIX)" >> "${xmake_sh_makefile}"
- echo "endif" >> "${xmake_sh_makefile}"
- echo "endif" >> "${xmake_sh_makefile}"
- echo "" >> "${xmake_sh_makefile}"
- }
-
- _gmake_add_flags() {
- _get_targets_toolkinds; local kinds="${_ret}"
- for target in ${_xmake_sh_targets}; do
- for kind in ${kinds}; do
- _get_target_flags "${target}" "${kind}"; local flags="${_ret}"
- _get_flagname "${kind}"; local flagname="${_ret}"
- local key="${target}_${flagname}"
- echo "${key}=${flags}" >> "${xmake_sh_makefile}"
- done
- echo "" >> "${xmake_sh_makefile}"
- done
- }
-
- _gmake_add_toolchains() {
- _get_targets_toolkinds; local kinds="${_ret}"
- for kind in ${kinds}; do
- _get_toolchain_toolset "${_target_toolchain}" "${kind}"; local program="${_ret}"
- local key="${kind}"
- echo "${key}=${program}" >> "${xmake_sh_makefile}"
- done
- echo "" >> "${xmake_sh_makefile}"
- }
-
- _gmake_add_build_object_for_gcc_clang() {
- local kind="${1}"
- local sourcefile="${2}"
- local objectfile="${3}"
- local flagname="${4}"
- path_directory "${objectfile}"; local objectdir="${_ret}"
- print "\t@mkdir -p ${objectdir}" >> "${xmake_sh_makefile}"
- print "\t\$(VV)\$(${kind}) -c \$(${flagname}) -o ${objectfile} ${sourcefile}" >> "${xmake_sh_makefile}"
- }
-
- _gmake_add_build_object() {
- local target=${1}
- local sourcefile="${2}"
- local objectfile="${3}"
- path_sourcekind "${sourcefile}"; local sourcekind="${_ret}"
- _get_toolchain_toolset "${_target_toolchain}" "${sourcekind}"; local program="${_ret}"
- path_toolname "${program}"; local toolname="${_ret}"
- _get_flagname "${sourcekind}"; local flagname="${_ret}"
- flagname="${target}_${flagname}"
- echo "${objectfile}: ${sourcefile}" >> "${xmake_sh_makefile}"
- print "\t@echo compiling.${_target_mode} ${sourcefile}" >> "${xmake_sh_makefile}"
- case "${toolname}" in
- gcc) _gmake_add_build_object_for_gcc_clang "${sourcekind}" "${sourcefile}" "${objectfile}" "${flagname}";;
- gxx) _gmake_add_build_object_for_gcc_clang "${sourcekind}" "${sourcefile}" "${objectfile}" "${flagname}";;
- clang) _gmake_add_build_object_for_gcc_clang "${sourcekind}" "${sourcefile}" "${objectfile}" "${flagname}";;
- clangxx) _gmake_add_build_object_for_gcc_clang "${sourcekind}" "${sourcefile}" "${objectfile}" "${flagname}";;
- emcc) _gmake_add_build_object_for_gcc_clang "${sourcekind}" "${sourcefile}" "${objectfile}" "${flagname}";;
- emxx) _gmake_add_build_object_for_gcc_clang "${sourcekind}" "${sourcefile}" "${objectfile}" "${flagname}";;
- *) raise "unknown toolname(${toolname})!" ;;
- esac
- echo "" >> "${xmake_sh_makefile}"
- }
-
- _gmake_add_build_objects() {
- local target=${1}
- _get_target_sourcefiles "${target}"; local sourcefiles="${_ret}"
- for sourcefile in ${sourcefiles}; do
- _get_target_objectfile "${target}" "${sourcefile}"; local objectfile="${_ret}"
- _gmake_add_build_object "${target}" "${sourcefile}" "${objectfile}"
- done
- }
-
- _gmake_add_build_target_for_gcc_clang() {
- local kind="${1}"
- local targetfile="${2}"
- local objectfiles="${3}"
- local flagname="${4}"
- path_directory "${targetfile}"; local targetdir="${_ret}"
- print "\t@mkdir -p ${targetdir}" >> "${xmake_sh_makefile}"
- print "\t\$(VV)\$(${kind}) -o ${targetfile} ${objectfiles} \$(${flagname})" >> "${xmake_sh_makefile}"
- }
-
- _gmake_add_build_target_for_ar() {
- local kind="${1}"
- local targetfile="${2}"
- local objectfiles="${3}"
- local flagname="${4}"
- path_directory "${targetfile}"; local targetdir="${_ret}"
- print "\t@mkdir -p ${targetdir}" >> "${xmake_sh_makefile}"
- print "\t\$(VV)\$(${kind}) \$(${flagname}) ${flags} ${targetfile} ${objectfiles}" >> "${xmake_sh_makefile}"
- }
-
- _gmake_add_build_target() {
- local target=${1}
- _get_targetdir "${target}"; local targetdir="${_ret}"
- _get_target_file "${target}"; local targetfile="${_ret}"
- _get_target_item "${target}" "deps"; local deps="${_ret}"
- _get_target_objectfiles "${target}"; local objectfiles="${_ret}"
-
- # get linker
- _get_target_item "${target}" "kind"; local targetkind="${_ret}"
- local toolkind=""
- case "${targetkind}" in
- binary) toolkind="ld";;
- static) toolkind="ar";;
- shared) toolkind="sh";;
- *) raise "unknown targetkind(${targetkind})!" ;;
- esac
- _get_toolchain_toolset "${_target_toolchain}" "${toolkind}"; local program="${_ret}"
- path_toolname "${program}"; local toolname="${_ret}"
-
- # get linker flags
- _get_flagname "${toolkind}"; local flagname="${_ret}"
- flagname="${target}_${flagname}"
-
- # get depfiles
- local dep=""
- local depfiles=""
- for dep in ${deps}; do
- _get_target_file "${dep}"; local depfile="${_ret}"
- if test_nz "${depfiles}"; then
- depfiles="${depfiles} ${depfile}"
- else
- depfiles="${depfile}"
- fi
- done
-
- # link target
- echo "${target}: ${targetfile}" >> "${xmake_sh_makefile}"
- echo "${targetfile}: ${depfiles}${objectfiles}" >> "${xmake_sh_makefile}"
- print "\t@echo linking.${_target_mode} ${targetfile}" >> "${xmake_sh_makefile}"
- case "${toolname}" in
- gcc) _gmake_add_build_target_for_gcc_clang "${toolkind}" "${targetfile}" "${objectfiles}" "${flagname}";;
- gxx) _gmake_add_build_target_for_gcc_clang "${toolkind}" "${targetfile}" "${objectfiles}" "${flagname}";;
- clang) _gmake_add_build_target_for_gcc_clang "${toolkind}" "${targetfile}" "${objectfiles}" "${flagname}";;
- clangxx) _gmake_add_build_target_for_gcc_clang "${toolkind}" "${targetfile}" "${objectfiles}" "${flagname}";;
- emcc) _gmake_add_build_target_for_gcc_clang "${toolkind}" "${targetfile}" "${objectfiles}" "${flagname}";;
- emxx) _gmake_add_build_target_for_gcc_clang "${toolkind}" "${targetfile}" "${objectfiles}" "${flagname}";;
- ar) _gmake_add_build_target_for_ar "${toolkind}" "${targetfile}" "${objectfiles}" "${flagname}";;
- emar) _gmake_add_build_target_for_ar "${toolkind}" "${targetfile}" "${objectfiles}" "${flagname}";;
- *) raise "unknown toolname(${toolname})!" ;;
- esac
-
- # @see https://github.com/tboox/tbox/issues/214
- if test_eq "${targetkind}" "shared"; then
- _get_target_item "${target}" "version"; local version="${_ret}"
- _get_target_soname "${target}"; local soname="${_ret}"
- if test_nz "${soname}" && test_nz "${version}"; then
- _get_target_filename "${target}"; local filename="${_ret}"
- _get_target_extension "${target}"; local extension="${_ret}"
- local targetfile_with_version="${targetdir}/${filename}.${version}"
- if test_eq "${extension}" ".dylib"; then
- path_basename "${filename}"; local basename="${_ret}"
- targetfile_with_version="${targetdir}/${basename}.${version}${extension}"
- fi
- local targetfile_with_soname="${targetdir}/${soname}"
- path_filename "${targetfile_with_version}"; local targetfilename_with_version="${_ret}"
- if test_nq "${soname}" "${filename}" && test_nq "${soname}" "${targetfilename_with_version}"; then
- print "\t@cp -p ${targetfile} ${targetfile_with_version}" >> "${xmake_sh_makefile}"
- print "\t@cd ${targetdir} && ln -sf ${targetfilename_with_version} ${soname} && ln -sf ${soname} ${filename}" >> "${xmake_sh_makefile}"
- fi
- fi
- fi
-
- # end
- echo "" >> "${xmake_sh_makefile}"
-
- # build objects
- _gmake_add_build_objects "${target}"
- }
-
- _gmake_add_build_targets() {
- local target=""
- local defaults=""
- for target in ${_xmake_sh_targets}; do
- if _is_target_default "${target}"; then
- defaults="${defaults} ${target}"
- fi
- done
- echo "default:${defaults}" >> "${xmake_sh_makefile}"
- echo "all:${_xmake_sh_targets}" >> "${xmake_sh_makefile}"
- echo ".PHONY: default all" >> "${xmake_sh_makefile}"
- echo "" >> "${xmake_sh_makefile}"
- for target in ${_xmake_sh_targets}; do
- _gmake_add_build_target "${target}"
- done
- }
-
- _gmake_add_build() {
- _gmake_add_build_targets
- }
-
- _gmake_add_run_target() {
- local target=${1}
- _get_targetdir "${target}"; local targetdir="${_ret}"
- _get_target_file "${target}"; local targetfile="${_ret}"
- if is_plat "macosx"; then
- print "\t@DYLD_LIBRARY_PATH=${targetdir} ${targetfile}" >> "${xmake_sh_makefile}"
- elif is_plat "linux" "bsd"; then
- print "\t@LD_LIBRARY_PATH=${targetdir} ${targetfile}" >> "${xmake_sh_makefile}"
- else
- print "\t@${targetfile}" >> "${xmake_sh_makefile}"
- fi
- }
-
- _gmake_add_run_targets() {
- local target=""
- local targets=""
- for target in ${_xmake_sh_targets}; do
- _get_target_item "${target}" "kind"; local kind="${_ret}"
- if test "x${kind}" = "xbinary"; then
- if _is_target_default "${target}"; then
- targets="${targets} ${target}"
- fi
- fi
- done
- echo "run:${targets}" >> "${xmake_sh_makefile}"
- for target in ${targets}; do
- _gmake_add_run_target "${target}"
- done
- echo "" >> "${xmake_sh_makefile}"
- }
-
- _gmake_add_run() {
- _gmake_add_run_targets
- }
-
- _gmake_add_clean_target() {
- local target=${1}
- local objectfile=""
- _get_target_file "${target}"; local targetfile="${_ret}"
- _get_target_objectfiles "${target}"; local objectfiles="${_ret}"
- print "\t@rm ${targetfile}" >> "${xmake_sh_makefile}"
- for objectfile in ${objectfiles}; do
- print "\t@rm ${objectfile}" >> "${xmake_sh_makefile}"
- done
-
- # @see https://github.com/tboox/tbox/issues/214
- _get_targetdir "${target}"; local targetdir="${_ret}"
- _get_target_item "${target}" "kind"; local targetkind="${_ret}"
- if test_eq "${targetkind}" "shared"; then
- _get_target_item "${target}" "version"; local version="${_ret}"
- _get_target_soname "${target}"; local soname="${_ret}"
- if test_nz "${soname}" && test_nz "${version}"; then
- _get_target_filename "${target}"; local filename="${_ret}"
- _get_target_extension "${target}"; local extension="${_ret}"
- local targetfile_with_version="${targetdir}/${filename}.${version}"
- if test_eq "${extension}" ".dylib"; then
- path_basename "${filename}"; local basename="${_ret}"
- targetfile_with_version="${targetdir}/${basename}.${version}${extension}"
- fi
- local targetfile_with_soname="${targetdir}/${soname}"
- print "\t@if test -f ${targetfile_with_soname}; then rm ${targetfile_with_soname}; fi" >> "${xmake_sh_makefile}"
- print "\t@if test -f ${targetfile_with_version}; then rm ${targetfile_with_version}; fi" >> "${xmake_sh_makefile}"
- fi
- fi
- }
-
- _gmake_add_clean_targets() {
- local target=""
- local targets=""
- for target in ${_xmake_sh_targets}; do
- if _is_target_default "${target}"; then
- targets="${targets} ${target}"
- fi
- done
- echo "clean:${targets}" >> "${xmake_sh_makefile}"
- for target in ${targets}; do
- _gmake_add_clean_target "${target}"
- done
- echo "" >> "${xmake_sh_makefile}"
- }
-
- _gmake_add_clean() {
- _gmake_add_clean_targets
- }
-
- _gmake_add_install_target() {
- local target=${1}
- _get_target_file "${target}"; local targetfile="${_ret}"
- path_filename "${targetfile}"; local filename="${_ret}"
- _get_target_item "${target}" "installdir"; local installdir="${_ret}"
- _get_target_item "${target}" "kind"; local targetkind="${_ret}"
- if test_z "${installdir}"; then
- installdir="\$(INSTALLDIR)"
- fi
-
- # before install
- _get_target_item "${target}" "before_install"; local before_install="${_ret}"
- if test_nz "${before_install}"; then
- eval ${before_install} "\${target}" "\${installdir}"
- fi
-
- # @see https://github.com/tboox/tbox/issues/214
- install_for_soname=false
- if test_eq "${targetkind}" "shared"; then
- _get_target_item "${target}" "version"; local version="${_ret}"
- _get_target_soname "${target}"; local soname="${_ret}"
- if test_nz "${soname}" && test_nz "${version}"; then
- _get_target_extension "${target}"; local extension="${_ret}"
- string_replace "${_install_libdir_default}" "\${prefix}" "${installdir}"; _install_libdir_default="${_ret}"
- local targetfile_with_version="${_install_libdir_default}/${filename}.${version}"
- if test_eq "${extension}" ".dylib"; then
- path_basename "${filename}"; local basename="${_ret}"
- targetfile_with_version="${_install_libdir_default}/${basename}.${version}${extension}"
- fi
- local targetfile_with_soname="${_install_libdir_default}/${soname}"
- path_filename "${targetfile_with_version}"; local targetfilename_with_version="${_ret}"
- if test_nq "${soname}" "${filename}" && test_nq "${soname}" "${targetfilename_with_version}"; then
- install_for_soname=true
- fi
- fi
- fi
-
- # install target file
- if test_eq "${targetkind}" "binary"; then
- string_replace "${_install_bindir_default}" "\${prefix}" "${installdir}"; _install_bindir_default="${_ret}"
- print "\t@echo installing ${targetfile} to ${_install_bindir_default}" >> "${xmake_sh_makefile}"
- print "\t@mkdir -p ${_install_bindir_default}" >> "${xmake_sh_makefile}"
- print "\t@cp -p ${targetfile} ${_install_bindir_default}/${filename}" >> "${xmake_sh_makefile}"
- elif ${install_for_soname}; then
- string_replace "${_install_libdir_default}" "\${prefix}" "${installdir}"; _install_libdir_default="${_ret}"
- print "\t@echo installing ${targetfile} to ${_install_libdir_default}" >> "${xmake_sh_makefile}"
- print "\t@mkdir -p ${_install_libdir_default}" >> "${xmake_sh_makefile}"
- print "\t@cp -p ${targetfile} ${targetfile_with_version}" >> "${xmake_sh_makefile}"
- print "\t@cd ${_install_libdir_default} && ln -sf ${targetfilename_with_version} ${soname} && ln -sf ${soname} ${filename}" >> "${xmake_sh_makefile}"
- elif test_eq "${targetkind}" "static" || test_eq "${targetkind}" "shared"; then
- string_replace "${_install_libdir_default}" "\${prefix}" "${installdir}"; _install_libdir_default="${_ret}"
- print "\t@echo installing ${targetfile} to ${_install_libdir_default}" >> "${xmake_sh_makefile}"
- print "\t@mkdir -p ${_install_libdir_default}" >> "${xmake_sh_makefile}"
- print "\t@cp -p ${targetfile} ${_install_libdir_default}/${filename}" >> "${xmake_sh_makefile}"
- fi
-
- # install header files
- _get_target_item "${target}" "headerfiles"; local headerfiles="${_ret}"
- if test_nz "${headerfiles}"; then
- string_replace "${_install_includedir_default}" "\${prefix}" "${installdir}"; _install_includedir_default="${_ret}"
- local srcheaderfile=""
- local includedir="${_install_includedir_default}"
- for srcheaderfile in ${headerfiles}; do
- string_split "${srcheaderfile}" ":"
- local srcheaderfile="${_ret}"
- local rootdir="${_ret2}"
- local prefixdir="${_ret3}"
- local filename="${_ret4}"
- if test_z "${filename}"; then
- path_filename "${srcheaderfile}"; filename="${_ret}"
- fi
- local dstheaderdir="${includedir}"
- if test_nz "${prefixdir}"; then
- dstheaderdir="${dstheaderdir}/${prefixdir}"
- fi
- local dstheaderfile="${dstheaderdir}/${filename}"
- if test_nz "${rootdir}"; then
- path_relative "${rootdir}" "${srcheaderfile}"; local subfile="${_ret}"
- dstheaderfile="${dstheaderdir}/${subfile}"
- fi
- path_directory "${dstheaderfile}"; dstheaderdir="${_ret}"
- print "\t@mkdir -p ${dstheaderdir}" >> "${xmake_sh_makefile}"
- print "\t@cp -p ${srcheaderfile} ${dstheaderfile}" >> "${xmake_sh_makefile}"
- done
- fi
-
- # install user files
- _get_target_item "${target}" "installfiles"; local installfiles="${_ret}"
- if test_nz "${installfiles}"; then
- local srcinstallfile=""
- for srcinstallfile in ${installfiles}; do
- string_split "${srcinstallfile}" ":"
- local srcinstallfile="${_ret}"
- local rootdir="${_ret2}"
- local prefixdir="${_ret3}"
- local filename="${_ret4}"
- if test_z "${filename}"; then
- path_filename "${srcinstallfile}"; filename="${_ret}"
- fi
- local dstinstalldir="${installdir}"
- if test_nz "${prefixdir}"; then
- dstinstalldir="${dstinstalldir}/${prefixdir}"
- fi
- local dstinstallfile="${dstinstalldir}/${filename}"
- if test_nz "${rootdir}"; then
- path_relative "${rootdir}" "${srcinstallfile}"; local subfile="${_ret}"
- dstinstallfile="${dstinstalldir}/${subfile}"
- fi
- path_directory "${dstinstallfile}"; dstinstalldir="${_ret}"
- print "\t@mkdir -p ${dstinstalldir}" >> "${xmake_sh_makefile}"
- print "\t@cp -p ${srcinstallfile} ${dstinstallfile}" >> "${xmake_sh_makefile}"
- done
- fi
-
- # after install
- _get_target_item "${target}" "after_install"; local after_install="${_ret}"
- if test_nz "${after_install}"; then
- eval ${after_install} "\${target}" "\${installdir}"
- fi
- }
-
- _gmake_add_install_targets() {
- local target=""
- local targets=""
- for target in ${_xmake_sh_targets}; do
- if _is_target_default "${target}"; then
- targets="${targets} ${target}"
- fi
- done
- echo "install:${targets}" >> "${xmake_sh_makefile}"
- for target in ${targets}; do
- _gmake_add_install_target "${target}"
- done
- echo "" >> "${xmake_sh_makefile}"
- }
-
- _gmake_add_install() {
- _gmake_add_install_targets
- }
-
- _gmake_done() {
- echo "makefile is generated!"
- if "${xmake_sh_diagnosis}"; then
- cat "${xmake_sh_makefile}"
- fi
- }
-
- # generate build file for gmake
- _generate_for_gmake() {
- _gmake_begin
- _gmake_add_header
- _gmake_add_switches
- _gmake_add_toolchains
- _gmake_add_flags
- _gmake_add_build
- _gmake_add_clean
- _gmake_add_install
- _gmake_add_run
- _gmake_done
- }
-
- #-----------------------------------------------------------------------------
- # generate ninja file
- #
-
- # generate build file for ninja
- _generate_for_ninja() {
- raise "Ninja generator has been not supported!"
- }
-
- #-----------------------------------------------------------------------------
- # generate build file
- #
-
- _generate_build_file() {
- if test_eq "${project_generator}" "gmake"; then
- _generate_for_gmake
- elif test_eq "${project_generator}" "ninja"; then
- _generate_for_ninja
- else
- raise "unknown generator: ${project_generator}"
- fi
- }
- _generate_build_file
|