configure-data.tcl 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. #
  2. # SRT - Secure, Reliable, Transport
  3. # Copyright (c) 2018 Haivision Systems Inc.
  4. #
  5. # This Source Code Form is subject to the terms of the Mozilla Public
  6. # License, v. 2.0. If a copy of the MPL was not distributed with this
  7. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
  8. #
  9. # API description:
  10. # Expected variables:
  11. # - options: dictionary "option-name" : "description"
  12. # if there's '=' in option name, it expects an argument. Otherwise it's boolean.
  13. # - alias: optional, you can make shortcuts to longer named options. Remember to use = in target name.
  14. #
  15. # Optional procedures:
  16. # - preprocess: run before command-line arguments ($argv) are reviewed
  17. # - postprocess: run after options are reviewed and all data filled in
  18. #
  19. # Available variables in postprocess:
  20. #
  21. # - optval (array): contains all option names with their assigned values
  22. # - cmakeopt (scalar): a list of all options for "cmake" command line
  23. # Options processed here internally, not passed to cmake
  24. set internal_options {
  25. with-compiler-prefix=<prefix> "set C/C++ toolchains <prefix>gcc and <prefix>g++"
  26. with-compiler-type=<name> "compiler type: gcc(default), cc, others simply add ++ for C++"
  27. with-srt-name=<name> "Override srt library name"
  28. with-haicrypt-name=<name> "Override haicrypt library name (if compiled separately)"
  29. with-atomic=<spec> "Select implementation for atomics (compiler-intrinsics or sync-mutex)"
  30. }
  31. # Options that refer directly to variables used in CMakeLists.txt
  32. set cmake_options {
  33. cygwin-use-posix "Should the POSIX API be used for cygwin. Ignored if the system isn't cygwin. (default: OFF)"
  34. enable-c++11 "Should the c++11 parts (srt-live-transmit) be enabled (default: ON, with gcc < 4.7 OFF)"
  35. enable-apps "Should the Support Applications be Built? (default: ON)"
  36. enable-bonding "Enable 'bonding' SRT feature (default: OFF)"
  37. enable-testing "Should developer testing applications be built (default: OFF)"
  38. enable-profile "Should instrument the code for profiling. Ignored for non-GNU compiler. (default: OFF)"
  39. enable-logging "Should logging be enabled (default: ON)"
  40. enable-heavy-logging "Should heavy debug logging be enabled (default: OFF)"
  41. enable-haicrypt-logging "Should logging in haicrypt be enabled (default: OFF)"
  42. enable-pktinfo "Should pktinfo reading and using be enabled (POSIX only) (default: OFF)"
  43. enable-shared "Should libsrt be built as a shared library (default: ON)"
  44. enable-static "Should libsrt be built as a static library (default: ON)"
  45. enable-relative-libpath "Should applications contain relative library paths, like ../lib (default: OFF)"
  46. enable-getnameinfo "In-logs sockaddr-to-string should do rev-dns (default: OFF)"
  47. enable-unittests "Enable Unit Tests (will download Google UT) (default: OFF)"
  48. enable-encryption "Should encryption features be enabled (default: ON)"
  49. enable-c++-deps "Extra library dependencies in srt.pc for C language (default: ON)"
  50. use-static-libstdc++ "Should use static rather than shared libstdc++ (default: OFF)"
  51. enable-inet-pton "Set to OFF to prevent usage of inet_pton when building against modern SDKs (default: ON)"
  52. enable-code-coverage "Enable code coverage reporting (default: OFF)"
  53. enable-monotonic-clock "Enforced clock_gettime with monotonic clock on GC CV /temporary fix for #729/ (default: OFF)"
  54. enable-thread-check "Enable #include <threadcheck.h> that implements THREAD_* macros"
  55. enable-stdc++-sync "Use standard C++11 chrono/threads instead of pthread wrapper (default: OFF, on Windows: ON)"
  56. use-openssl-pc "Use pkg-config to find OpenSSL libraries (default: ON)"
  57. openssl-use-static-libs "Link OpenSSL statically (default: OFF)."
  58. use-busy-waiting "Enable more accurate sending times at a cost of potentially higher CPU load (default: OFF)"
  59. use-gnustl "Get c++ library/headers from the gnustl.pc"
  60. enable-sock-cloexec "Enable setting SOCK_CLOEXEC on a socket (default: ON)"
  61. enable-show-project-config "Enables use of ShowProjectConfig() in cmake (default: OFF)"
  62. enable-new-rcvbuffer "Enables the new receiver buffer implementation (default: ON)"
  63. enable-clang-tsa "Enable Clang's Thread-Safety-Analysis (default: OFF)"
  64. atomic-use-srt-sync-mutex "Use mutex to implement atomics (alias: --with-atomic=sync-mutex) (default: OFF)"
  65. use-enclib "Encryption library to be used: openssl(default), gnutls, mbedtls"
  66. enable-debug=<0,1,2> "Enable debug mode (0=disabled, 1=debug, 2=rel-with-debug)"
  67. pkg-config-executable=<filepath> "pkg-config executable"
  68. openssl-crypto-library=<filepath> "OpenSSL: Path to a libcrypto library."
  69. openssl-include-dir=<path> "OpenSSL: Path to includes."
  70. openssl-ssl-library=<filepath> "OpenSSL: Path to a libssl library."
  71. pthread-include-dir=<path> "PThread: Path to includes"
  72. pthread-library=<filepath> "PThread: Path to the pthread library."
  73. }
  74. set options $internal_options$cmake_options
  75. # Just example. Available in the system.
  76. set alias {
  77. --prefix --cmake-install-prefix=
  78. }
  79. proc pkg-config args {
  80. return [string trim [exec pkg-config {*}$args]]
  81. }
  82. proc flagval v {
  83. set out ""
  84. foreach o $v {
  85. lappend out [string trim [string range $o 2 en]]
  86. }
  87. return $out
  88. }
  89. set haicrypt_name ""
  90. set srt_name ""
  91. proc preprocess {} {
  92. # Prepare windows basic path info
  93. set ::CYGWIN 0
  94. set e [catch {exec uname -o} res]
  95. # We have Cygwin, if uname -o returns "cygwin" and does not fail.
  96. if { !$e && $res == "Cygwin" } {
  97. set ::CYGWIN 1
  98. puts "CYGWIN DETECTED"
  99. }
  100. set ::HAVE_LINUX [expr {$::tcl_platform(os) == "Linux"}]
  101. set ::HAVE_DARWIN [expr {$::tcl_platform(os) == "Darwin"}]
  102. set ::CYGWIN_USE_POSIX 0
  103. if { "--cygwin-use-posix" in $::optkeys } {
  104. set ::CYGWIN_USE_POSIX 1
  105. }
  106. set ::HAVE_WINDOWS 0
  107. if { $::tcl_platform(platform) == "windows" } {
  108. puts "WINDOWS PLATFORM detected"
  109. set ::HAVE_WINDOWS 1
  110. }
  111. if { $::CYGWIN && !$::CYGWIN_USE_POSIX } {
  112. puts "CYGWIN - MINGW enforced"
  113. # Make Cygwin tools see it right, to compile for MinGW
  114. if { "--with-compiler-prefix" ni $::optkeys } {
  115. set ::optval(--with-compiler-prefix) /bin/x86_64-w64-mingw32-
  116. }
  117. # Extract drive C: information
  118. set drive_path [exec mount -p | tail -1 | cut {-d } -f 1]
  119. set ::DRIVE_C $drive_path/c
  120. set ::HAVE_WINDOWS 1
  121. } else {
  122. # Don't check for Windows, non-Windows parts will not use it.
  123. set ::DRIVE_C C:
  124. }
  125. # Alias to old name --with-gnutls, which enforces using gnutls instead of openssl
  126. if { [info exists ::optval(--with-gnutls)] } {
  127. unset ::optval(--with-gnutls)
  128. set ::optval(--use-enclib) gnutls
  129. puts "WARNING: --with-gnutls is a deprecated alias to --use-enclib=gnutls, please use the latter one"
  130. }
  131. # Alias to old name --use-gnutls, which enforces using gnutls instead of openssl
  132. if { [info exists ::optval(--use-gnutls)] } {
  133. unset ::optval(--use-gnutls)
  134. set ::optval(--use-enclib) gnutls
  135. puts "WARNING: --use-gnutls is a deprecated alias to --use-enclib=gnutls, please use the latter one"
  136. }
  137. if { [info exists ::optval(--with-target-path)] } {
  138. set ::target_path $::optval(--with-target-path)
  139. unset ::optval(--with-target-path)
  140. puts "NOTE: Explicit target path: $::target_path"
  141. }
  142. if { "--with-srt-name" in $::optkeys } {
  143. set ::srt_name $::optval(--with-srt-name)
  144. unset ::optval(--with-srt-name)
  145. }
  146. if { "--with-haicrypt-name" in $::optkeys } {
  147. set ::haicrypt_name $::optval(--with-haicrypt-name)
  148. unset ::optval(--with-haicrypt-name)
  149. }
  150. if { "--with-atomic" in $::optkeys } {
  151. switch -- $::optval(--with-atomic) {
  152. compiler-intrinsics {
  153. }
  154. sync-mutex {
  155. set ::optval(--atomic-use-srt-sync-mutex) 1
  156. }
  157. default {
  158. puts "ERROR: --with-atomic option accepts two values: compiler-intrinsics (default) or sync-mutex"
  159. exit 1
  160. }
  161. }
  162. unset ::optval(--with-atomic)
  163. }
  164. }
  165. proc GetCompilerCommand {} {
  166. # Expect that the compiler was set through:
  167. # --with-compiler-prefix
  168. # --cmake-c[++]-compiler
  169. # (cmake-toolchain-file will set things up without the need to check things here)
  170. set compiler gcc
  171. if { [info exists ::optval(--with-compiler-type)] } {
  172. set compiler $::optval(--with-compiler-type)
  173. }
  174. if { [info exists ::optval(--with-compiler-prefix)] } {
  175. set prefix $::optval(--with-compiler-prefix)
  176. return ${prefix}$compiler
  177. } else {
  178. return $compiler
  179. }
  180. if { [info exists ::optval(--cmake-c-compiler)] } {
  181. return $::optval(--cmake-c-compiler)
  182. }
  183. if { [info exists ::optval(--cmake-c++-compiler)] } {
  184. return $::optval(--cmake-c++-compiler)
  185. }
  186. if { [info exists ::optval(--cmake-cxx-compiler)] } {
  187. return $::optval(--cmake-cxx-compiler)
  188. }
  189. puts "NOTE: Cannot obtain compiler, assuming toolchain file will do what's necessary"
  190. return ""
  191. }
  192. proc postprocess {} {
  193. set iscross 0
  194. # Check if there was any option that changed the toolchain. If so, don't apply any autodetection-based toolchain change.
  195. set all_options [array names ::optval]
  196. set toolchain_changed no
  197. foreach changer {
  198. --with-compiler-prefix
  199. --with-compiler-type
  200. --cmake-c-compiler
  201. --cmake-c++-compiler
  202. --cmake-cxx-compiler
  203. --cmake-toolchain-file
  204. } {
  205. if { $changer in $all_options } {
  206. puts "NOTE: toolchain changed by '$changer' option"
  207. set toolchain_changed yes
  208. break
  209. }
  210. }
  211. set cygwin_posix 0
  212. if { "--cygwin-use-posix" in $all_options } {
  213. # Will enforce OpenSSL autodetection
  214. set cygwin_posix 1
  215. }
  216. if { $toolchain_changed } {
  217. # Check characteristics of the compiler - in particular, whether the target is different
  218. # than the current target.
  219. set compiler_path ""
  220. set target_platform ""
  221. set cmd [GetCompilerCommand]
  222. if { $cmd != "" } {
  223. set gcc_version [exec $cmd -v 2>@1]
  224. set target ""
  225. set compiler_path [file dirname $cmd]
  226. foreach l [split $gcc_version \n] {
  227. if { [string match Target:* $l] } {
  228. set target [lindex $l 1] ;# [0]Target: [1]x86_64-some-things-further
  229. set target_platform [lindex [split $target -] 0] ;# [0]x86_64 [1]redhat [2]linux
  230. break
  231. }
  232. }
  233. if { $target_platform == "" } {
  234. puts "NOTE: can't obtain target from '[file tail $cmd] -v': $l - ASSUMING HOST compiler"
  235. } else {
  236. if { $target_platform != $::tcl_platform(machine) } {
  237. puts "NOTE: foreign target type detected ($target)" ;# - setting CROSSCOMPILING flag"
  238. #lappend ::cmakeopt "-DHAVE_CROSSCOMPILER=1"
  239. set iscross 1
  240. }
  241. }
  242. } else {
  243. puts "CONFIGURE: default compiler used"
  244. }
  245. }
  246. if { $::srt_name != "" } {
  247. lappend ::cmakeopt "-DTARGET_srt=$::srt_name"
  248. }
  249. if { $::haicrypt_name != "" } {
  250. lappend ::cmakeopt "-DTARGET_haicrypt=$::haicrypt_name"
  251. }
  252. set have_openssl 0
  253. if { [lsearch -glob $::optkeys --openssl*] != -1 } {
  254. set have_openssl 1
  255. }
  256. set have_gnutls 0
  257. if { [lsearch -glob $::optkeys --use-gnutls] != -1 } {
  258. set have_gnutls 1
  259. }
  260. if { $have_openssl && $have_gnutls } {
  261. puts "NOTE: SSL library is exclusively selectable. Thus, --use-gnutls option will be ignored"
  262. set have_gnutls 0
  263. }
  264. if { $have_gnutls } {
  265. lappend ::cmakeopt "-DUSE_GNUTLS=ON"
  266. }
  267. if {$iscross} {
  268. proc check-target-path {path} {
  269. puts "Checking path '$path'"
  270. if { [file isdir $path]
  271. && [file isdir $path/bin]
  272. && [file isdir $path/include]
  273. && ([file isdir $path/lib] || [file isdir $path/lib64]) } {
  274. return yes
  275. }
  276. return no
  277. }
  278. if { ![info exists ::target_path] } {
  279. # Try to autodetect the target path by having the basic 3 directories.
  280. set target_path ""
  281. set compiler_prefix [file dirname $compiler_path] ;# strip 'bin' directory
  282. puts "NOTE: no --with-target-path found, will try to autodetect at $compiler_path"
  283. foreach path [list $compiler_path $compiler_prefix/$target] {
  284. if { [check-target-path $path] } {
  285. set target_path $path
  286. puts "NOTE: target path detected: $target_path"
  287. break
  288. }
  289. }
  290. if { $target_path == "" } {
  291. puts "ERROR: Can't determine compiler's platform files root path (using compiler command path). Specify --with-target-path."
  292. exit 1
  293. }
  294. } else {
  295. set target_path $::target_path
  296. # Still, check if correct.
  297. if { ![check-target-path $target_path] } {
  298. puts "ERROR: path in --with-target-path does not contain typical subdirectories"
  299. exit 1
  300. }
  301. puts "NOTE: Using explicit target path: $target_path"
  302. }
  303. # Add this for cmake, should it need for something
  304. lappend ::cmakeopt "-DCMAKE_PREFIX_PATH=$target_path"
  305. # Add explicitly the path for pkg-config
  306. # which lib
  307. if { [file isdir $target_path/lib64/pkgconfig] } {
  308. set ::env(PKG_CONFIG_PATH) $target_path/lib64/pkgconfig
  309. puts "PKG_CONFIG_PATH: Found pkgconfig in lib64 for '$target_path' - using it"
  310. } elseif { [file isdir $target_path/lib/pkgconfig] } {
  311. set ::env(PKG_CONFIG_PATH) $target_path/lib/pkgconfig
  312. puts "PKG_CONFIG_PATH: Found pkgconfig in lib for '$target_path' - using it"
  313. } else {
  314. puts "PKG_CONFIG_PATH: NOT changed, no pkgconfig in '$target_path'"
  315. }
  316. # Otherwise don't set PKG_CONFIG_PATH and we'll see.
  317. }
  318. set use_brew 0
  319. if { $::HAVE_DARWIN && !$toolchain_changed } {
  320. set use_brew 1
  321. }
  322. if { $use_brew } {
  323. foreach item $::cmakeopt {
  324. if { [string first "Android" $item] != -1 } {
  325. set use_brew 0
  326. break
  327. }
  328. }
  329. }
  330. if { $use_brew } {
  331. if { $have_gnutls } {
  332. # Use gnutls explicitly, as found in brew
  333. set er [catch {exec brew info gnutls} res]
  334. if { $er } {
  335. error "Cannot find gnutls in brew"
  336. }
  337. } else {
  338. # ON Darwin there's a problem with linking against the Mac-provided OpenSSL.
  339. # This must use brew-provided OpenSSL.
  340. #
  341. if { !$have_openssl } {
  342. set er [catch {exec brew info openssl} res]
  343. if { $er } {
  344. error "You must have OpenSSL installed from 'brew' tool. The standard Mac version is inappropriate."
  345. }
  346. lappend ::cmakeopt "-DOPENSSL_INCLUDE_DIR=/usr/local/opt/openssl/include"
  347. lappend ::cmakeopt "-DOPENSSL_LIBRARIES=/usr/local/opt/openssl/lib/libcrypto.a"
  348. }
  349. }
  350. }
  351. }