third_party: Import exact files from waf-2.0.8/waflib
[bbaumbach/samba.git] / third_party / waf / waflib / extras / cabal.py
1 #!/usr/bin/env python\r
2 # encoding: utf-8\r
3 # Anton Feldmann, 2012\r
4 # "Base for cabal"\r
5 \r
6 from waflib import Task, Utils\r
7 from waflib.TaskGen import extension\r
8 from waflib.Utils import threading\r
9 from shutil import rmtree\r
10 \r
11 lock = threading.Lock()\r
12 registering = False\r
13 \r
14 def configure(self):\r
15     self.find_program('cabal', var='CABAL')\r
16     self.find_program('ghc-pkg', var='GHCPKG')\r
17     pkgconfd = self.bldnode.abspath() + '/package.conf.d'\r
18     self.env.PREFIX = self.bldnode.abspath() + '/dist'\r
19     self.env.PKGCONFD = pkgconfd\r
20     if self.root.find_node(pkgconfd + '/package.cache'):\r
21         self.msg('Using existing package database', pkgconfd, color='CYAN')\r
22     else:\r
23         pkgdir = self.root.find_dir(pkgconfd)\r
24         if pkgdir:\r
25             self.msg('Deleting corrupt package database', pkgdir.abspath(), color ='RED')\r
26             rmtree(pkgdir.abspath())\r
27             pkgdir = None\r
28 \r
29         self.cmd_and_log(self.env.GHCPKG + ['init', pkgconfd])\r
30         self.msg('Created package database', pkgconfd, color = 'YELLOW' if pkgdir else 'GREEN')\r
31 \r
32 @extension('.cabal')\r
33 def process_cabal(self, node):\r
34     out_dir_node = self.bld.root.find_dir(self.bld.out_dir)\r
35     package_node = node.change_ext('.package')\r
36     package_node = out_dir_node.find_or_declare(package_node.name)\r
37     build_node   = node.parent.get_bld()\r
38     build_path   = build_node.abspath()\r
39     config_node  = build_node.find_or_declare('setup-config')\r
40     inplace_node = build_node.find_or_declare('package.conf.inplace')\r
41 \r
42     config_task = self.create_task('cabal_configure', node)\r
43     config_task.cwd = node.parent.abspath()\r
44     config_task.depends_on = getattr(self, 'depends_on', '')\r
45     config_task.build_path = build_path\r
46     config_task.set_outputs(config_node)\r
47 \r
48     build_task = self.create_task('cabal_build', config_node)\r
49     build_task.cwd = node.parent.abspath()\r
50     build_task.build_path = build_path\r
51     build_task.set_outputs(inplace_node)\r
52 \r
53     copy_task = self.create_task('cabal_copy', inplace_node)\r
54     copy_task.cwd = node.parent.abspath()\r
55     copy_task.depends_on = getattr(self, 'depends_on', '')\r
56     copy_task.build_path = build_path\r
57 \r
58     last_task = copy_task\r
59     task_list = [config_task, build_task, copy_task]\r
60 \r
61     if (getattr(self, 'register', False)):\r
62         register_task = self.create_task('cabal_register', inplace_node)\r
63         register_task.cwd = node.parent.abspath()\r
64         register_task.set_run_after(copy_task)\r
65         register_task.build_path = build_path\r
66 \r
67         pkgreg_task = self.create_task('ghcpkg_register', inplace_node)\r
68         pkgreg_task.cwd = node.parent.abspath()\r
69         pkgreg_task.set_run_after(register_task)\r
70         pkgreg_task.build_path = build_path\r
71 \r
72         last_task = pkgreg_task\r
73         task_list += [register_task, pkgreg_task]\r
74 \r
75     touch_task = self.create_task('cabal_touch', inplace_node)\r
76     touch_task.set_run_after(last_task)\r
77     touch_task.set_outputs(package_node)\r
78     touch_task.build_path = build_path\r
79 \r
80     task_list += [touch_task]\r
81 \r
82     return task_list\r
83 \r
84 def get_all_src_deps(node):\r
85     hs_deps = node.ant_glob('**/*.hs')\r
86     hsc_deps = node.ant_glob('**/*.hsc')\r
87     lhs_deps = node.ant_glob('**/*.lhs')\r
88     c_deps = node.ant_glob('**/*.c')\r
89     cpp_deps = node.ant_glob('**/*.cpp')\r
90     proto_deps = node.ant_glob('**/*.proto')\r
91     return sum([hs_deps, hsc_deps, lhs_deps, c_deps, cpp_deps, proto_deps], [])\r
92 \r
93 class Cabal(Task.Task):\r
94     def scan(self):\r
95         return (get_all_src_deps(self.generator.path), ())\r
96 \r
97 class cabal_configure(Cabal):\r
98     run_str = '${CABAL} configure -v0 --prefix=${PREFIX} --global --user --package-db=${PKGCONFD} --builddir=${tsk.build_path}'\r
99     shell = True\r
100 \r
101     def scan(self):\r
102         out_node = self.generator.bld.root.find_dir(self.generator.bld.out_dir)\r
103         deps = [out_node.find_or_declare(dep).change_ext('.package') for dep in Utils.to_list(self.depends_on)]\r
104         return (deps, ())\r
105 \r
106 class cabal_build(Cabal):\r
107     run_str = '${CABAL} build -v1 --builddir=${tsk.build_path}/'\r
108     shell = True\r
109 \r
110 class cabal_copy(Cabal):\r
111     run_str = '${CABAL} copy -v0 --builddir=${tsk.build_path}'\r
112     shell = True\r
113 \r
114 class cabal_register(Cabal):\r
115     run_str = '${CABAL} register -v0 --gen-pkg-config=${tsk.build_path}/pkg.config --builddir=${tsk.build_path}'\r
116     shell = True\r
117 \r
118 class ghcpkg_register(Cabal):\r
119     run_str = '${GHCPKG} update -v0 --global --user --package-conf=${PKGCONFD} ${tsk.build_path}/pkg.config'\r
120     shell = True\r
121 \r
122     def runnable_status(self):\r
123         global lock, registering\r
124 \r
125         val = False \r
126         lock.acquire()\r
127         val = registering\r
128         lock.release()\r
129 \r
130         if val:\r
131             return Task.ASK_LATER\r
132 \r
133         ret = Task.Task.runnable_status(self)\r
134         if ret == Task.RUN_ME:\r
135             lock.acquire()\r
136             registering = True\r
137             lock.release()\r
138 \r
139         return ret\r
140 \r
141     def post_run(self):\r
142         global lock, registering\r
143 \r
144         lock.acquire()\r
145         registering = False\r
146         lock.release()\r
147 \r
148         return Task.Task.post_run(self)\r
149 \r
150 class cabal_touch(Cabal):\r
151     run_str = 'touch ${TGT}'\r
152 \r