clang_cl.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. # vim: sw=4 ts=4 noexpandtab
  4. """
  5. LLVM Clang-CL support.
  6. Clang-CL is supposed to be a drop-in replacement for MSVC CL, but also serves
  7. well as a cross compiler for Windows from Linux (provided you have set up the
  8. environment). Requires Visual Studio 2015+ to be installed.
  9. On Windows it uses (most) MSVC tools.
  10. Usage:
  11. $ waf configure
  12. Or:
  13. $ LLVM_PATH=C:\\Program Files\\LLVM\\bin waf configure
  14. Or:
  15. def configure(self):
  16. self.env.LLVM_PATH = 'C:\\Program Files\\LLVM\\bin'
  17. self.load('clang_cl')
  18. """
  19. import os
  20. from waflib import Utils, Errors, Logs
  21. from waflib.Configure import conf
  22. from waflib.Tools import msvc
  23. def options(opt):
  24. msvc.options(opt)
  25. @conf
  26. def get_llvm_paths(self):
  27. llvm_path = []
  28. if Utils.is_win32:
  29. try:
  30. llvm_key = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE,'SOFTWARE\\Wow6432Node\\LLVM\\LLVM')
  31. except OSError:
  32. try:
  33. llvm_key = Utils.winreg.OpenKey(Utils.winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\LLVM\\LLVM')
  34. except OSError:
  35. llvm_key = None
  36. if llvm_key:
  37. llvm_dir, _ = Utils.winreg.QueryValueEx(llvm_key, '')
  38. if llvm_dir:
  39. llvm_path.append(os.path.join(llvm_dir, 'bin'))
  40. tmp = self.environ.get('LLVM_PATH') or self.env.LLVM_PATH
  41. if tmp:
  42. llvm_path.append(tmp)
  43. llvm_path += self.env.PATH
  44. return llvm_path
  45. @conf
  46. def find_clang_cl(self):
  47. """
  48. Find the program clang-cl.
  49. """
  50. del(self.env.CC)
  51. del(self.env.CXX)
  52. paths = self.get_llvm_paths()
  53. cc = self.find_program('clang-cl', var='CC', path_list=paths)
  54. self.env.CC = self.env.CXX = cc
  55. self.env.CC_NAME_SECONDARY = self.env.CXX_NAME_SECONDARY = 'clang'
  56. if not Utils.is_win32:
  57. self.env.MSVC_COMPILER = 'msvc'
  58. self.env.MSVC_VERSION = 19
  59. if not self.env.LINK_CXX:
  60. self.find_program('lld-link', path_list=paths, errmsg='lld-link was not found (linker)', var='LINK_CXX')
  61. if not self.env.LINK_CC:
  62. self.env.LINK_CC = self.env.LINK_CXX
  63. @conf
  64. def find_llvm_tools(self):
  65. """
  66. Find the librarian, manifest tool, and resource compiler.
  67. """
  68. self.env.CC_NAME = self.env.CXX_NAME = 'msvc'
  69. paths = self.get_llvm_paths()
  70. llvm_path = self.environ.get('LLVM_PATH') or self.env.LLVM_PATH
  71. if llvm_path:
  72. paths = [llvm_path] + self.env.PATH
  73. else:
  74. paths = self.env.PATH
  75. if not self.env.AR:
  76. stliblink = self.find_program('llvm-lib', path_list=paths, var='AR')
  77. if not stliblink:
  78. self.fatal('Unable to find required program "llvm-lib"')
  79. self.env.ARFLAGS = ['/nologo']
  80. # We assume clang_cl to only be used with relatively new MSVC installations.
  81. self.env.MSVC_MANIFEST = True
  82. self.find_program('llvm-mt', path_list=paths, var='MT')
  83. self.env.MTFLAGS = ['/nologo']
  84. try:
  85. self.load('winres')
  86. except Errors.ConfigurationError:
  87. Logs.warn('Resource compiler not found. Compiling resource file is disabled')
  88. def configure(self):
  89. if Utils.is_win32:
  90. self.autodetect(True)
  91. self.find_msvc()
  92. else:
  93. self.find_llvm_tools()
  94. self.find_clang_cl()
  95. self.msvc_common_flags()
  96. self.cc_load_tools()
  97. self.cxx_load_tools()
  98. self.cc_add_flags()
  99. self.cxx_add_flags()
  100. self.link_add_flags()
  101. self.visual_studio_add_flags()