wscript 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #! /usr/bin/env python
  2. # encoding: utf-8
  3. # Thomas Nagy, 2006-2010 (ita)
  4. # the following two variables are used by the target "waf dist"
  5. VERSION='0.0.1'
  6. APPNAME='cxx_test'
  7. # these variables are mandatory ('/' are converted automatically)
  8. top = '.'
  9. out = 'debug'
  10. import re
  11. from functools import partial
  12. from pathlib import Path
  13. class TestRecognizer:
  14. RE_FIND_WAF_INFO = re.compile(r"[^\w]waf_test_[A-Za-z0-9_]+\(")
  15. def __init__(self, bld, file):
  16. self.bld = bld
  17. self.file = Path(file)
  18. self.root = Path(str(bld.top_dir))
  19. self.src_dir = self.root / "src"
  20. self.tests_dir = self.root / "tests"
  21. self.target = {
  22. "source" : [self.file.name],
  23. "target" : self.file.name.replace(".cpp", ""),
  24. "includes" : [".", "..", str(self.src_dir), str(self.tests_dir)],
  25. "lib" : ["SDL2", "SDL2_image", "fftw3", "sndfile"],
  26. "use" : ["io", "core", ]
  27. }
  28. def recognize(self, content, reco):
  29. start = reco.regs[0][0]+1
  30. curr = start
  31. while content[curr] != "(":
  32. curr +=1
  33. function = content[start : curr].strip(" \n\t")
  34. start = curr
  35. curr += 1
  36. count = 1
  37. while count>0:
  38. if content[curr] == ")":
  39. count-=1
  40. if content[curr] == "(":
  41. count+=1
  42. curr +=1
  43. args = content[start:curr+1]
  44. args = eval(args)
  45. if not isinstance(args, (tuple, list)):
  46. args = [args]
  47. args = list(args)
  48. f_name = f"execute_{function[9:]}"
  49. if not hasattr(self, f_name):
  50. nb = len(content[:start].split("\n")) + 1
  51. raise ValueError(f"Fichier {self.file} ligne {nb} waf_test_{f_name} est inconnu")
  52. getattr(self, f_name)(args)
  53. def _add_or_append(self, k, v):
  54. if k not in self.target:
  55. self.target[k] = []
  56. if not isinstance(self.target[k], list):
  57. self.target[k] = [*(self.target[k].split(" "))]
  58. self.target[k].extend(v)
  59. def execute_use(self, data):
  60. self._add_or_append("use", data)
  61. def add_test(self):
  62. content = Path(self.file).read_text()
  63. for x in self.RE_FIND_WAF_INFO.finditer(content):
  64. self.recognize(content, x)
  65. print(f"add program : {self.target}")
  66. self.bld.program(**self.target)
  67. def find_test(bld):
  68. dir = str(bld.path)
  69. for file in Path(dir).iterdir():
  70. if file.is_file() and file.name.endswith(".cpp"):
  71. TestRecognizer(bld, file).add_test()
  72. elif file.is_dir() and (file / "wscript").is_file():
  73. bld.recurse(file.name)
  74. def get_sub_files(obj, suffixes=(".c", ".cpp", ".cxx"), max_depth=None):
  75. root = Path(str(obj.path))
  76. if root.is_file():
  77. root = root.parent
  78. queue = [(0, root)]
  79. ret = []
  80. while queue:
  81. depth, curr = queue.pop()
  82. if max_depth is not None and depth>max_depth: continue
  83. for file in curr.iterdir():
  84. if file.is_file():
  85. if not suffixes or file.name.endswith(suffixes):
  86. ret.append(str(file.relative_to(root)))
  87. elif file.is_dir():
  88. queue.append((depth+1, file))
  89. return ret
  90. def options(opt):
  91. opt.load('compiler_cxx')
  92. def configure(conf):
  93. conf.load('compiler_cxx')
  94. conf.env.append_value('CXXFLAGS', '-g')
  95. conf.check(header_name='stdio.h', features='cxx cxxprogram', mandatory=False)
  96. def build(bld):
  97. bld.find_test = partial(find_test, bld)
  98. bld.get_sub_files = partial(get_sub_files, bld)
  99. bld.recurse("src/common")
  100. bld.recurse("src/core")
  101. bld.recurse("src/fft")
  102. bld.recurse("src/io")
  103. bld.recurse("src/plugins")
  104. bld.recurse("tests")
  105. bld.program(target=APPNAME,
  106. features='cxx cxxprogram',
  107. lib=['fftw3', "sndfile"],
  108. use=["common", "fft", "io"])