ffi 1.15.5 → 1.16.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (309) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +61 -0
  4. data/Gemfile +1 -1
  5. data/README.md +3 -2
  6. data/Rakefile +10 -7
  7. data/ext/ffi_c/AbstractMemory.c +56 -34
  8. data/ext/ffi_c/AbstractMemory.h +3 -2
  9. data/ext/ffi_c/ArrayType.c +49 -13
  10. data/ext/ffi_c/ArrayType.h +1 -0
  11. data/ext/ffi_c/Buffer.c +86 -29
  12. data/ext/ffi_c/Call.c +13 -5
  13. data/ext/ffi_c/DynamicLibrary.c +89 -26
  14. data/ext/ffi_c/Function.c +238 -98
  15. data/ext/ffi_c/Function.h +1 -0
  16. data/ext/ffi_c/FunctionInfo.c +78 -24
  17. data/ext/ffi_c/LastError.c +25 -7
  18. data/ext/ffi_c/MappedType.c +66 -23
  19. data/ext/ffi_c/MappedType.h +0 -2
  20. data/ext/ffi_c/MemoryPointer.c +34 -7
  21. data/ext/ffi_c/MethodHandle.c +3 -1
  22. data/ext/ffi_c/Pointer.c +68 -29
  23. data/ext/ffi_c/Pointer.h +1 -0
  24. data/ext/ffi_c/Struct.c +151 -80
  25. data/ext/ffi_c/Struct.h +7 -4
  26. data/ext/ffi_c/StructByValue.c +48 -16
  27. data/ext/ffi_c/StructLayout.c +117 -48
  28. data/ext/ffi_c/Type.c +104 -36
  29. data/ext/ffi_c/Type.h +3 -1
  30. data/ext/ffi_c/Types.c +1 -1
  31. data/ext/ffi_c/Variadic.c +65 -23
  32. data/ext/ffi_c/compat.h +22 -22
  33. data/ext/ffi_c/extconf.rb +19 -2
  34. data/ext/ffi_c/ffi.c +4 -0
  35. data/ext/ffi_c/libffi/.appveyor/site.exp +16 -0
  36. data/ext/ffi_c/libffi/.appveyor/unix-noexec.exp +7 -0
  37. data/ext/ffi_c/libffi/.appveyor.yml +27 -9
  38. data/ext/ffi_c/libffi/.ci/build-cross-in-container.sh +18 -0
  39. data/ext/ffi_c/libffi/{.travis → .ci}/build-in-container.sh +4 -6
  40. data/ext/ffi_c/libffi/.ci/build.sh +124 -0
  41. data/ext/ffi_c/libffi/{.travis → .ci}/install.sh +14 -7
  42. data/ext/ffi_c/libffi/.ci/msvs-detect +1103 -0
  43. data/ext/ffi_c/libffi/{.travis → .ci}/site.exp +5 -3
  44. data/ext/ffi_c/libffi/.circleci/config.yml +156 -0
  45. data/ext/ffi_c/libffi/.github/workflows/build.yml +460 -0
  46. data/ext/ffi_c/libffi/.github/workflows/emscripten.yml +171 -0
  47. data/ext/ffi_c/libffi/.gitignore +10 -2
  48. data/ext/ffi_c/libffi/LICENSE +1 -1
  49. data/ext/ffi_c/libffi/Makefile.am +12 -5
  50. data/ext/ffi_c/libffi/Makefile.in +118 -51
  51. data/ext/ffi_c/libffi/README.md +144 -104
  52. data/ext/ffi_c/libffi/acinclude.m4 +10 -112
  53. data/ext/ffi_c/libffi/compile +347 -0
  54. data/ext/ffi_c/libffi/config.guess +623 -556
  55. data/ext/ffi_c/libffi/config.sub +75 -34
  56. data/ext/ffi_c/libffi/configure +4571 -3830
  57. data/ext/ffi_c/libffi/configure.ac +64 -28
  58. data/ext/ffi_c/libffi/configure.host +25 -6
  59. data/ext/ffi_c/libffi/doc/Makefile.in +9 -6
  60. data/ext/ffi_c/libffi/doc/libffi.texi +82 -33
  61. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  62. data/ext/ffi_c/libffi/fficonfig.h.in +12 -47
  63. data/ext/ffi_c/libffi/generate-darwin-source-and-headers.py +163 -52
  64. data/ext/ffi_c/libffi/include/Makefile.am +1 -1
  65. data/ext/ffi_c/libffi/include/Makefile.in +10 -9
  66. data/ext/ffi_c/libffi/include/ffi.h.in +54 -50
  67. data/ext/ffi_c/libffi/include/ffi_cfi.h +21 -0
  68. data/ext/ffi_c/libffi/include/ffi_common.h +29 -0
  69. data/ext/ffi_c/libffi/include/tramp.h +45 -0
  70. data/ext/ffi_c/libffi/install-sh +92 -69
  71. data/ext/ffi_c/libffi/libtool-version +2 -2
  72. data/ext/ffi_c/libffi/ltmain.sh +512 -315
  73. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +18 -14
  74. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +108 -72
  75. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +76 -45
  76. data/ext/ffi_c/libffi/m4/ax_prepend_flag.m4 +51 -0
  77. data/ext/ffi_c/libffi/man/Makefile.in +9 -6
  78. data/ext/ffi_c/libffi/missing +1 -1
  79. data/ext/ffi_c/libffi/msvc_build/aarch64/aarch64_include/ffi.h +1 -1
  80. data/ext/ffi_c/libffi/msvcc.sh +1 -1
  81. data/ext/ffi_c/libffi/src/aarch64/ffi.c +146 -42
  82. data/ext/ffi_c/libffi/src/aarch64/internal.h +32 -0
  83. data/ext/ffi_c/libffi/src/aarch64/sysv.S +134 -42
  84. data/ext/ffi_c/libffi/src/arc/arcompact.S +169 -94
  85. data/ext/ffi_c/libffi/src/arc/ffi.c +325 -148
  86. data/ext/ffi_c/libffi/src/arc/ffitarget.h +14 -0
  87. data/ext/ffi_c/libffi/src/arm/ffi.c +62 -17
  88. data/ext/ffi_c/libffi/src/arm/ffitarget.h +3 -3
  89. data/ext/ffi_c/libffi/src/arm/internal.h +10 -0
  90. data/ext/ffi_c/libffi/src/arm/sysv.S +113 -42
  91. data/ext/ffi_c/libffi/src/closures.c +133 -47
  92. data/ext/ffi_c/libffi/src/dlmalloc.c +5 -0
  93. data/ext/ffi_c/libffi/src/ia64/ffi.c +12 -0
  94. data/ext/ffi_c/libffi/src/ia64/unix.S +20 -2
  95. data/ext/ffi_c/libffi/src/loongarch64/ffi.c +621 -0
  96. data/ext/ffi_c/libffi/src/loongarch64/ffitarget.h +82 -0
  97. data/ext/ffi_c/libffi/src/loongarch64/sysv.S +327 -0
  98. data/ext/ffi_c/libffi/src/m32r/ffi.c +31 -14
  99. data/ext/ffi_c/libffi/src/mips/ffi.c +240 -65
  100. data/ext/ffi_c/libffi/src/mips/ffitarget.h +7 -0
  101. data/ext/ffi_c/libffi/src/mips/n32.S +137 -28
  102. data/ext/ffi_c/libffi/src/mips/o32.S +61 -4
  103. data/ext/ffi_c/libffi/src/moxie/ffi.c +47 -22
  104. data/ext/ffi_c/libffi/src/or1k/ffi.c +25 -12
  105. data/ext/ffi_c/libffi/src/pa/ffi.c +32 -33
  106. data/ext/ffi_c/libffi/src/pa/ffi64.c +614 -0
  107. data/ext/ffi_c/libffi/src/pa/ffitarget.h +22 -8
  108. data/ext/ffi_c/libffi/src/pa/hpux32.S +83 -36
  109. data/ext/ffi_c/libffi/src/pa/hpux64.S +681 -0
  110. data/ext/ffi_c/libffi/src/pa/linux.S +82 -35
  111. data/ext/ffi_c/libffi/src/powerpc/ffi_linux64.c +1 -1
  112. data/ext/ffi_c/libffi/src/powerpc/linux64.S +2 -0
  113. data/ext/ffi_c/libffi/src/powerpc/linux64_closure.S +2 -0
  114. data/ext/ffi_c/libffi/src/powerpc/t-aix +5 -0
  115. data/ext/ffi_c/libffi/src/prep_cif.c +22 -2
  116. data/ext/ffi_c/libffi/src/riscv/ffi.c +37 -4
  117. data/ext/ffi_c/libffi/src/sparc/ffi64.c +16 -0
  118. data/ext/ffi_c/libffi/src/tramp.c +716 -0
  119. data/ext/ffi_c/libffi/src/wasm32/ffi.c +934 -0
  120. data/ext/ffi_c/libffi/src/wasm32/ffitarget.h +62 -0
  121. data/ext/ffi_c/libffi/src/x86/ffi.c +99 -37
  122. data/ext/ffi_c/libffi/src/x86/ffi64.c +67 -12
  123. data/ext/ffi_c/libffi/src/x86/ffitarget.h +9 -5
  124. data/ext/ffi_c/libffi/src/x86/ffiw64.c +43 -0
  125. data/ext/ffi_c/libffi/src/x86/internal.h +14 -0
  126. data/ext/ffi_c/libffi/src/x86/internal64.h +14 -0
  127. data/ext/ffi_c/libffi/src/x86/sysv.S +172 -38
  128. data/ext/ffi_c/libffi/src/x86/sysv_intel.S +91 -88
  129. data/ext/ffi_c/libffi/src/x86/unix64.S +96 -6
  130. data/ext/ffi_c/libffi/src/x86/win64.S +20 -7
  131. data/ext/ffi_c/libffi/src/xtensa/ffi.c +16 -8
  132. data/ext/ffi_c/libffi/src/xtensa/ffitarget.h +4 -0
  133. data/ext/ffi_c/libffi/src/xtensa/sysv.S +26 -16
  134. data/ext/ffi_c/libffi/testsuite/Makefile.am +127 -114
  135. data/ext/ffi_c/libffi/testsuite/Makefile.in +137 -121
  136. data/ext/ffi_c/libffi/testsuite/emscripten/build-tests.sh +54 -0
  137. data/ext/ffi_c/libffi/testsuite/emscripten/build.sh +63 -0
  138. data/ext/ffi_c/libffi/testsuite/emscripten/conftest.py +80 -0
  139. data/ext/ffi_c/libffi/testsuite/emscripten/node-tests.sh +48 -0
  140. data/ext/ffi_c/libffi/testsuite/emscripten/test.html +7 -0
  141. data/ext/ffi_c/libffi/testsuite/emscripten/test_libffi.py +51 -0
  142. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +43 -21
  143. data/ext/ffi_c/libffi/testsuite/lib/target-libpath.exp +2 -2
  144. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/test-call.c +1 -0
  145. data/ext/ffi_c/libffi/testsuite/libffi.bhaible/testcases.c +5 -1
  146. data/ext/ffi_c/libffi/testsuite/libffi.call/bpo_38748.c +41 -0
  147. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +28 -3
  148. data/ext/ffi_c/libffi/testsuite/libffi.call/float_va.c +3 -0
  149. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +5 -0
  150. data/ext/ffi_c/libffi/testsuite/libffi.call/return_sl.c +4 -0
  151. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ul.c +4 -0
  152. data/ext/ffi_c/libffi/testsuite/libffi.call/s55.c +60 -0
  153. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen.c +8 -9
  154. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen2.c +2 -2
  155. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen3.c +2 -2
  156. data/ext/ffi_c/libffi/testsuite/libffi.call/strlen4.c +2 -2
  157. data/ext/ffi_c/libffi/testsuite/libffi.call/struct10.c +1 -1
  158. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_2.c +63 -0
  159. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3.c +65 -0
  160. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_3f.c +65 -0
  161. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4.c +67 -0
  162. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_4f.c +67 -0
  163. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_big.c +93 -0
  164. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_by_value_small.c +61 -0
  165. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_2H.c +63 -0
  166. data/ext/ffi_c/libffi/testsuite/libffi.call/struct_return_8H.c +90 -0
  167. data/ext/ffi_c/libffi/testsuite/libffi.call/va_1.c +1 -119
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/va_2.c +220 -0
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/va_3.c +154 -0
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct1.c +13 -0
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct2.c +11 -0
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/va_struct3.c +15 -0
  173. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn0.c +3 -2
  174. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn1.c +2 -0
  175. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn2.c +2 -0
  176. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn3.c +21 -1
  177. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn4.c +2 -0
  178. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn5.c +2 -0
  179. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_fn6.c +2 -0
  180. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_loc_fn0.c +7 -6
  181. data/ext/ffi_c/libffi/testsuite/libffi.closures/closure_simple.c +6 -0
  182. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_12byte.c +18 -0
  183. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_16byte.c +22 -0
  184. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_18byte.c +24 -0
  185. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_19byte.c +29 -0
  186. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_1_1byte.c +4 -0
  187. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_20byte.c +19 -1
  188. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_20byte1.c +21 -1
  189. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_24byte.c +35 -3
  190. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_2byte.c +13 -0
  191. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3_1byte.c +19 -0
  192. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3byte1.c +13 -0
  193. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3byte2.c +13 -0
  194. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_3float.c +18 -0
  195. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_4_1byte.c +22 -0
  196. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_4byte.c +13 -0
  197. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_5_1_byte.c +29 -1
  198. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_5byte.c +19 -1
  199. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_64byte.c +24 -0
  200. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_6_1_byte.c +28 -1
  201. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_6byte.c +24 -2
  202. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_7_1_byte.c +39 -1
  203. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_7byte.c +25 -1
  204. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_8byte.c +14 -0
  205. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_9byte1.c +14 -1
  206. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_9byte2.c +14 -2
  207. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_double.c +19 -1
  208. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_float.c +19 -1
  209. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble.c +20 -1
  210. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble_split.c +40 -25
  211. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_longdouble_split2.c +40 -3
  212. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_pointer.c +19 -1
  213. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint16.c +18 -1
  214. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint32.c +18 -3
  215. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_sint64.c +18 -1
  216. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint16.c +18 -1
  217. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint32.c +19 -1
  218. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_align_uint64.c +19 -1
  219. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_dbls_struct.c +3 -1
  220. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_double_va.c +9 -1
  221. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_float.c +4 -0
  222. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_longdouble.c +11 -1
  223. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_longdouble_va.c +22 -3
  224. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_schar.c +5 -1
  225. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshort.c +6 -1
  226. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_sshortchar.c +9 -1
  227. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_uchar.c +9 -1
  228. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushort.c +6 -2
  229. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_multi_ushortchar.c +9 -1
  230. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_pointer.c +5 -0
  231. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_pointer_stack.c +10 -0
  232. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_schar.c +3 -0
  233. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_sint.c +2 -0
  234. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_sshort.c +3 -0
  235. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_struct_va1.c +11 -0
  236. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uchar.c +3 -0
  237. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint.c +4 -0
  238. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uint_va.c +4 -0
  239. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulong_va.c +4 -0
  240. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ulonglong.c +2 -0
  241. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ushort.c +3 -0
  242. data/ext/ffi_c/libffi/testsuite/libffi.closures/ffitest.h +1 -138
  243. data/ext/ffi_c/libffi/testsuite/libffi.closures/huge_struct.c +21 -21
  244. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct.c +32 -9
  245. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct1.c +1 -1
  246. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct10.c +12 -0
  247. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct11.c +21 -5
  248. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct12.c +86 -0
  249. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct13.c +115 -0
  250. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct2.c +10 -1
  251. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct3.c +10 -1
  252. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct4.c +9 -0
  253. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct5.c +9 -0
  254. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct6.c +11 -0
  255. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct7.c +9 -0
  256. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct8.c +11 -0
  257. data/ext/ffi_c/libffi/testsuite/libffi.closures/nested_struct9.c +11 -0
  258. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs1.c +86 -0
  259. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs2.c +102 -0
  260. data/ext/ffi_c/libffi/testsuite/libffi.closures/single_entry_structs3.c +101 -0
  261. data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_medium.c +1 -1
  262. data/ext/ffi_c/libffi/testsuite/libffi.closures/stret_medium2.c +1 -1
  263. data/ext/ffi_c/libffi/testsuite/libffi.closures/testclosure.c +6 -1
  264. data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest.cc +2 -1
  265. data/ext/ffi_c/libffi/testsuite/libffi.closures/unwindtest_ffi_call.cc +1 -0
  266. data/ext/ffi_c/libffi.bsd.mk +2 -2
  267. data/ext/ffi_c/libffi.gnu.mk +2 -2
  268. data/ext/ffi_c/rbffi.h +1 -1
  269. data/ffi.gemspec +3 -3
  270. data/lib/ffi/autopointer.rb +7 -22
  271. data/lib/ffi/compat.rb +43 -0
  272. data/lib/ffi/data_converter.rb +2 -2
  273. data/lib/ffi/dynamic_library.rb +89 -0
  274. data/lib/ffi/enum.rb +18 -11
  275. data/lib/ffi/ffi.rb +3 -0
  276. data/lib/ffi/function.rb +71 -0
  277. data/lib/ffi/library.rb +55 -71
  278. data/lib/ffi/library_path.rb +109 -0
  279. data/lib/ffi/managedstruct.rb +1 -1
  280. data/lib/ffi/platform/aarch64-windows/types.conf +52 -0
  281. data/lib/ffi/platform/hppa1.1-linux/types.conf +178 -0
  282. data/lib/ffi/platform/hppa2.0-linux/types.conf +178 -0
  283. data/lib/ffi/platform/loongarch64-linux/types.conf +141 -0
  284. data/lib/ffi/platform/sw_64-linux/types.conf +141 -0
  285. data/lib/ffi/platform.rb +15 -13
  286. data/lib/ffi/struct.rb +2 -1
  287. data/lib/ffi/struct_layout.rb +1 -1
  288. data/lib/ffi/struct_layout_builder.rb +1 -1
  289. data/lib/ffi/types.rb +30 -5
  290. data/lib/ffi/variadic.rb +19 -8
  291. data/lib/ffi/version.rb +1 -1
  292. data.tar.gz.sig +3 -0
  293. metadata +98 -25
  294. metadata.gz.sig +3 -0
  295. data/ext/ffi_c/libffi/.travis/build-cross-in-container.sh +0 -14
  296. data/ext/ffi_c/libffi/.travis/build.sh +0 -142
  297. data/ext/ffi_c/libffi/.travis.yml +0 -83
  298. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_uchar_va.c +0 -44
  299. data/ext/ffi_c/libffi/testsuite/libffi.closures/cls_ushort_va.c +0 -44
  300. /data/ext/ffi_c/libffi/{.travis → .ci}/ar-lib +0 -0
  301. /data/ext/ffi_c/libffi/{.travis → .ci}/bfin-sim.exp +0 -0
  302. /data/ext/ffi_c/libffi/{.travis → .ci}/compile +0 -0
  303. /data/ext/ffi_c/libffi/{.travis → .ci}/m32r-sim.exp +0 -0
  304. /data/ext/ffi_c/libffi/{.travis → .ci}/moxie-sim.exp +0 -0
  305. /data/ext/ffi_c/libffi/{.travis → .ci}/or1k-sim.exp +0 -0
  306. /data/ext/ffi_c/libffi/{.travis → .ci}/powerpc-eabisim.exp +0 -0
  307. /data/ext/ffi_c/libffi/{.travis → .ci}/wine-sim.exp +0 -0
  308. /data/ext/ffi_c/libffi/testsuite/libffi.call/{pyobjc-tc.c → pyobjc_tc.c} +0 -0
  309. /data/lib/ffi/platform/{sparc64-linux → sparcv9-linux}/types.conf +0 -0
