configure 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #!/usr/bin/tclsh
  2. #
  3. # SRT - Secure, Reliable, Transport
  4. # Copyright (c) 2018 Haivision Systems Inc.
  5. #
  6. # This Source Code Form is subject to the terms of the Mozilla Public
  7. # License, v. 2.0. If a copy of the MPL was not distributed with this
  8. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. #
  10. # This is a general-purpose configure script, which is a user-friendly
  11. # wrapper to call the "cmake" command.
  12. # There are two options that are handled specifically:
  13. #
  14. # --help: show the list of official options
  15. # --prefix: alias to --cmake-install-prefix
  16. # The processing done automatically on all options by default is:
  17. # Every option like:
  18. # --long-c++-option
  19. # --cmake-special-option=ON
  20. # Turns into:
  21. # -DLONG_CXX_OPTION=1
  22. # -DCMAKE_SPECIAL_OPTION=ON
  23. #
  24. # In the configuration file, "configure-data.tcl", you can add
  25. # special processing for options and define explicit options
  26. # in the "::options" dictionary. Explicit options (in contrast
  27. # to "blind" options) have additional properties:
  28. #
  29. # - only those options are mentioned with --help
  30. # - you can pass a value for this option without = character
  31. # - you can specify --disable-option instead of --enable-option=0
  32. #
  33. # In "configure-data.tcl", beside ::options, you can define "preprocess" and
  34. # "postprocess" procedures. In "preprocess", use ::optval array to modify the
  35. # list of options to be processed further. Additionally in "postprocess"
  36. # procedure you can influence directly the options for "cmake" command in
  37. # ::cmakeopt variable (modifying ::optval in "postprocess" is useless).
  38. # The idea is that CMakeLists.txt contains things that are highly
  39. # customizable, but no system or option autodetection AWA "sensible
  40. # defaults" are provided. This is done by this script.
  41. set here [file dirname $argv0]
  42. set options ""
  43. set toolchain_changers ""
  44. source $here/configure-data.tcl
  45. # Update alias with default alias
  46. dict set alias --prefix --cmake-install-prefix=
  47. proc resolve opt {
  48. set type arg
  49. set pos [string first $opt =]
  50. if { $pos == -1 } {
  51. set type bool
  52. set mark ""
  53. } else {
  54. set type arg
  55. set mark [string range $opt $pos+1 end]
  56. set opt [string range $opt 0 $pos-1]
  57. }
  58. set var [string toupper [string map {- _ + x} $opt]]
  59. return [list --$opt $var $type $mark]
  60. }
  61. # Check if a --disable option has its --enable counterpart. If so,
  62. # then just invert the option.
  63. proc resolve_disablers {} {
  64. set enablers ""
  65. set optkeys_len [llength $::optkeys]
  66. for {set pos 0} {$pos < $optkeys_len} {incr pos} {
  67. set opt [lindex $::optkeys $pos]
  68. if { [string match --disable-* $opt] } {
  69. set inverted enable-[string range $opt 10 end]
  70. if { $inverted in [dict keys $::options] } {
  71. lset ::optkeys $pos --$inverted
  72. set val $::optval($opt)
  73. unset ::optval($opt)
  74. if { $val == "" || ![string is boolean $val] } {
  75. set ::optval(--$inverted) 0
  76. } else {
  77. set ::optval(--$inverted) [expr {!$val}]
  78. }
  79. puts "NOTE: $opt changed into --$inverted=$::optval(--$inverted)"
  80. }
  81. }
  82. }
  83. }
  84. foreach {o desc} $options {
  85. lassign [resolve $o] optname optvar opttype optmark
  86. set opt($optname) [list $optvar $opttype $optmark]
  87. set info($optname) $desc
  88. }
  89. if { $argv == "--help" || $argv == "-h" } {
  90. puts stderr "Usage: ./configure \[options\]"
  91. puts stderr "OPTIONS:"
  92. foreach o [lsort [array names opt]] {
  93. lassign $opt($o) unu type mark
  94. set imark ""
  95. if { $mark != "" } {
  96. set imark "=$mark"
  97. }
  98. puts stderr "\t$o$imark - $info($o)"
  99. }
  100. puts stderr "NOTE1: Option list may be incomplete. Refer to variables in CMakeLists.txt"
  101. puts stderr "NOTE2: Non-internal options turn e.g. --enable-c++11 into cmake -DENABLE_CXX11=1"
  102. puts stderr "NOTE3: You can use --disable-x instead of --enable-x=0 for the above options."
  103. exit 1
  104. }
  105. if { [info proc init] != "" } {
  106. init
  107. }
  108. #parray opt
  109. set saveopt ""
  110. set optkeys ""
  111. set dryrun 0
  112. set type ""
  113. foreach a $argv {
  114. if { [info exists val] } { unset val }
  115. if { $saveopt != "" } {
  116. set optval($saveopt) $a
  117. set saveopt ""
  118. continue
  119. }
  120. if { [string range $a 0 1] != "--" } {
  121. error "Unexpected argument '$a'. Options must start with --"
  122. }
  123. if { $a == "--dryrun" } {
  124. set dryrun 1
  125. continue
  126. }
  127. set type ""
  128. if { [set a1 [string first = $a]] != -1 } {
  129. # Do not split. Options may include =.
  130. set val [string range $a $a1+1 end]
  131. set a [string range $a 0 $a1-1]
  132. }
  133. if { [dict exists $::alias $a] } {
  134. set aname [dict get $::alias $a]
  135. if { [string first = $aname] != -1 } {
  136. lassign [split $aname =] a aval
  137. set type arg
  138. }
  139. }
  140. if { ![info exists opt($a)] } {
  141. #puts stderr "WARNING: Unknown option: $a"
  142. # But still, simply turn the option to assign-based use.
  143. lassign [resolve [string range $a 2 end]] oname var
  144. if { ![info exists val] && $type == "" } {
  145. set type bool
  146. }
  147. } else {
  148. lassign $opt($a) var type
  149. }
  150. if { $type == "bool" } {
  151. if { ![info exists val] } {
  152. set val 1
  153. }
  154. set optval($a) $val
  155. } elseif { [info exists val] } {
  156. set optval($a) $val
  157. } else {
  158. set saveopt $a
  159. }
  160. lappend optkeys $a
  161. }
  162. if { $saveopt != "" } {
  163. error "Extra unhandled argument: $saveopt"
  164. }
  165. # Save the original call into config-status.sh
  166. set ofd [open config-status.sh w]
  167. puts $ofd "#!/bin/bash"
  168. puts -nonewline $ofd "$argv0 "
  169. foreach a $argv {
  170. set len 1
  171. if {[catch {llength $a} len] || $len > 1 } {
  172. puts -nonewline $ofd "'$a' "
  173. } else {
  174. puts -nonewline $ofd "$a "
  175. }
  176. }
  177. puts $ofd ""
  178. close $ofd
  179. file attributes config-status.sh -permissions +x
  180. set cmakeopt ""
  181. resolve_disablers
  182. if { [info proc preprocess] != "" } {
  183. preprocess
  184. }
  185. # Check if there were new values added not added to optkeys
  186. foreach a [array names optval] {
  187. if { $a ni $optkeys } {
  188. lappend optkeys $a
  189. }
  190. }
  191. foreach a $optkeys {
  192. if { ![info exists optval($a)] } {
  193. continue ;# user action might have removed it.
  194. }
  195. if { ![info exists opt($a)] } {
  196. #puts stderr "WARNING: Unknown option: $a"
  197. # But still, simply turn the option to assign-based use.
  198. lassign [resolve [string range $a 2 end]] oname var
  199. if { ![info exists val] && $type == "" } {
  200. set type bool
  201. }
  202. } else {
  203. lassign $opt($a) var type
  204. }
  205. set val $optval($a)
  206. lappend cmakeopt "-D$var=$val"
  207. }
  208. if { [info proc postprocess] != "" } {
  209. postprocess
  210. }
  211. #puts "VARSPEC: $cmakeopt"
  212. set cmd [list cmake $here {*}$cmakeopt]
  213. puts "Running: $cmd"
  214. if { !$dryrun} {
  215. if { [catch {exec 2>@stderr >@stdout {*}$cmd} result] } {
  216. puts "CONFIGURE: cmake reported error: $result"
  217. }
  218. } else {
  219. puts "(not really - dry run)"
  220. }