cc-lib.tcl 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. # Copyright (c) 2011 WorkWare Systems http://www.workware.net.au/
  2. # All rights reserved
  3. # @synopsis:
  4. #
  5. # Provides a library of common tests on top of the 'cc' module.
  6. use cc
  7. # @cc-check-lfs
  8. #
  9. # The equivalent of the 'AC_SYS_LARGEFILE' macro.
  10. #
  11. # defines 'HAVE_LFS' if LFS is available,
  12. # and defines '_FILE_OFFSET_BITS=64' if necessary
  13. #
  14. # Returns 1 if 'LFS' is available or 0 otherwise
  15. #
  16. proc cc-check-lfs {} {
  17. cc-check-includes sys/types.h
  18. msg-checking "Checking if -D_FILE_OFFSET_BITS=64 is needed..."
  19. set lfs 1
  20. if {[msg-quiet cc-with {-includes sys/types.h} {cc-check-sizeof off_t}] == 8} {
  21. msg-result no
  22. } elseif {[msg-quiet cc-with {-includes sys/types.h -cflags -D_FILE_OFFSET_BITS=64} {cc-check-sizeof off_t}] == 8} {
  23. define _FILE_OFFSET_BITS 64
  24. msg-result yes
  25. } else {
  26. set lfs 0
  27. msg-result none
  28. }
  29. define-feature lfs $lfs
  30. return $lfs
  31. }
  32. # @cc-check-endian
  33. #
  34. # The equivalent of the 'AC_C_BIGENDIAN' macro.
  35. #
  36. # defines 'HAVE_BIG_ENDIAN' if endian is known to be big,
  37. # or 'HAVE_LITTLE_ENDIAN' if endian is known to be little.
  38. #
  39. # Returns 1 if determined, or 0 if not.
  40. #
  41. proc cc-check-endian {} {
  42. cc-check-includes sys/types.h sys/param.h
  43. set rc 0
  44. msg-checking "Checking endian..."
  45. cc-with {-includes {sys/types.h sys/param.h}} {
  46. if {[cctest -code {
  47. #if !defined(BIG_ENDIAN) || !defined(BYTE_ORDER)
  48. #error unknown
  49. #elif BYTE_ORDER != BIG_ENDIAN
  50. #error little
  51. #endif
  52. }]} {
  53. define-feature big-endian
  54. msg-result "big"
  55. set rc 1
  56. } elseif {[cctest -code {
  57. #if !defined(LITTLE_ENDIAN) || !defined(BYTE_ORDER)
  58. #error unknown
  59. #elif BYTE_ORDER != LITTLE_ENDIAN
  60. #error big
  61. #endif
  62. }]} {
  63. define-feature little-endian
  64. msg-result "little"
  65. set rc 1
  66. } else {
  67. msg-result "unknown"
  68. }
  69. }
  70. return $rc
  71. }
  72. # @cc-check-flags flag ?...?
  73. #
  74. # Checks whether the given C/C++ compiler flags can be used. Defines feature
  75. # names prefixed with 'HAVE_CFLAG' and 'HAVE_CXXFLAG' respectively, and
  76. # appends working flags to '-cflags' and 'AS_CFLAGS' or 'AS_CXXFLAGS'.
  77. proc cc-check-flags {args} {
  78. set result 1
  79. array set opts [cc-get-settings]
  80. switch -exact -- $opts(-lang) {
  81. c++ {
  82. set lang C++
  83. set prefix CXXFLAG
  84. }
  85. c {
  86. set lang C
  87. set prefix CFLAG
  88. }
  89. default {
  90. autosetup-error "cc-check-flags failed with unknown language: $opts(-lang)"
  91. }
  92. }
  93. foreach flag $args {
  94. msg-checking "Checking whether the $lang compiler accepts $flag..."
  95. if {[cctest -cflags $flag]} {
  96. msg-result yes
  97. define-feature $prefix$flag
  98. cc-with [list -cflags [list $flag]]
  99. define-append AS_${prefix}S $flag
  100. } else {
  101. msg-result no
  102. set result 0
  103. }
  104. }
  105. return $result
  106. }
  107. # @cc-check-standards ver ?...?
  108. #
  109. # Checks whether the C/C++ compiler accepts one of the specified '-std=$ver'
  110. # options, and appends the first working one to '-cflags' and 'AS_CFLAGS' or
  111. # 'AS_CXXFLAGS'.
  112. proc cc-check-standards {args} {
  113. array set opts [cc-get-settings]
  114. foreach std $args {
  115. if {[cc-check-flags -std=$std]} {
  116. return $std
  117. }
  118. }
  119. return ""
  120. }
  121. # Checks whether $keyword is usable as alignof
  122. proc cctest_alignof {keyword} {
  123. msg-checking "Checking for $keyword..."
  124. if {[cctest -code "int x = ${keyword}(char), y = ${keyword}('x');"]} then {
  125. msg-result ok
  126. define-feature $keyword
  127. } else {
  128. msg-result "not found"
  129. }
  130. }
  131. # @cc-check-c11
  132. #
  133. # Checks for several C11/C++11 extensions and their alternatives. Currently
  134. # checks for '_Static_assert', '_Alignof', '__alignof__', '__alignof'.
  135. proc cc-check-c11 {} {
  136. msg-checking "Checking for _Static_assert..."
  137. if {[cctest -code {
  138. _Static_assert(1, "static assertions are available");
  139. }]} then {
  140. msg-result ok
  141. define-feature _Static_assert
  142. } else {
  143. msg-result "not found"
  144. }
  145. cctest_alignof _Alignof
  146. cctest_alignof __alignof__
  147. cctest_alignof __alignof
  148. }
  149. # @cc-check-alloca
  150. #
  151. # The equivalent of the 'AC_FUNC_ALLOCA' macro.
  152. #
  153. # Checks for the existence of 'alloca'
  154. # defines 'HAVE_ALLOCA' and returns 1 if it exists.
  155. proc cc-check-alloca {} {
  156. cc-check-some-feature alloca {
  157. cctest -includes alloca.h -code { alloca (2 * sizeof (int)); }
  158. }
  159. }
  160. # @cc-signal-return-type
  161. #
  162. # The equivalent of the 'AC_TYPE_SIGNAL' macro.
  163. #
  164. # defines 'RETSIGTYPE' to 'int' or 'void'.
  165. proc cc-signal-return-type {} {
  166. msg-checking "Checking return type of signal handlers..."
  167. cc-with {-includes {sys/types.h signal.h}} {
  168. if {[cctest -code {return *(signal (0, 0)) (0) == 1;}]} {
  169. set type int
  170. } else {
  171. set type void
  172. }
  173. define RETSIGTYPE $type
  174. msg-result $type
  175. }
  176. }