config_functions 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. # Auxiliary functions for custom build system
  2. # Copyright (c) 2002 Serge van den Boom
  3. #
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program; if not, write to the Free Software
  16. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. BUILDLOG=/dev/null
  18. TEMPFILE="/tmp/build.$$.tmp"
  19. # Description: prints a command to stdout and then executes it
  20. # Arguments: command with arguments
  21. # Returns: the return value of the command
  22. echo_and_perform() {
  23. cat << EOF
  24. $@
  25. EOF
  26. "$@"
  27. }
  28. # Description: read text from stdin to use as a c file to compile
  29. # Arguments: $1 - CFLAGS to use for compilation (optional)
  30. # $2 - LDFLAGS to use for linking (optional)
  31. # Returns: 0 - if compile successful
  32. # something else - if compile failed
  33. try_compile_c() {
  34. if [ -z "$COMPILE" ]; then
  35. echo "Fatal: Program \$COMPILE is not defined!" >&2
  36. exit 1
  37. fi
  38. cat > "$TEMPFILE.c"
  39. echo_and_perform $COMPILE $1 $2 "$TEMPFILE.c" \
  40. -o /dev/null 2>&1 >> "$BUILDLOG"
  41. RESULT=$?
  42. rm -f "$TEMPFILE.c"
  43. return $RESULT
  44. }
  45. # Description: read text from stdin to use as a c file to compile
  46. # Arguments: $1 - CFLAGS to use for compilation (optional)
  47. # $2 - LDFLAGS to use for linking (optional)
  48. # Returns: -1 - if compile failed
  49. # otherwise - exit status of the program
  50. try_compile_and_run_c() {
  51. if [ -z "$COMPILE" ]; then
  52. echo "Fatal: Program \$COMPILE is not defined!" >&2
  53. exit 1
  54. fi
  55. cat > "$TEMPFILE.c"
  56. echo_and_perform $COMPILE $1 $2 "$TEMPFILE.c" \
  57. -o "$TEMPFILE.out" 2>&1 >> "$BUILDLOG"
  58. if [ $? -ne 0 ]; then
  59. return -1
  60. fi
  61. rm -f -- "$TEMPFILE.c"
  62. "$TEMPFILE.out"
  63. RESULT=$?
  64. rm -f -- "$TEMPFILE.out"
  65. return $RESULT
  66. }
  67. # Description: Output a message to stderr, unless BUILD_SILENT is set
  68. # Arguments: the message
  69. build_message() {
  70. if [ -z "$BUILD_SILENT" ]; then
  71. cat >&2 << EOF
  72. $@
  73. EOF
  74. fi
  75. }
  76. # Description: Output a message to stderr, unless BUILD_SILENT is set
  77. # Arguments: the message
  78. build_message() {
  79. if [ -z "$BUILD_SILENT" ]; then
  80. cat >&2 << EOF
  81. $@
  82. EOF
  83. fi
  84. }
  85. # Description: check if a program is present in the path
  86. # Arguments:
  87. have_program() {
  88. local TEMP_NAME TEMP_FILE TEMP_VERSION
  89. eval eval TEMP_NAME="\\\"\$PROG_${1}_NAME\\\""
  90. if [ -z "$TEMP_NAME" ]; then
  91. echo "Fatal: Program '$1' is not defined!" >&2
  92. exit 1
  93. fi
  94. eval eval TEMP_FILE="\\\"\$PROG_${1}_FILE\\\""
  95. type "$TEMP_FILE" 2>&1 > /dev/null
  96. if [ $? -ne 0 ]; then
  97. build_message "$TEMP_NAME not found."
  98. return 1
  99. fi
  100. if [ $# -gt 1 ]; then
  101. # Minimum version supplied
  102. eval eval TEMP_VERSION="\\\"\$PROG_${1}_VERSION\\\""
  103. if [ -z "$TEMP_VERSION" ]; then
  104. echo "Fatal: Could not determine version of $TEMP_NAME" >&2
  105. exit 1
  106. fi
  107. if [ "$TEMP_VERSION" \< "$2" ]; then
  108. build_message "Found version $TEMP_VERSION of $TEMP_NAME, \
  109. but version $2 is required!"
  110. return 1
  111. fi
  112. build_message "$TEMP_NAME version $TEMP_VERSION found."
  113. return 0
  114. fi
  115. build_message "$TEMP_NAME found."
  116. return 0
  117. }
  118. # Description: check if a library is present on the system
  119. # Arguments: $1 - The name of the library without 'lib' of '.so'
  120. # $2 - (optional) minimum version required
  121. # Pre: variables LIB_${1}_NAME, LIB_${1}_CFLAGS, and
  122. # LIB_${1}_LDFLAGS are expected to exist. If two arguments are
  123. # supplied, so is LIB_${1}_VERSION.
  124. # Returns: 0 - if the library is found
  125. # 1 - if the library is not found
  126. have_library() {
  127. local LIB TEMP_NAME TEMP_PRESENT TEMP_LDFLAGS TEMP_CFLAGS \
  128. TEMP_VERSION
  129. LIB="$1"
  130. eval eval TEMP_NAME="\\\"\$LIB_${1}_NAME\\\""
  131. if [ -z "$TEMP_NAME" ]; then
  132. echo "Fatal: Library '$1' is not defined!" >&2
  133. exit 1
  134. fi
  135. eval TEMP_PRESENT="\$LIB_${LIB}_PRESENT"
  136. if [ -n "$TEMP_PRESENT" ]; then
  137. return "$TEMP_PRESENT"
  138. fi
  139. eval eval TEMP_LDFLAGS="\\\"\$LIB_${LIB}_LDFLAGS\\\""
  140. eval eval TEMP_CFLAGS="\\\"\$LIB_${LIB}_CFLAGS\\\""
  141. try_compile_c "$TEMP_CFLAGS" "$TEMP_LDFLAGS" << EOF
  142. int main() {
  143. return 0;
  144. }
  145. EOF
  146. if [ $? -ne 0 ]; then
  147. eval "LIB_${LIB}_PRESENT"=1
  148. build_message "$TEMP_NAME not found."
  149. return 1
  150. fi
  151. if [ $# -gt 1 ]; then
  152. # Minimum version supplied
  153. eval eval TEMP_VERSION="\\\"\$LIB_${LIB}_VERSION\\\""
  154. if [ -z "$TEMP_VERSION" ]; then
  155. eval "LIB_${LIB}_PRESENT"=1
  156. echo "Fatal: Could not determine version of $TEMP_NAME" >&2
  157. exit 1
  158. fi
  159. if [ "$TEMP_VERSION" \< "$2" ]; then
  160. eval "LIB_${LIB}_PRESENT"=1
  161. build_message "Found version $TEMP_VERSION of $TEMP_NAME, \
  162. but version $2 is required"
  163. return 1
  164. fi
  165. eval "LIB_${LIB}_PRESENT"=0
  166. build_message "$TEMP_NAME version $TEMP_VERSION found."
  167. return 0
  168. fi
  169. eval "LIB_${LIB}_PRESENT"=0
  170. build_message "$TEMP_NAME found."
  171. return 0
  172. }
  173. # Description: check if a library is present on the system.
  174. # If it is, add the appropriate flags to CFLAGS and LDFLAGS.
  175. # If not, bail out.
  176. # Arguments: $1 - The name of the library without 'lib' of '.so'
  177. # $2 - (optional) minimum version required
  178. # Pre: variables LIB_${1}_NAME, LIB_${1}_CFLAGS, and
  179. # LIB_${1}_LDFLAGS are expected to exist. If two arguments are
  180. # supplied, so is LIB_${1}_VERSION.
  181. use_library() {
  182. local TEMP_CFLAGS TEMP_LDFLAGS
  183. have_library "$@"
  184. [ $? -eq 0 ] || exit 1
  185. eval eval TEMP_CFLAGS="\\\"\$LIB_${1}_CFLAGS\\\""
  186. eval eval TEMP_LDFLAGS="\\\"\$LIB_${1}_LDFLAGS\\\""
  187. CFLAGS="$CFLAGS $TEMP_CFLAGS"
  188. LDFLAGS="$LDFLAGS $TEMP_LDFLAGS"
  189. return 0
  190. }
  191. # Description: check if a symbol is defined.
  192. # Arguments: $1 - the name of the symbol
  193. have_symbol() {
  194. local SYMBOL
  195. SYMBOL="$1"
  196. # TODO: I'll want the include handling to be done differently
  197. # eventually.
  198. try_compile_c "$TEMP_CFLAGS" "$TEMP_LDFLAGS" << EOF 2>&1 > /dev/null
  199. #include <stdio.h>
  200. #include <sys/types.h>
  201. #include <stdlib.h>
  202. #include <unistd.h>
  203. #include <string.h>
  204. int main() {
  205. (void) $SYMBOL;
  206. return 0;
  207. }
  208. EOF
  209. if [ $? -gt 0 ]; then
  210. build_message "Symbol '$SYMBOL' not found."
  211. return 1
  212. fi
  213. build_message "Symbol '$SYMBOL' found."
  214. return 0
  215. }
  216. # Description: check if a symbol is defined.
  217. # set HAVE_<NAME> accordingly, where <NAME> is the capitalized
  218. # name of the symbol.
  219. # Arguments: $1 - the name of the symbol
  220. define_have_symbol() {
  221. local NAME VALUE
  222. NAME=`$TR a-z A-Z << EOF
  223. $1
  224. EOF
  225. `
  226. if have_symbol "$1"; then
  227. add_symbol "HAVE_$NAME" "#define HAVE_$NAME"
  228. else
  229. add_symbol "HAVE_$NAME" "#undef HAVE_$NAME"
  230. fi
  231. }
  232. # Description: Add a symbol to be replaced by substitute_vars
  233. # $HAVE_SYMBOLS will contain the variable names of all
  234. # symbols added by define_have_symbol and should be passed to
  235. # substitute_vars for the file you want them in.
  236. # Arguments: $1 - the symbol to add
  237. # $2 - the value of the symbol
  238. add_symbol() {
  239. local NAME
  240. eval NAME="$1"
  241. eval "$NAME"=\"\$2\"
  242. HAVE_SYMBOLS="$HAVE_SYMBOLS $NAME"
  243. }
  244. check_endianness() {
  245. try_compile_and_run_c << EOF
  246. int main() {
  247. int i;
  248. i = 1;
  249. return *((unsigned char *) &i);
  250. }
  251. EOF
  252. if [ $? -eq 0 ]; then
  253. build_message "Big-endian machine."
  254. add_symbol WORDS_BIGENDIAN "#define WORDS_BIGENDIAN"
  255. else
  256. build_message "Little-endian machine."
  257. add_symbol WORDS_BIGENDIAN "#undef WORDS_BIGENDIAN"
  258. fi
  259. }
  260. # Description: substitute variables in files.
  261. # Every supplied variable name found between @'s in the
  262. # supplied files, is replaced by its value.
  263. # Arguments: $1 - The name of the variable which contains a list of
  264. # variables to substitute in the files.
  265. # $2 - The name of the variable which contains a list of
  266. # files to substitute variables in.
  267. # If a filename ends on .in, that filename is used as
  268. # source, and the filename without .in as target.
  269. # If a filename doesn't end on .in, that filename is used
  270. # as target, and the filename with .in attached as source.
  271. substitute_vars() {
  272. local VARS VAR VALUE FILES FILE
  273. eval VARS=\"\$$1\"
  274. eval FILES=\"\$$2\"
  275. for VAR in $VARS; do
  276. # Using CR as a seperator, as it's unlikely that's used in
  277. # $VAR itself.
  278. eval VALUE=\"\$$VAR\"
  279. cat << EOF
  280. s @${VAR}@ ${VALUE} g
  281. EOF
  282. done > "${TEMPFILE}.sed"
  283. for FILE in $FILES; do
  284. FILE="${FILE%.in}"
  285. $SED -f "${TEMPFILE}.sed" < "$FILE".in > "$FILE"
  286. done
  287. rm -- "${TEMPFILE}.sed"
  288. }
  289. # Include information about programs we can detect
  290. . build/config_proginfo
  291. # Some initialisations
  292. HAVE_SYMBOLS=""
  293. # Requirements for the config program itself
  294. have_program sed || exit 1
  295. SED="$PROG_sed_FILE"
  296. have_program tr || exit 1
  297. TR="$PROG_tr_FILE"
  298. have_program make || exit 1
  299. MAKE="$PROG_make_FILE"