rename vshelper.h to VSHelper.h
[vapoursynth-svn.git] / wscript
blob22b3675fdd93ec5521b41e7eed9c8a10a46ee179
1 #!/usr/bin/env python
3 import os, subprocess
4 from waflib import Task, TaskGen, Utils
6 APPNAME = 'VapourSynth'
7 VERSION = '13'
9 TOP = os.curdir
10 OUT = 'build'
12 class preproc(Task.Task):
13 "Preprocess Cython source files"
15 ext_out = ['.pyx']
16 inst_to = None
17 color = 'CYAN'
19 def run(self):
20 if self.env.CXX_NAME == 'gcc':
21 params = ['-E', '-x', 'c']
22 elif self.env.CXX_NAME == 'msvc':
23 params = ['/nologo', '/E']
25 args = [Utils.subst_vars('${CC}', self.env)] + params + [self.inputs[0].abspath()]
27 with open(self.outputs[0].abspath(), 'w') as f:
28 subprocess.Popen(args, stdout = f).wait()
30 @TaskGen.extension('.pyx')
31 def add_pyx_file(self, node):
32 self.create_task('preproc', node, node.get_bld().change_ext('.pyx'))
34 class docs(Task.Task):
35 "Build Sphinx documentation"
37 ext_out = ['.html']
38 inst_to = None
39 color = 'PINK'
41 def run(self):
42 subprocess.Popen('make html BUILDDIR={0}'.format(os.path.join(os.pardir, OUT)),
43 shell = True,
44 cwd = 'doc',
45 stdout = subprocess.PIPE).wait()
47 @TaskGen.feature('docs')
48 @TaskGen.before_method('process_source')
49 def apply_rst(self):
50 rst_nodes = []
51 no_nodes = []
53 for x in self.to_nodes(self.source):
54 if x.name.endswith('.rst'):
55 rst_nodes.append(x)
56 else:
57 no_nodes.append(x)
59 self.source = no_nodes
61 inst = getattr(self, 'install_path', '${DOCDIR}')
62 mod = getattr(self, 'chmod', Utils.O644)
64 bld_nodes = []
65 i = 0
67 for node in rst_nodes:
68 n = self.path.find_node(OUT).make_node('html')
70 cur = node.parent
71 dirs = []
73 while not cur is self.path.find_node('doc'):
74 dirs.append(cur)
75 cur = cur.parent
77 for dir in reversed(dirs):
78 n = n.make_node(dir.name)
80 n = n.make_node(node.name).change_ext('.html')
82 bld_nodes.append(n)
84 if inst:
85 path = inst
87 for dir in reversed(dirs):
88 path = os.path.join(path, dir.name)
90 setattr(self, 'install_task_{0}'.format(i), self.bld.install_files(path, n, env = self.env, chmod = mod))
92 i += 1
94 self.rst_task = self.create_task('docs', rst_nodes, bld_nodes)
96 def options(opt):
97 opt.load('compiler_c')
98 opt.load('compiler_cxx')
99 opt.load('qt4')
101 opt.add_option('--libdir', action = 'store', default = '${PREFIX}/lib', help = 'library installation directory')
102 opt.add_option('--plugindir', action = 'store', default = '${LIBDIR}/vapoursynth', help = 'plugin installation directory')
103 opt.add_option('--docdir', action = 'store', default = '${PREFIX}/share/doc/vapoursynth', help = 'documentation installation directory')
104 opt.add_option('--includedir', action = 'store', default = '${PREFIX}/include', help = 'header installation directory')
105 opt.add_option('--mode', action = 'store', default = 'release', help = 'the mode to compile in (debug/release)')
106 opt.add_option('--static', action = 'store', default = 'false', help = 'build a static library (true/false)')
107 opt.add_option('--filters', action = 'store', default = 'true', help = 'build included filters (true/false)')
108 opt.add_option('--cython', action = 'store', default = 'true', help = 'build Cython wrapper (true/false)')
109 opt.add_option('--avisynth', action = 'store', default = 'true', help = 'build Avisynth compatibility layer (true/false)')
110 opt.add_option('--docs', action = 'store', default = 'false', help = 'build the documentation (true/false)')
111 opt.add_option('--examples', action = 'store', default = 'false', help = 'install SDK examples (true/false)')
113 def configure(conf):
114 def add_options(flags, options):
115 for flag in flags:
116 conf.env.append_unique(flag, options)
118 conf.load('compiler_c')
119 conf.load('compiler_cxx')
120 conf.load('qt4')
122 # Load Yasm explicitly, then the Nasm module which
123 # supports both Nasm and Yasm.
124 conf.find_program('yasm', var = 'AS', mandatory = True)
125 conf.load('nasm')
127 if conf.env.DEST_OS == 'darwin':
128 if conf.env.CXX_NAME == 'gcc':
129 add_options(['ASFLAGS'],
130 ['-DPREFIX'])
132 if conf.env.CXX_NAME == 'gcc':
133 add_options(['CFLAGS', 'CXXFLAGS'],
134 ['-DVSCORE_EXPORTS',
135 '-fPIC'])
136 elif conf.env.CXX_NAME == 'msvc':
137 add_options(['CFLAGS', 'CXXFLAGS'],
138 ['/DVSCORE_EXPORTS',
139 '/EHsc',
140 '/Zc:wchar_t-'])
142 add_options(['ASFLAGS'],
143 ['-w',
144 '-Worphan-labels',
145 '-Wunrecognized-char'])
147 if conf.env.DEST_CPU in ['x86_64', 'amd64', 'x64']:
148 add_options(['ASFLAGS'],
149 ['-DARCH_X86_64=1'])
151 if conf.env.DEST_OS == 'darwin':
152 fmt = 'macho64'
153 elif conf.env.DEST_OS == 'win32':
154 fmt = 'win64'
155 else:
156 fmt = 'elf64'
157 else:
158 add_options(['ASFLAGS'],
159 ['-DARCH_X86_64=0'])
161 if conf.env.DEST_OS == 'darwin':
162 fmt = 'macho32'
163 elif conf.env.DEST_OS == 'win32':
164 fmt = 'win32'
165 else:
166 fmt = 'elf32'
168 add_options(['ASFLAGS'],
169 ['-f{0}'.format(fmt)])
171 if conf.options.mode == 'debug':
172 if conf.env.CXX_NAME == 'gcc':
173 add_options(['CFLAGS', 'CXXFLAGS'],
174 ['-DVSCORE_DEBUG',
175 '-g',
176 '-ggdb',
177 '-ftrapv'])
178 elif conf.env.CXX_NAME == 'msvc':
179 add_options(['CFLAGS', 'CXXFLAGS'],
180 ['/DVSCORE_DEBUG',
181 '/Z7'])
183 add_options(['ASFLAGS'],
184 ['-DVSCORE_DEBUG'])
185 elif conf.options.mode == 'release':
186 if conf.env.CXX_NAME == 'gcc':
187 add_options(['CFLAGS', 'CXXFLAGS'],
188 ['-O3'])
189 elif conf.env.CXX_NAME == 'msvc':
190 add_options(['CFLAGS', 'CXXFLAGS'],
191 ['/Ox'])
192 else:
193 conf.fatal('--mode must be either debug or release.')
195 # Waf always uses gcc/g++ for linking when using a GCC
196 # compatible C/C++ compiler.
197 if conf.env.CXX_NAME == 'gcc':
198 add_options(['LINKFLAGS_cxxshlib', 'LINKFLAGS_cxxprogram'],
199 ['-Wl,-Bsymbolic'])
201 for opt in ['static', 'filters', 'cython', 'avisynth', 'docs', 'examples']:
202 if not conf.options.__dict__[opt] in ['true', 'false']:
203 conf.fatal('--{0} must be either true or false.'.format(opt))
204 else:
205 conf.env[opt.upper()] = conf.options.__dict__[opt]
207 conf.define('PATH_PREFIX', conf.env.PREFIX)
209 for dir in ['libdir', 'plugindir', 'docdir', 'includedir']:
210 u = dir.upper()
212 conf.env[u] = Utils.subst_vars(conf.options.__dict__[dir], conf.env)
213 conf.define('PATH_' + u, conf.env[u])
215 conf.check_cxx(use = ['QTCORE'], header_name = 'QtCore/QtCore')
216 conf.check_cxx(use = ['QTCORE'], header_name = 'QtCore/QtCore', type_name = 'QAtomicInt')
218 conf.check_cc(lib = 'avutil')
219 conf.check_cc(use = ['AVUTIL'], header_name = 'libavutil/avutil.h')
220 conf.check_cc(use = ['AVUTIL'], header_name = 'libavutil/avutil.h', function_name = 'avutil_license')
222 conf.check_cc(lib = 'swscale')
223 conf.check_cc(use = ['SWSCALE'], header_name = 'libswscale/swscale.h')
224 conf.check_cc(use = ['SWSCALE'], header_name = 'libswscale/swscale.h', function_name = 'swscale_license')
226 libs = '-lm '
228 if not conf.env.DEST_OS in ['darwin', 'freebsd', 'netbsd', 'openbsd']:
229 libs += '-ldl '
231 conf.env.LIBS = libs.strip()
233 def build(bld):
234 def search_paths(paths):
235 srcpaths = []
237 for path in paths:
238 srcpaths += [os.path.join(path, '*.c'),
239 os.path.join(path, '*.cpp'),
240 os.path.join(path, '*.asm')]
242 return srcpaths
244 sources = search_paths([os.path.join('src', 'core'),
245 os.path.join('src', 'core', 'asm')])
247 if bld.env.DEST_OS == 'win32' and bld.env.AVISYNTH == 'true':
248 sources += search_paths([os.path.join('src', 'avisynth')])
250 bld(features = 'c qxx asm',
251 includes = 'include',
252 use = ['QTCORE', 'SWSCALE', 'AVUTIL'],
253 source = bld.path.ant_glob(sources),
254 target = 'objs')
256 bld(features = 'c qxx asm cxxshlib',
257 use = ['objs'],
258 target = 'vapoursynth',
259 install_path = '${LIBDIR}')
261 if bld.env.STATIC == 'true':
262 bld(features = 'c qxx asm cxxstlib',
263 use = ['objs', 'QTCORE', 'SWSCALE', 'AVUTIL'],
264 target = 'vapoursynth',
265 install_path = '${LIBDIR}')
267 if bld.env.FILTERS == 'true':
268 bld(features = 'c qxx asm cxxshlib',
269 includes = 'include',
270 use = ['vapoursynth'],
271 source = bld.path.ant_glob(search_paths([os.path.join('src', 'filters', 'eedi3')])),
272 target = 'eedi3',
273 install_path = '${PLUGINDIR}')
275 if bld.env.CYTHON == 'true':
276 bld(features = 'preproc',
277 source = bld.path.ant_glob([os.path.join('src', 'cython', '*.pyx')]))
279 if bld.env.DOCS == 'true':
280 bld(features = 'docs',
281 source = bld.path.ant_glob([os.path.join('doc', '*.rst'),
282 os.path.join('doc', '**', '*.rst')]),
283 install_path = '${DOCDIR}')
285 if bld.env.EXAMPLES == 'true':
286 bld(features = 'c cxxshlib',
287 includes = 'include',
288 use = ['vapoursynth'],
289 source = os.path.join('sdk', 'filter_skeleton.c'),
290 target = 'example_skeleton',
291 install_path = None)
293 bld(features = 'c cxxshlib',
294 includes = 'include',
295 use = ['vapoursynth'],
296 source = os.path.join('sdk', 'invert_example.c'),
297 target = 'example_invert',
298 install_path = None)
300 bld.install_files('${DOCDIR}/examples',
301 bld.path.ant_glob([os.path.join('sdk', '*')]))
303 bld.install_files('${INCLUDEDIR}', os.path.join('include', 'VapourSynth.h'))
305 bld(source = 'vapoursynth.pc.in',
306 install_path = '${LIBDIR}/pkgconfig',
307 PREFIX = bld.env.PREFIX,
308 LIBDIR = bld.env.LIBDIR,
309 INCLUDEDIR = bld.env.INCLUDEDIR,
310 LIBS = bld.env.LIBS,
311 VERSION = VERSION)