@@ -0,0 +1,1103 @@
1
+ #!/usr/bin/env bash
2
+ # ################################################################################################ #
3
+ # MetaStack Solutions Ltd. #
4
+ # ################################################################################################ #
5
+ # Microsoft C Compiler Environment Detection Script #
6
+ # ################################################################################################ #
7
+ # Copyright (c) 2016, 2017, 2018, 2019, 2020 MetaStack Solutions Ltd. #
8
+ # ################################################################################################ #
9
+ # Author: David Allsopp #
10
+ # 16-Feb-2016 #
11
+ # ################################################################################################ #
12
+ # Redistribution and use in source and binary forms, with or without modification, are permitted #
13
+ # provided that the following two conditions are met: #
14
+ # 1. Redistributions of source code must retain the above copyright notice, this list of #
15
+ # conditions and the following disclaimer. #
16
+ # 2. Neither the name of MetaStack Solutions Ltd. nor the names of its contributors may be #
17
+ # used to endorse or promote products derived from this software without specific prior #
18
+ # written permission. #
19
+ # #
20
+ # This software is provided by the Copyright Holder 'as is' and any express or implied warranties #
21
+ # including, but not limited to, the implied warranties of merchantability and fitness for a #
22
+ # particular purpose are disclaimed. In no event shall the Copyright Holder be liable for any #
23
+ # direct, indirect, incidental, special, exemplary, or consequential damages (including, but not #
24
+ # limited to, procurement of substitute goods or services; loss of use, data, or profits; or #
25
+ # business interruption) however caused and on any theory of liability, whether in contract, #
26
+ # strict liability, or tort (including negligence or otherwise) arising in any way out of the use #
27
+ # of this software, even if advised of the possibility of such damage. #
28
+ # ################################################################################################ #
29
+
30
+ VERSION=0.4.1
31
+
32
+ # debug [level=2] message
33
+ debug ()
34
+ {
35
+ if [[ -z ${2+x} ]] ; then
36
+ DEBUG_LEVEL=2
37
+ else
38
+ DEBUG_LEVEL=$1
39
+ shift
40
+ fi
41
+
42
+ if [[ $DEBUG -ge $DEBUG_LEVEL ]] ; then
43
+ echo "$1">&2
44
+ fi
45
+ }
46
+
47
+ # warning message
48
+ warning ()
49
+ {
50
+ if [[ $DEBUG -gt 0 ]] ; then
51
+ echo "Warning: $1">&2
52
+ fi
53
+ }
54
+
55
+ # reg_string key value
56
+ # Retrieves a REG_SZ value from the registry (redirected on WOW64)
57
+ reg_string ()
58
+ {
59
+ reg query "$1" /v "$2" 2>/dev/null | tr -d '\r' | sed -ne "s/ *$2 *REG_SZ *//p"
60
+ }
61
+
62
+ # reg64_string key value
63
+ # As reg_string, but without WOW64 redirection (i.e. guaranteed access to 64-bit registry)
64
+ reg64_string ()
65
+ {
66
+ $REG64 query "$1" /v "$2" 2>/dev/null | tr -d '\r' | sed -ne "s/ *$2 *REG_SZ *//p"
67
+ }
68
+
69
+ # find_in list file
70
+ # Increments $RET if file does not exist in any of the directories in the *-separated list
71
+ find_in ()
72
+ {
73
+ debug 4 "Looking for $2 in $1"
74
+ if [[ -z $1 ]] ; then
75
+ STATUS=1
76
+ else
77
+ IFS=*
78
+ STATUS=1
79
+ for f in $1; do
80
+ if [[ -e "$f/$2" ]] ; then
81
+ STATUS=0
82
+ break
83
+ fi
84
+ done
85
+ unset IFS
86
+ fi
87
+ if [[ $STATUS -eq 1 ]] ; then
88
+ debug 4 "$2 not found"
89
+ fi
90
+ ((RET+=STATUS))
91
+ }
92
+
93
+ # check_environment PATH INC LIB name arch
94
+ # By checking for the presence of various files, verifies that PATH, INC and LIB provide a complete
95
+ # compiler and indicates this in its return status. RET is assumed to be zero on entry. $ASSEMBLER
96
+ # will contain the name of assembler for this compiler series (ml.exe or ml64.exe).
97
+ # The following files are checked:
98
+ # cl.exe PATH Microsoft C compiler
99
+ # kernel32.lib LIB Implies Windows SDK present
100
+ # link.exe PATH Microsoft Linker
101
+ # ml[64].exe PATH Microsoft Assembler (ml.exe or ml64.exe)
102
+ # msvcrt.lib LIB Implies C Runtime Libraries present
103
+ # mt.exe PATH Microsoft Manifest Tool
104
+ # oldnames.lib LIB Implies C Runtime Libraries present
105
+ # rc.exe PATH Microsoft Resource Compiler (implies tools present)
106
+ # stdlib.h INC Implies Microsoft C Runtime Libraries present
107
+ # windows.h INC Implies Windows SDK present
108
+ # oldnames.lib is included, because certain SDKs and older versions don't correctly install the
109
+ # entire runtime if only some options (e.g. Dynamic Runtime and not Static) are selected.
110
+ check_environment ()
111
+ {
112
+ debug 4 "Checking $4 ($5)"
113
+ for tool in cl rc link ; do
114
+ find_in "$1" $tool.exe
115
+ done
116
+
117
+ if [[ $RET -gt 0 ]] ; then
118
+ warning "Microsoft C Compiler tools not all found - $4 ($5) excluded"
119
+ return 1
120
+ fi
121
+
122
+ RET=0
123
+ find_in "$2" windows.h
124
+ find_in "$3" kernel32.lib
125
+ if [[ $RET -gt 0 ]] ; then
126
+ warning "Windows SDK not all found - $4 ($5) excluded"
127
+ return 1
128
+ fi
129
+
130
+ RET=0
131
+ find_in "$2" stdlib.h
132
+ find_in "$3" msvcrt.lib
133
+ find_in "$3" oldnames.lib
134
+ if [[ $RET -gt 0 ]] ; then
135
+ warning "Microsoft C runtime library not all found - $4 ($5) excluded"
136
+ return 1
137
+ fi
138
+
139
+ ASSEMBLER=ml${5#x}
140
+ ASSEMBLER=${ASSEMBLER%86}.exe
141
+ if [[ $ML_REQUIRED -eq 1 ]] ; then
142
+ RET=0
143
+ find_in "$1" $ASSEMBLER
144
+ if [[ $RET -gt 0 ]] ; then
145
+ warning "Microsoft Assembler ($ASSEMBLER) not found - $4 ($5)"
146
+ return 1
147
+ fi
148
+ fi
149
+
150
+ if [[ $MT_REQUIRED -eq 1 ]] ; then
151
+ RET=0
152
+ find_in "$1" mt.exe
153
+ if [[ $RET -gt 0 ]] ; then
154
+ warning "Microsoft Manifest Tool not found - $4 ($5)"
155
+ return 1
156
+ fi
157
+ fi
158
+
159
+ return 0
160
+ }
161
+
162
+ # output VAR value arch
163
+ # Outputs a command for setting VAR to value based on $OUTPUT. If $ENV_ARCH is arch, then an empty
164
+ # value (i.e. no change) is output.
165
+ output ()
166
+ {
167
+ if [[ $3 = $ENV_ARCH ]] ; then
168
+ VALUE=
169
+ else
170
+ VALUE=$2
171
+ fi
172
+ case "$OUTPUT" in
173
+ 0)
174
+ echo "$1='${VALUE//\'/\'\"\'\"\'}'";;
175
+ 1)
176
+ VALUE=${VALUE//#/\\\#}
177
+ echo "$1=${VALUE//\$/\$\$}";;
178
+ esac
179
+ }
180
+
181
+ # DEBUG Debugging level
182
+ # MODE Operation mode
183
+ # 0 - Normal
184
+ # 1 - --all
185
+ # 2 - --help
186
+ # 3 - --version
187
+ # OUTPUT --output option
188
+ # 0 - =shell
189
+ # 1 - =make
190
+ # MT_REQUIRED --with-mt
191
+ # ML_REQUIRED --with-assembler
192
+ # TARGET_ARCH Normalised --arch (x86, x64 or blank for both)
193
+ # LEFT_ARCH \ If $TARGET_ARCH is blank, these will be x86 and x64 respectively, otherwise they
194
+ # RIGHT_ARCH / equal $TARGET_ARCH
195
+ # SCAN_ENV Controls from parsing whether the environment should be queried for a compiler
196
+ DEBUG=0
197
+ MODE=0
198
+ OUTPUT=0
199
+ MT_REQUIRED=0
200
+ ML_REQUIRED=0
201
+ TARGET_ARCH=
202
+ SCAN_ENV=0
203
+
204
+ # Various PATH messing around means it's sensible to know where tools are now
205
+ WHICH=$(which which)
206
+
207
+ if [[ $(uname --operating-system 2>/dev/null) = "Msys" ]] ; then
208
+ # Prevent MSYS from translating command line switches to paths
209
+ SWITCH_PREFIX='//'
210
+ else
211
+ SWITCH_PREFIX='/'
212
+ fi
213
+
214
+ # Parse command-line. At the moment, the short option which usefully combines with anything is -d,
215
+ # so for the time being, combining short options is not permitted, as the loop becomes even less
216
+ # clear with getopts. GNU getopt isn't installed by default on Cygwin...
217
+ if [[ $@ != "" ]] ; then
218
+ while true ; do
219
+ case "$1" in
220
+ # Mode settings ($MODE)
221
+ -a|--all)
222
+ MODE=1
223
+ shift 1;;
224
+ -h|--help)
225
+ MODE=2
226
+ shift;;
227
+ -v|--version)
228
+ MODE=3
229
+ shift;;
230
+
231
+ # Simple flags ($MT_REQUIRED and $ML_REQUIRED)
232
+ --with-mt)
233
+ MT_REQUIRED=1
234
+ shift;;
235
+ --with-assembler)
236
+ ML_REQUIRED=1
237
+ shift;;
238
+
239
+ # -o, --output ($OUTPUT)
240
+ -o|--output)
241
+ case "$2" in
242
+ shell)
243
+ ;;
244
+ make)
245
+ OUTPUT=1;;
246
+ *)
247
+ echo "$0: unrecognised option for $1: '$2'">&2
248
+ exit 2;;
249
+ esac
250
+ shift 2;;
251
+ -oshell|--output=shell)
252
+ shift;;
253
+ -omake|--output=make)
254
+ OUTPUT=1
255
+ shift;;
256
+ -o*)
257
+ echo "$0: unrecognised option for -o: '${1#-o}'">&2
258
+ exit 2;;
259
+ --output=*)
260
+ echo "$0: unrecognised option for --output: '${1#--output=}'">&2
261
+ exit 2;;
262
+
263
+ # -x, --arch ($TARGET_ARCH)
264
+ -x|--arch)
265
+ case "$2" in
266
+ 86|x86)
267
+ TARGET_ARCH=x86;;
268
+ 64|x64)
269
+ TARGET_ARCH=x64;;
270
+ *)
271
+ echo "$0: unrecognised option for $1: '$2'">&2
272
+ exit 2
273
+ esac
274
+ shift 2;;
275
+ -x86|-xx86|--arch=x86|--arch=86)
276
+ TARGET_ARCH=x86
277
+ shift;;
278
+ -x64|-xx64|--arch=x64|--arch=64)
279
+ TARGET_ARCH=x64
280
+ shift;;
281
+ -x*)
282
+ echo "$0: unrecognised option for -x: '${1#-x}'">&2
283
+ exit 2;;
284
+ --arch=*)
285
+ echo "$0: unrecognised option for --arch: '${1#--arch}'">&2
286
+ exit 2;;
287
+
288
+ # -d, --debug ($DEBUG)
289
+ -d*)
290
+ DEBUG=${1#-d}
291
+ if [[ -z $DEBUG ]] ; then
292
+ DEBUG=1
293
+ fi
294
+ shift;;
295
+ --debug=*)
296
+ DEBUG=${1#*=}
297
+ shift;;
298
+ --debug)
299
+ DEBUG=1
300
+ shift;;
301
+
302
+ # End of option marker
303
+ --)
304
+ shift
305
+ break;;
306
+
307
+ # Invalid options
308
+ --*)
309
+ echo "$0: unrecognised option: '${1%%=*}'">&2
310
+ exit 2;;
311
+ -*)
312
+ echo "$0: unrecognised option: '${1:1:1}'">&2
313
+ exit 2;;
314
+
315
+ # MSVS_PREFERENCE (without end-of-option marker)
316
+ *)
317
+ break;;
318
+ esac
319
+ done
320
+
321
+ if [[ -n ${1+x} ]] ; then
322
+ if [[ $MODE -eq 1 ]] ; then
323
+ echo "$0: cannot specify MSVS_PREFERENCE and --all">&2
324
+ exit 2
325
+ else
326
+ MSVS_PREFERENCE="$@"
327
+ fi
328
+ fi
329
+ fi
330
+
331
+ # Options sanitising
332
+ if [[ $MODE -eq 1 ]] ; then
333
+ if [[ -n $TARGET_ARCH ]] ; then
334
+ echo "$0: --all and --arch are mutually exclusive">&2
335
+ exit 2
336
+ fi
337
+ MSVS_PREFERENCE=
338
+ SCAN_ENV=1
339
+ elif [[ -z ${MSVS_PREFERENCE+x} ]] ; then
340
+ MSVS_PREFERENCE='@;VS16.*;VS15.*;VS14.0;VS12.0;VS11.0;10.0;9.0;8.0;7.1;7.0'
341
+ fi
342
+
343
+ MSVS_PREFERENCE=${MSVS_PREFERENCE//;/ }
344
+
345
+ if [[ -z $TARGET_ARCH ]] ; then
346
+ LEFT_ARCH=x86
347
+ RIGHT_ARCH=x64
348
+ else
349
+ LEFT_ARCH=$TARGET_ARCH
350
+ RIGHT_ARCH=$TARGET_ARCH
351
+ fi
352
+
353
+ # Command line parsing complete (MSVS_PREFERENCE pending)
354
+
355
+ NAME="Microsoft C Compiler Environment Detection Script"
356
+ case $MODE in
357
+ 2)
358
+ echo "$NAME"
359
+ echo "Queries the environment and registry to locate Visual Studio / Windows SDK"
360
+ echo "installations and uses their initialisation scripts (SetEnv.cmd, vcvarsall.bat,"
361
+ echo "etc.) to determine INCLUDE, LIB and PATH alterations."
362
+ echo
363
+ echo "Usage:"
364
+ echo " $0 [OPTIONS] [--] [MSVS_PREFERENCE]"
365
+ echo
366
+ echo "Options:"
367
+ echo " -a, --all Display all available compiler packages"
368
+ echo " -x, --arch=ARCH Only consider packages for ARCH (x86 or x64). Default is"
369
+ echo " to return packages containing both architectures"
370
+ echo " -d, --debug[=LEVEL] Set debug messages level"
371
+ echo " -h, --help Display this help screen"
372
+ echo " -o, --output=OUTPUT Set final output. Default is shell. Valid values:"
373
+ echo " shell - shell assignments, for use with eval"
374
+ echo " make - make assignments, for inclusion in a Makefile"
375
+ echo " -v, --version Display the version"
376
+ echo " --with-mt Only consider packages including the Manifest Tool"
377
+ echo " --with-assembler Only consider packages including an assembler"
378
+ echo
379
+ echo "If MSVS_PREFERENCE is not given, then the environment variable MSVS_PREFERENCE"
380
+ echo "is read. MSVS_PREFERENCE is a semicolon separated list of preferred versions."
381
+ echo "Three kinds of version notation are supported:"
382
+ echo " 1. @ - which refers to the C compiler found in PATH (if it can be identified)"
383
+ echo " (this allows the C compiler corresponding to the opposite architecture to"
384
+ echo " be selected, if possible)."
385
+ echo " 2. mm.n - which refers to a Visual Studio version (e.g. 14.0, 7.1) but which"
386
+ echo " also allows an SDK to provide the compiler (e.g. Windows SDK 7.1 provides"
387
+ echo " 10.0). Visual Studio packages are always preferred ahead of SDKs."
388
+ echo " 3. SPEC - an actual package specification. Visual Studio packages are VSmm.n"
389
+ echo " (e.g. VS14.0, VS7.1) and SDK packages are SDKm.n (e.g. SDK7.1)."
390
+ echo " Any Visual Studio 2017 update can be selected with VS15.*"
391
+ echo "The default behaviour is to match the environment compiler followed by the most"
392
+ echo "recent version of the compiler."
393
+ exit 0;;
394
+ 3)
395
+ echo "$NAME"
396
+ echo "Version $VERSION"
397
+ exit 0;;
398
+ esac
399
+
400
+ # Known compiler packages. Visual Studio .NET 2002 onwards. Detection is in place for Visual Studio
401
+ # 2005 Express, but because it doesn't include a Windows SDK, it can only ever be detected if the
402
+ # script has been launched from within a Platform SDK command prompt (this provides the Windows
403
+ # Headers and Libraries which allows this script to detect the rest).
404
+ # Each element is either a Visual Studio or SDK package and the value is the syntax for a bash
405
+ # associative array to be eval'd. Each of these contains the following properties:
406
+ # NAME - the friendly name of the package
407
+ # ENV - (VS only) the version-specific portion of the VSCOMNTOOLS environment variable
408
+ # VERSION - (VS only) version number of the package
409
+ # ARCH - Lists the architectures available in this version
410
+ # ARCH_SWITCHES - The script is assumed to accept x86 and x64 to indicate architecture. This key
411
+ # contains another eval'd associative array allowing alternate values to be given
412
+ # SETENV_RELEASE - (SDK only) script switch necessary to select release than debugging versions
413
+ # EXPRESS - (VS only) the prefix to the registry key to detect the Express edition
414
+ # EXPRESS_ARCH - (VS only) overrides ARCH if Express edition is detected
415
+ # EXPRESS_ARCH_SWITCHES - (VS only) overrides ARCH_SWITCHES if Express edition is detected
416
+ # VC_VER - (SDK only) specifies the version of the C Compilers included in the SDK (SDK
417
+ # equivalent of the VERSION key)
418
+ # REG_KEY - (SDK only) registry key to open to identify this package installation
419
+ # REG_VALUE - (SDK only) registry value to query to identify this package installation
420
+ # VSWHERE - (VS 2017+) is 1 if the compiler can only be detected using vswhere
421
+ # For a while, Windows SDKs followed a standard pattern which is stored in the SDK element and
422
+ # copied to the appropriate version. SDKs after 7.1 do not include compilers, and so are not
423
+ # captured (as of Visual Studio 2015, the Windows SDK is official part of Visual Studio).
424
+ declare -A COMPILERS
425
+ SDK52_KEY='HKLM\SOFTWARE\Microsoft\MicrosoftSDK\InstalledSDKs\8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3'
426
+ COMPILERS=(
427
+ ["VS7.0"]='(
428
+ ["NAME"]="Visual Studio .NET 2002"
429
+ ["ENV"]=""
430
+ ["VERSION"]="7.0"
431
+ ["ARCH"]="x86")'
432
+ ["VS7.1"]='(
433
+ ["NAME"]="Visual Studio .NET 2003"
434
+ ["ENV"]="71"
435
+ ["VERSION"]="7.1"
436
+ ["ARCH"]="x86")'
437
+ ["VS8.0"]='(
438
+ ["NAME"]="Visual Studio 2005"
439
+ ["ENV"]="80"
440
+ ["VERSION"]="8.0"
441
+ ["EXPRESS"]="VC"
442
+ ["ARCH"]="x86 x64"
443
+ ["EXPRESS_ARCH"]="x86")'
444
+ ["VS9.0"]='(
445
+ ["NAME"]="Visual Studio 2008"
446
+ ["ENV"]="90"
447
+ ["VERSION"]="9.0"
448
+ ["EXPRESS"]="VC"
449
+ ["ARCH"]="x86 x64"
450
+ ["EXPRESS_ARCH"]="x86")'
451
+ ["VS10.0"]='(
452
+ ["NAME"]="Visual Studio 2010"
453
+ ["ENV"]="100"
454
+ ["VERSION"]="10.0"
455
+ ["EXPRESS"]="VC"
456
+ ["ARCH"]="x86 x64"
457
+ ["EXPRESS_ARCH"]="x86")'
458
+ ["VS11.0"]='(
459
+ ["NAME"]="Visual Studio 2012"
460
+ ["ENV"]="110"
461
+ ["VERSION"]="11.0"
462
+ ["EXPRESS"]="WD"
463
+ ["ARCH"]="x86 x64"
464
+ ["EXPRESS_ARCH_SWITCHES"]="([\"x64\"]=\"x86_amd64\")")'
465
+ ["VS12.0"]='(
466
+ ["NAME"]="Visual Studio 2013"
467
+ ["ENV"]="120"
468
+ ["VERSION"]="12.0"
469
+ ["EXPRESS"]="WD"
470
+ ["ARCH"]="x86 x64"
471
+ ["EXPRESS_ARCH_SWITCHES"]="([\"x64\"]=\"x86_amd64\")")'
472
+ ["VS14.0"]='(
473
+ ["NAME"]="Visual Studio 2015"
474
+ ["ENV"]="140"
475
+ ["VERSION"]="14.0"
476
+ ["ARCH"]="x86 x64")'
477
+ ["VS15.*"]='(
478
+ ["NAME"]="Visual Studio 2017"
479
+ ["VSWHERE"]="1")'
480
+ ["VS16.*"]='(
481
+ ["NAME"]="Visual Studio 2019"
482
+ ["VSWHERE"]="1")'
483
+ ["SDK5.2"]='(
484
+ ["NAME"]="Windows Server 2003 SP1 SDK"
485
+ ["VC_VER"]="8.0"
486
+ ["REG_KEY"]="$SDK52_KEY"
487
+ ["REG_VALUE"]="Install Dir"
488
+ ["SETENV_RELEASE"]="/RETAIL"
489
+ ["ARCH"]="x64"
490
+ ["ARCH_SWITCHES"]="([\"x64\"]=\"/X64\")")'
491
+ ["SDK"]='(
492
+ ["NAME"]="Generalised Windows SDK"
493
+ ["SETENV_RELEASE"]="/Release"
494
+ ["ARCH"]="x86 x64"
495
+ ["ARCH_SWITCHES"]="([\"x86\"]=\"/x86\" [\"x64\"]=\"/x64\")")'
496
+ ["SDK6.1"]='(
497
+ ["NAME"]="Windows Server 2008 with .NET 3.5 SDK"
498
+ ["VC_VER"]="9.0")'
499
+ ["SDK7.0"]='(
500
+ ["NAME"]="Windows 7 with .NET 3.5 SP1 SDK"
501
+ ["VC_VER"]="9.0")'
502
+ ["SDK7.1"]='(
503
+ ["NAME"]="Windows 7 with .NET 4 SDK"
504
+ ["VC_VER"]="10.0")'
505
+ )
506
+
507
+ # FOUND is ultimately an associative array containing installed compiler packages. It's
508
+ # hijacked here as part of MSVS_PREFERENCE validation.
509
+ # Ultimately, it contains a copy of the value from COMPILERS with the following extra keys:
510
+ # IS_EXPRESS - (VS only) indicates whether the Express edition was located
511
+ # SETENV - (SDK only) the full location of the SetEnv.cmd script
512
+ # ASSEMBLER - the name of the assembler (ml or ml64)
513
+ # MSVS_PATH \
514
+ # MSVS_INC > prefix values for PATH, INCLUDE and LIB determined by running the scripts.
515
+ # MSVS_LIB /
516
+ declare -A FOUND
517
+
518
+ # Check that MSVS_PREFERENCE is valid and contains no repetitions.
519
+ for v in $MSVS_PREFERENCE ; do
520
+ if [[ -n ${FOUND[$v]+x} ]] ; then
521
+ echo "$0: corrupt MSVS_PREFERENCE: repeated '$v'">&2
522
+ exit 2
523
+ fi
524
+ if [[ $v != "@" ]] ; then
525
+ if [[ -z ${COMPILERS[$v]+x} && -z ${COMPILERS["VS$v"]+x} && -z ${COMPILERS[${v%.*}.*]+x} ]] ; then
526
+ echo "$0: corrupt MSVS_PREFERENCE: unknown compiler '$v'">&2
527
+ exit 2
528
+ fi
529
+ else
530
+ SCAN_ENV=1
531
+ fi
532
+ FOUND["$v"]=""
533
+ done
534
+
535
+ # Reset FOUND for later use.
536
+ FOUND=()
537
+
538
+ # Scan the environment for a C compiler, and check that it's valid. Throughout the rest of the
539
+ # script, it is assumed that if ENV_ARCH is set then there is a valid environment compiler.
540
+ if [[ $SCAN_ENV -eq 1 ]] ; then
541
+ if "$WHICH" cl >/dev/null 2>&1 ; then
542
+ # Determine its architecture from the Microsoft Logo line.
543
+ ENV_ARCH=$(cl 2>&1 | head -1 | tr -d '\r')
544
+ case "${ENV_ARCH#* for }" in
545
+ x64|AMD64)
546
+ ENV_ARCH=x64;;
547
+ 80x86|x86)
548
+ ENV_ARCH=x86;;
549
+ *)
550
+ echo "Unable to identify C compiler architecture from '${ENV_ARCH#* for }'">&2
551
+ echo "Environment C compiler discarded">&2
552
+ unset ENV_ARCH;;
553
+ esac
554
+
555
+ # Environment variable names are a bit of a nightmare on Windows - they are actually case
556
+ # sensitive (at the kernel level) but not at the user level! To compound the misery is that SDKs
557
+ # use Include and Lib where vcvars32 tends to use INCLUDE and LIB. Windows versions also contain
558
+ # a mix of Path and PATH, but fortunately Cygwin normalises that to PATH for us! For this
559
+ # reason, use env to determine the actual case of the LIB and INCLUDE variables.
560
+ if [[ -n ${ENV_ARCH+x} ]] ; then
561
+ RET=0
562
+ ENV_INC=$(env | sed -ne 's/^\(INCLUDE\)=.*/\1/pi')
563
+ ENV_LIB=$(env | sed -ne 's/^\(LIB\)=.*/\1/pi')
564
+ if [[ -z $ENV_INC || -z $ENV_LIB ]] ; then
565
+ warning "Microsoft C Compiler Include and/or Lib not set - Environment C compiler ($ENV_ARCH) excluded"
566
+ unset ENV_ARCH
567
+ else
568
+ if check_environment "${PATH//:/*}" \
569
+ "${!ENV_INC//;/*}" \
570
+ "${!ENV_LIB//;/*}" \
571
+ "Environment C compiler" \
572
+ "$ENV_ARCH" ; then
573
+ ENV_CL=$("$WHICH" cl)
574
+ ENV_cl=${ENV_CL,,}
575
+ ENV_cl=${ENV_cl/bin\/*_/bin\/}
576
+ debug "Environment appears to include a compiler at $ENV_CL"
577
+ if [[ -n $TARGET_ARCH && $TARGET_ARCH != $ENV_ARCH ]] ; then
578
+ debug "But architecture doesn't match required value"
579
+ unset ENV_ARCH
580
+ fi
581
+ else
582
+ unset ENV_ARCH
583
+ fi
584
+ fi
585
+ fi
586
+ fi
587
+ fi
588
+
589
+ # Even if launched from a 64-bit Command Prompt, Cygwin is usually 32-bit and so the scripts
590
+ # executed will inherit that fact. This is a problem when querying the registry, but fortunately
591
+ # WOW64 provides a mechanism to break out of the 32-bit environment by mapping $WINDIR/sysnative to
592
+ # the real 64-bit programs.
593
+ # Thus:
594
+ # MS_ROOT is the 32-bit Microsoft Registry key (all Visual Studio keys are located there)
595
+ # REG64 is the processor native version of the reg utility (allowing 64-bit keys to be read for
596
+ # the SDKs)
597
+ if [[ -n ${PROCESSOR_ARCHITEW6432+x} ]] ; then
598
+ debug "WOW64 detected"
599
+ MS_ROOT='HKLM\SOFTWARE\Microsoft'
600
+ REG64=$WINDIR/sysnative/reg
601
+ else
602
+ MS_ROOT='HKLM\SOFTWARE\Wow6432Node\Microsoft'
603
+ REG64=reg
604
+ fi
605
+
606
+ # COMPILER contains each eval'd element from COMPILERS
607
+ declare -A COMPILER
608
+
609
+ # Scan the registry for compiler package (vswhere is later)
610
+ for i in "${!COMPILERS[@]}" ; do
611
+ eval COMPILER=${COMPILERS[$i]}
612
+
613
+ if [[ -n ${COMPILER["ENV"]+x} ]] ; then
614
+ # Visual Studio package - test for its environment variable
615
+ ENV=VS${COMPILER["ENV"]}COMNTOOLS
616
+ if [[ -n ${!ENV+x} ]] ; then
617
+ debug "$ENV is a candidate"
618
+ TEST_PATH=${!ENV%\"}
619
+ TEST_PATH=$(cygpath -u -f - <<< ${TEST_PATH#\"})
620
+ if [[ -e $TEST_PATH/vsvars32.bat ]] ; then
621
+ debug "Directory pointed to by $ENV contains vsvars32.bat"
622
+ EXPRESS=0
623
+ # Check for the primary Visual Studio registry value indicating installation
624
+ INSTALL_DIR=$(reg_string "$MS_ROOT\\VisualStudio\\${COMPILER["VERSION"]}" InstallDir)
625
+ if [[ -z $INSTALL_DIR ]] ; then
626
+ if [[ -n ${COMPILER["EXPRESS"]+x} ]] ; then
627
+ TEST_KEY="$MS_ROOT\\${COMPILER["EXPRESS"]}Express\\${COMPILER["VERSION"]}"
628
+ INSTALL_DIR=$(reg_string "$TEST_KEY" InstallDir)
629
+ # Exception for Visual Studio 2005 Express, which doesn't set the registry correctly, so
630
+ # set INSTALL_DIR to a fake value to pass the next test.
631
+ if [[ ${COMPILER["VERSION"]} = "8.0" ]] ; then
632
+ INSTALL_DIR=$(cygpath -w "$TEST_PATH")
633
+ EXPRESS=1
634
+ else
635
+ if [[ -z $INSTALL_DIR ]] ; then
636
+ warning "vsvars32.bat found, but registry value not located (Exp or Pro)"
637
+ else
638
+ EXPRESS=1
639
+ fi
640
+ fi
641
+ else
642
+ warning "vsvars32.bat found, but registry value not located"
643
+ fi
644
+ fi
645
+
646
+ if [[ -n $INSTALL_DIR ]] ; then
647
+ if [[ ${TEST_PATH%/} = $(cygpath -u "$INSTALL_DIR\\..\\Tools") ]] ; then
648
+ RESULT=${COMPILERS[$i]%)}
649
+ DISPLAY=${COMPILER["NAME"]}
650
+ if [[ $EXPRESS -eq 1 ]] ; then
651
+ DISPLAY="$DISPLAY Express"
652
+ fi
653
+ FOUND+=(["$i"]="$RESULT [\"DISPLAY\"]=\"$DISPLAY\" [\"IS_EXPRESS\"]=\"$EXPRESS\")")
654
+ debug "${COMPILER["NAME"]} accepted for further detection"
655
+ else
656
+ warning "$ENV doesn't agree with registry"
657
+ fi
658
+ else
659
+ warning "vsvars32.bat found, but registry settings not found"
660
+ fi
661
+ else
662
+ warning "$ENV set, but vsvars32.bat not found"
663
+ fi
664
+ fi
665
+ elif [[ -n ${COMPILER["REG_KEY"]+x} ]] ; then
666
+ # SDK with explicit registry detection value
667
+ INSTALL_DIR=$(reg64_string "${COMPILER["REG_KEY"]}" "${COMPILER["REG_VALUE"]}")
668
+ if [[ -n $INSTALL_DIR ]] ; then
669
+ TEST_PATH=$(cygpath -u "$INSTALL_DIR")
670
+ if [[ -e $TEST_PATH/SetEnv.cmd ]] ; then
671
+ RESULT=${COMPILERS[$i]%)}
672
+ FOUND+=(["$i"]="$RESULT [\"DISPLAY\"]=\"${COMPILER["NAME"]}\" [\"SETENV\"]=\"$INSTALL_DIR\\SetEnv.cmd\")")
673
+ debug "${COMPILER["NAME"]} accepted for further detection"
674
+ else
675
+ warning "Registry set for Windows Server 2003 SDK, but SetEnv.cmd not found"
676
+ fi
677
+ fi
678
+ fi
679
+ done
680
+
681
+ # Now enumerate installed SDKs for v6.0+
682
+ SDK_ROOT='HKLM\SOFTWARE\Microsoft\Microsoft SDKs\Windows'
683
+ for i in $(reg query "$SDK_ROOT" 2>/dev/null | tr -d '\r' | sed -ne '/Windows\\v/s/.*\\//p') ; do
684
+ debug "Analysing SDK key $SDK_ROOT\\$i"
685
+ INSTALL_DIR=$(reg_string "$SDK_ROOT\\$i" InstallationFolder)
686
+ if [[ -n $INSTALL_DIR ]] ; then
687
+ TEST_PATH=$(cygpath -u "$INSTALL_DIR")
688
+ if [[ -e $TEST_PATH/Bin/SetEnv.cmd ]] ; then
689
+ if [[ -z ${COMPILERS["SDK${i#v}"]+x} ]] ; then
690
+ warning "SDK $i is not known to this script - assuming compatibility"
691
+ DISPLAY="Windows SDK $i"
692
+ else
693
+ eval COMPILER=${COMPILERS["SDK${i#v}"]}
694
+ DISPLAY=${COMPILER['NAME']}
695
+ fi
696
+ RESULT=${COMPILERS['SDK']%)}
697
+ FOUND+=(["SDK${i/v/}"]="$RESULT [\"DISPLAY\"]=\"$DISPLAY\" [\"SETENV\"]=\"$INSTALL_DIR\\Bin\\SetEnv.cmd\")")
698
+ else
699
+ if [[ -n ${COMPILERS["SDK${i#v}"]+x} ]] ; then
700
+ warning "Registry set for Windows SDK $i, but SetEnv.cmd not found"
701
+ fi
702
+ fi
703
+ else
704
+ warning "Registry key for Windows SDK $i doesn't contain expected InstallationFolder value"
705
+ fi
706
+ done
707
+
708
+ # Now enumerate Visual Studio 2017+ instances
709
+ VSWHERE=$(dirname $(realpath $0))/vswhere.exe
710
+ if [[ ! -x $VSWHERE ]] ; then
711
+ VSWHERE="$(printenv 'ProgramFiles(x86)')\\Microsoft Visual Studio\\Installer\\vswhere.exe"
712
+ VSWHERE=$(echo $VSWHERE| cygpath -f -)
713
+ fi
714
+ if [[ -x $VSWHERE ]] ; then
715
+ debug "$VSWHERE found"
716
+ while IFS= read -r line; do
717
+ case ${line%: *} in
718
+ instanceId)
719
+ INSTANCE=${line#*: };;
720
+ installationPath)
721
+ INSTANCE_PATH=${line#*: };;
722
+ installationVersion)
723
+ INSTANCE_VER=${line#*: }
724
+ INSTANCE_VER=${INSTANCE_VER%.*}
725
+ INSTANCE_VER=${INSTANCE_VER%.*};;
726
+ displayName)
727
+ INSTANCE_NAME=${line#*: }
728
+ debug "Looking at $INSTANCE in $INSTANCE_PATH ($INSTANCE_VER $INSTANCE_NAME)"
729
+ if [[ -e "$(echo $INSTANCE_PATH| cygpath -f -)/VC/Auxiliary/Build/vcvarsall.bat" ]] ; then
730
+ debug "vcvarsall.bat found"
731
+ FOUND+=(["VS$INSTANCE_VER"]="([\"DISPLAY\"]=\"$INSTANCE_NAME\" [\"ARCH\"]=\"x86 x64\" [\"SETENV\"]=\"$INSTANCE_PATH\\VC\\Auxiliary\\Build\\vcvarsall.bat\" [\"SETENV_RELEASE\"]=\"\")")
732
+ else
733
+ warning "vcvarsall.bat not found for $INSTANCE"
734
+ fi;;
735
+ esac
736
+ done < <("$VSWHERE" -all -nologo | tr -d '\r')
737
+ fi
738
+
739
+ if [[ $DEBUG -gt 1 ]] ; then
740
+ for i in "${!FOUND[@]}" ; do
741
+ echo "Inspect $i">&2
742
+ done
743
+ fi
744
+
745
+ # Basic scanning is complete, now interrogate the packages which seem to be installed and ensure
746
+ # that they pass the check_environment tests.
747
+
748
+ # CANDIDATES is a hash table of the keys of FOUND. The result of the next piece of processing is to
749
+ # derive two arrays PREFERENCE and TEST. TEST will contain a list of the keys of FOUND in the order
750
+ # in which they should be evaluated. PREFERENCE contains a parsed version of MSVS_PREFERENCE but
751
+ # filtered on the basis of the compiler packages already identified. The current "hoped for"
752
+ # preference is stored in $pref (the index into PREFERENCE) and $PREF (which is
753
+ # ${PREFERENCE[$pref]}). These two arrays together allow testing to complete quickly if the desired
754
+ # version is found (note that often this won't be possible as the @ environment option requires all
755
+ # packages to be tested in order to be sure that the environment compiler is not ambiguous).
756
+ declare -A CANDIDATES
757
+ for i in "${!FOUND[@]}" ; do
758
+ CANDIDATES[$i]="";
759
+ done
760
+
761
+ # For --all, act as though MSVS_PREFERENCE were "@" because this causes all packages to be tested.
762
+ if [[ $MODE -eq 1 ]] ; then
763
+ PREFER_ENV=1
764
+ PREFERENCE=("@")
765
+ else
766
+ PREFER_ENV=0
767
+ PREFERENCE=()
768
+ fi
769
+
770
+ TEST=()
771
+ for i in $MSVS_PREFERENCE ; do
772
+ if [[ $i = "@" ]] ; then
773
+ if [[ -n ${ENV_ARCH+x} ]] ; then
774
+ PREFERENCE+=("@")
775
+ PREFER_ENV=1
776
+ else
777
+ debug "Preference @ ignored since no environment compiler selected"
778
+ fi
779
+ else
780
+ if [[ -n ${COMPILERS[$i]+x} || -n ${COMPILERS[${i%.*}.*]+x} ]] ; then
781
+ if [[ -n ${CANDIDATES[$i]+x} ]] ; then
782
+ unset CANDIDATES[$i]
783
+ TEST+=($i)
784
+ PREFERENCE+=($i)
785
+ elif [[ ${i#*.} = "*" ]] ; then
786
+ INSTANCES=
787
+ for j in "${!CANDIDATES[@]}" ; do
788
+ if [[ "${j%.*}.*" = $i ]] ; then
789
+ unset CANDIDATES[$j]
790
+ INSTANCES="$INSTANCES $j"
791
+ fi
792
+ done
793
+ INSTANCES="$(sort -r <<< "${INSTANCES// /$'\n'}")"
794
+ eval TEST+=($INSTANCES)
795
+ eval PREFERENCE+=($INSTANCES)
796
+ fi
797
+ else
798
+ if [[ -n ${CANDIDATES["VS$i"]+x} ]] ; then
799
+ unset CANDIDATES["VS$i"]
800
+ TEST+=("VS$i")
801
+ PREFERENCE+=("VS$i")
802
+ fi
803
+ SDKS=
804
+ for j in "${!COMPILERS[@]}" ; do
805
+ eval COMPILER=${COMPILERS[$j]}
806
+ if [[ -n ${COMPILER["VC_VER"]+x} ]] ; then
807
+ if [[ $i = ${COMPILER["VC_VER"]} && -n ${CANDIDATES[$j]+x} ]] ; then
808
+ unset CANDIDATES[$j]
809
+ SDKS="$j $SDKS"
810
+ fi
811
+ fi
812
+ done
813
+ SDKS=${SDKS% }
814
+ SDKS="$(sort -r <<< "${SDKS// /$'\n'}")"
815
+ SDKS=${SDKS//$'\n'/ }
816
+ eval TEST+=($SDKS)
817
+ eval PREFERENCE+=($SDKS)
818
+ fi
819
+ fi
820
+ done
821
+
822
+ # If MSVS_PREFERENCE includes @, add any remaining items from CANDIDATES to TEST, otherwise remove
823
+ # them from FOUND so that they don't accidentally get reported on later.
824
+ for i in "${!CANDIDATES[@]}" ; do
825
+ if [[ $PREFER_ENV -eq 1 ]] ; then
826
+ TEST+=($i)
827
+ else
828
+ unset FOUND[$i]
829
+ fi
830
+ done
831
+
832
+ # Initialise pref and PREF to ${PREFERENCE[0]}
833
+ pref=0
834
+ PREF=${PREFERENCE[0]}
835
+
836
+ if [[ $DEBUG -gt 1 ]] ; then
837
+ for i in "${!TEST[@]}" ; do
838
+ echo "Test ${TEST[$i]}">&2
839
+ done
840
+ fi
841
+
842
+
843
+ # Now run each compiler's environment script and then test whether it is suitable. During this loop,
844
+ # attempt to identify the environment C compiler (if one was found). The environment C compiler is
845
+ # strongly identified if the full location of cl matches the one in PATH and both LIB and INCLUDE
846
+ # contain the strings returned by the script in an otherwise empty environment (if one or both of
847
+ # the LIB and INCLUDE variables do not contain the string returned, then the compiler is weakly
848
+ # identified). If the environment compiler is strongly identified by more than one package, then it
849
+ # is not identified at all; if it is strongly identified by no packages but weakly identified by
850
+ # exactly 1, then we grudgingly accept that that's probably the one.
851
+ ENV_COMPILER=
852
+ WEAK_ENV=
853
+
854
+ # ARCHINFO contains the appropriate ARCH_SWITCHES associative array for each compiler.
855
+ declare -A ARCHINFO
856
+
857
+ for i in "${TEST[@]}" ; do
858
+ CURRENT=${FOUND[$i]}
859
+ eval COMPILER=$CURRENT
860
+ # At the end of this process, the keys of FOUND will be augmented with the architecture found in
861
+ # each case (so if "VS14.0" was in FOUND from the scan and both the x86 and x64 compilers are
862
+ # valid, then at the end of this loop FOUND will contain "VS14.0-x86" and "VS14.0-x64").
863
+ unset FOUND[$i]
864
+
865
+ if [[ ${COMPILER["IS_EXPRESS"]}0 -gt 0 && -n ${COMPILER["EXPRESS_ARCH_SWITCHES"]+x} ]] ; then
866
+ eval ARCHINFO=${COMPILER["EXPRESS_ARCH_SWITCHES"]}
867
+ elif [[ -n ${COMPILER["ARCH_SWITCHES"]+x} ]] ; then
868
+ eval ARCHINFO=${COMPILER["ARCH_SWITCHES"]}
869
+ else
870
+ ARCHINFO=()
871
+ fi
872
+
873
+ # Determine the script to be executed and any non-architecture specific switches needed.
874
+ # $ENV is will contain the value of the environment variable for the compiler (empty for an SDK)
875
+ # which is required for Visual Studio 7.x shim later.
876
+ if [[ -n ${COMPILER["ENV"]+x} ]] ; then
877
+ ENV=VS${COMPILER["ENV"]}COMNTOOLS
878
+ ENV=${!ENV%\"}
879
+ ENV=${ENV#\"}
880
+ if [[ ${COMPILER["ENV"]}0 -ge 800 ]] ; then
881
+ SCRIPT="$(cygpath -d -f - <<< $ENV)\\..\\..\\VC\\vcvarsall.bat"
882
+ SCRIPT_SWITCHES=
883
+ else
884
+ SCRIPT="$(cygpath -d -f - <<< $ENV)\\vsvars32.bat"
885
+ SCRIPT_SWITCHES=
886
+ fi
887
+ else
888
+ ENV=
889
+ SCRIPT=${COMPILER["SETENV"]}
890
+ SCRIPT_SWITCHES=${COMPILER["SETENV_RELEASE"]}
891
+ fi
892
+ # For reasons of escaping, the script is executed using its basename so the directory needs
893
+ # prepending to PATH.
894
+ DIR=$(dirname "$SCRIPT" | cygpath -u -f -)
895
+
896
+ if [[ ${COMPILER["IS_EXPRESS"]} -gt 0 && -n ${COMPILER["EXPRESS_ARCH"]+x} ]] ; then
897
+ ARCHS=${COMPILER["EXPRESS_ARCH"]}
898
+ else
899
+ ARCHS=${COMPILER["ARCH"]}
900
+ fi
901
+
902
+ for arch in $ARCHS ; do
903
+ # Determine the command line switch for this architecture
904
+ if [[ -n ${ARCHINFO[$arch]+x} ]] ; then
905
+ ARCH_SWITCHES=${ARCHINFO[$arch]}
906
+ else
907
+ ARCH_SWITCHES=$arch
908
+ fi
909
+
910
+ # Run the script in order to determine changes made to PATH, INCLUDE and LIB. These scripts
911
+ # always prepend changes to the environment variables.
912
+ MSVS_PATH=
913
+ MSVS_LIB=
914
+ MSVS_INC=
915
+
916
+ COMMAND='%EXEC_SCRIPT% && echo XMARKER && echo !PATH! && echo !LIB! && echo !INCLUDE!'
917
+
918
+ # Note that EXEC_SCRIPT must have ARCH_SWITCHES first for older Platform SDKs (newer ones parse
919
+ # arguments properly)
920
+ if [[ $DEBUG -gt 3 ]] ; then
921
+ printf "Scanning %s... " "$(basename "$SCRIPT") $ARCH_SWITCHES $SCRIPT_SWITCHES">&2
922
+ fi
923
+ num=0
924
+ while IFS= read -r line; do
925
+ case $num in
926
+ 0)
927
+ MSVS_PATH=${line%% };;
928
+ 1)
929
+ MSVS_LIB=${line%% };;
930
+ 2)
931
+ MSVS_INC=${line%% };;
932
+ esac
933
+ ((num++))
934
+ done < <(INCLUDE='' LIB='' PATH="?msvs-detect?:$DIR:$PATH" ORIGINALPATH='' \
935
+ EXEC_SCRIPT="$(basename "$SCRIPT") $ARCH_SWITCHES $SCRIPT_SWITCHES" \
936
+ $(cygpath "$COMSPEC") ${SWITCH_PREFIX}v:on ${SWITCH_PREFIX}c $COMMAND 2>/dev/null | grep -F XMARKER -A 3 | tr -d '\015' | tail -3)
937
+ if [[ $DEBUG -gt 3 ]] ; then
938
+ echo done>&2
939
+ fi
940
+
941
+ if [[ -n $MSVS_PATH ]] ; then
942
+ # Translate MSVS_PATH back to Cygwin notation (/cygdrive, etc. and colon-separated)
943
+ MSVS_PATH=$(cygpath "$MSVS_PATH" -p)
944
+ # Remove any trailing / from elements of MSVS_PATH
945
+ MSVS_PATH=$(echo "$MSVS_PATH" | sed -e 's|\([^:]\)/\+\(:\|$\)|\1\2|g;s/?msvs-detect?.*//')
946
+ # Guarantee that MSVS_PATH ends with a single :
947
+ MSVS_PATH="${MSVS_PATH%%:}:"
948
+ fi
949
+ # Ensure that both variables end with a semi-colon (it doesn't matter if for some erroneous
950
+ # reason they have come back blank, because check_environment will shortly fail)
951
+ MSVS_LIB="${MSVS_LIB%%;};"
952
+ MSVS_INC="${MSVS_INC%%;};"
953
+
954
+ # Visual Studio .NET 2002 and 2003 do not include mt in PATH, for not entirely clear reasons.
955
+ # This shim detects that scenario and adds the winnt folder to MSVS_PATH.
956
+ RET=0
957
+ if [[ ${i/.*/} = "VS7" ]] ; then
958
+ find_in "${MSVS_PATH//:/*}" mt.exe
959
+ if [[ $RET -eq 1 ]] ; then
960
+ MSVS_PATH="$MSVS_PATH$(cygpath -u -f - <<< $ENV\\Bin\\winnt):"
961
+ RET=0
962
+ fi
963
+ fi
964
+
965
+ # Ensure that these derived values give a valid compiler.
966
+ if check_environment "${MSVS_PATH//:/*}" "${MSVS_INC//;/*}" "${MSVS_LIB//;/*}" "$i" $arch ; then
967
+ # Put the package back into FOUND, but augmented with the architecture name and with the
968
+ # derived values.
969
+ FOUND["$i-$arch"]="${CURRENT%)} [\"MSVS_PATH\"]=\"$MSVS_PATH\" \
970
+ [\"MSVS_INC\"]=\"$MSVS_INC\" \
971
+ [\"MSVS_LIB\"]=\"$MSVS_LIB\" \
972
+ [\"ASSEMBLER\"]=\"$ASSEMBLER\")" #"# fixes vim syn match error
973
+
974
+ # Check to see if this is a match for the environment C compiler.
975
+ if [[ -n ${ENV_ARCH+x} ]] ; then
976
+ TEST_cl=$(PATH="$MSVS_PATH:$PATH" "$WHICH" cl)
977
+ TEST_cl=${TEST_cl,,}
978
+ TEST_cl=${TEST_cl/bin\/*_/bin\/}
979
+ if [[ $TEST_cl = $ENV_cl ]] ; then
980
+ if [[ ${!ENV_INC/"$MSVS_INC"/} != "${!ENV_INC}" && \
981
+ ${!ENV_LIB/"$MSVS_LIB"/} != "${!ENV_LIB}" ]] ; then
982
+ debug "$i-$arch is a strong candidate for the Environment C compiler"
983
+ if [[ -n ${ENV_COMPILER+x} ]] ; then
984
+ if [[ -z ${ENV_COMPILER} ]] ; then
985
+ ENV_COMPILER=$i-$arch
986
+ unset WEAK_ENV
987
+ else
988
+ # More than one strong candidate - no fall back available
989
+ unset ENV_COMPILER
990
+ unset WEAK_ENV
991
+ fi
992
+ fi
993
+ else
994
+ debug "$i-$arch is a weak candidate for the Environment C compiler"
995
+ if [[ -n ${WEAK_ENV+x} ]] ; then
996
+ if [[ -z ${WEAK_ENV} ]] ; then
997
+ WEAK_ENV=$i-$arch
998
+ else
999
+ # More than one weak candidate - no fall back available
1000
+ unset WEAK_ENV
1001
+ fi
1002
+ fi
1003
+ fi
1004
+ fi
1005
+ fi
1006
+ fi
1007
+ done
1008
+
1009
+ # Does this package match the current preference? Note that PREFERENCE and TEST are constructed in
1010
+ # a cunning (and hopefully not too "You are not expected to understand this" way) such that $PREF
1011
+ # will always equal $i, unless $PREF = "@".
1012
+ if [[ $PREF = $i ]] ; then
1013
+ # In which case, check that the architecture(s)s were found
1014
+ if [[ -n ${FOUND["$i-$LEFT_ARCH"]+x} && -n ${FOUND["$i-$RIGHT_ARCH"]+x} ]] ; then
1015
+ debug "Solved TARGET_ARCH=$TARGET_ARCH with $i"
1016
+ SOLUTION=$i
1017
+ break
1018
+ fi
1019
+ fi
1020
+
1021
+ if [[ $PREF != "@" ]] ; then
1022
+ ((pref++))
1023
+ PREF=${PREFERENCE[$pref]}
1024
+ fi
1025
+ done
1026
+
1027
+ # If we got this far, then either we failed to find a compiler at all, or we were looking for the
1028
+ # environment compiler (or --all was specified).
1029
+
1030
+ # Adopt a weak match for the environment compiler, if that's the best we can do.
1031
+ if [[ -n ${ENV_COMPILER+x} && -z ${ENV_COMPILER} && -n ${WEAK_ENV} ]] ; then
1032
+ warning "Assuming Environment C compiler is $WEAK_ENV"
1033
+ ENV_COMPILER=$WEAK_ENV
1034
+ fi
1035
+
1036
+ declare -A FLIP
1037
+ FLIP=(["x86"]="x64" ["x64"]="x86")
1038
+
1039
+ if [[ $MODE -eq 0 ]] ; then
1040
+ if [[ $PREF = "@" && -n ${ENV_COMPILER} ]] ; then
1041
+ SOLUTION=${ENV_COMPILER%-$ENV_ARCH}
1042
+ # If --arch wasn't specified, then ensure that the other architecture was also found. If --arch
1043
+ # was specified, then validate that the compiler was valid. This should always happen, unless
1044
+ # something went wrong running the script to get MSVS_PATH, MSVS_LIB and MSVS_INC.
1045
+ if [[ -n ${FOUND["$SOLUTION-${FLIP[$ENV_ARCH]}"]+x} ||
1046
+ -n ${FOUND["$SOLUTION-$TARGET_ARCH"]+x} ]] ; then
1047
+ debug "Solved with $SOLUTION"
1048
+ else
1049
+ unset SOLUTION
1050
+ unset ENV_ARCH
1051
+ fi
1052
+ fi
1053
+
1054
+ if [[ -z ${SOLUTION+x} ]] ; then
1055
+ ((pref++))
1056
+ debug "Search remaining: ${PREFERENCE[*]}"
1057
+ TEST_ARCH=$TARGET_ARCH
1058
+ for i in "${PREFERENCE[@]:$pref}" ; do
1059
+ if [[ -n ${FOUND["$i-$LEFT_ARCH"]+x} && -n ${FOUND["$i-$RIGHT_ARCH"]+x} ]] ; then
1060
+ debug "Solved TARGET_ARCH='$TARGET_ARCH' with $i"
1061
+ SOLUTION=$i
1062
+ break
1063
+ fi
1064
+ done
1065
+ fi
1066
+ fi
1067
+
1068
+ debug "Solution: $SOLUTION"
1069
+
1070
+ if [[ -n ${ENV_COMPILER} && $MODE -eq 1 ]] ; then
1071
+ echo "Identified Environment C compiler as $ENV_COMPILER"
1072
+ fi
1073
+
1074
+ if [[ $MODE -eq 1 ]] ; then
1075
+ echo "Installed and usable packages:"
1076
+ for i in "${!FOUND[@]}" ; do
1077
+ echo " $i"
1078
+ done | sort
1079
+ exit 0
1080
+ fi
1081
+
1082
+ if [[ -n $SOLUTION ]] ; then
1083
+ eval COMPILER=${FOUND[$SOLUTION-$LEFT_ARCH]}
1084
+ output MSVS_NAME "${COMPILER["DISPLAY"]}" $LEFT_ARCH
1085
+ output MSVS_PATH "${COMPILER["MSVS_PATH"]}" $LEFT_ARCH
1086
+ output MSVS_INC "${COMPILER["MSVS_INC"]}" $LEFT_ARCH
1087
+ output MSVS_LIB "${COMPILER["MSVS_LIB"]}" $LEFT_ARCH
1088
+ if [[ $ML_REQUIRED -eq 1 ]] ; then
1089
+ output MSVS_ML "${COMPILER["ASSEMBLER"]%.exe}" always
1090
+ fi
1091
+ if [[ -z $TARGET_ARCH ]] ; then
1092
+ eval COMPILER=${FOUND[$SOLUTION-$RIGHT_ARCH]}
1093
+ output MSVS64_PATH "${COMPILER["MSVS_PATH"]}" $RIGHT_ARCH
1094
+ output MSVS64_INC "${COMPILER["MSVS_INC"]}" $RIGHT_ARCH
1095
+ output MSVS64_LIB "${COMPILER["MSVS_LIB"]}" $RIGHT_ARCH
1096
+ if [[ $ML_REQUIRED -eq 1 ]] ; then
1097
+ output MSVS64_ML "${COMPILER["ASSEMBLER"]%.exe}" always
1098
+ fi
1099
+ fi
1100
+ exit 0
1101
+ else
1102
+ exit 1
1103
+ fi