4 from waflib
import Task
, TaskGen
, Utils
6 APPNAME
= 'VapourSynth'
12 class preproc(Task
.Task
):
13 "Preprocess Cython source files"
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"
42 subprocess
.Popen('make html BUILDDIR={0}'.format(os
.path
.join(os
.pardir
, OUT
)),
45 stdout
= subprocess
.PIPE
).wait()
47 @TaskGen.feature('docs')
48 @TaskGen.before_method('process_source')
53 for x
in self
.to_nodes(self
.source
):
54 if x
.name
.endswith('.rst'):
59 self
.source
= no_nodes
61 inst
= getattr(self
, 'install_path', '${DOCDIR}')
62 mod
= getattr(self
, 'chmod', Utils
.O644
)
67 for node
in rst_nodes
:
68 n
= self
.path
.find_node(OUT
).make_node('html')
73 while not cur
is self
.path
.find_node('doc'):
77 for dir in reversed(dirs
):
78 n
= n
.make_node(dir.name
)
80 n
= n
.make_node(node
.name
).change_ext('.html')
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
))
94 self
.rst_task
= self
.create_task('docs', rst_nodes
, bld_nodes
)
97 opt
.load('compiler_c')
98 opt
.load('compiler_cxx')
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)')
114 def add_options(flags
, options
):
116 conf
.env
.append_unique(flag
, options
)
118 conf
.load('compiler_c')
119 conf
.load('compiler_cxx')
122 # Load Yasm explicitly, then the Nasm module which
123 # supports both Nasm and Yasm.
124 conf
.find_program('yasm', var
= 'AS', mandatory
= True)
127 if conf
.env
.DEST_OS
== 'darwin':
128 if conf
.env
.CXX_NAME
== 'gcc':
129 add_options(['ASFLAGS'],
132 if conf
.env
.CXX_NAME
== 'gcc':
133 add_options(['CFLAGS', 'CXXFLAGS'],
136 elif conf
.env
.CXX_NAME
== 'msvc':
137 add_options(['CFLAGS', 'CXXFLAGS'],
142 add_options(['ASFLAGS'],
145 '-Wunrecognized-char'])
147 if conf
.env
.DEST_CPU
in ['x86_64', 'amd64', 'x64']:
148 add_options(['ASFLAGS'],
151 if conf
.env
.DEST_OS
== 'darwin':
153 elif conf
.env
.DEST_OS
== 'win32':
158 add_options(['ASFLAGS'],
161 if conf
.env
.DEST_OS
== 'darwin':
163 elif conf
.env
.DEST_OS
== 'win32':
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'],
178 elif conf
.env
.CXX_NAME
== 'msvc':
179 add_options(['CFLAGS', 'CXXFLAGS'],
183 add_options(['ASFLAGS'],
185 elif conf
.options
.mode
== 'release':
186 if conf
.env
.CXX_NAME
== 'gcc':
187 add_options(['CFLAGS', 'CXXFLAGS'],
189 elif conf
.env
.CXX_NAME
== 'msvc':
190 add_options(['CFLAGS', 'CXXFLAGS'],
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'],
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
))
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']:
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')
228 if not conf
.env
.DEST_OS
in ['darwin', 'freebsd', 'netbsd', 'openbsd']:
231 conf
.env
.LIBS
= libs
.strip()
234 def search_paths(paths
):
238 srcpaths
+= [os
.path
.join(path
, '*.c'),
239 os
.path
.join(path
, '*.cpp'),
240 os
.path
.join(path
, '*.asm')]
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
),
256 bld(features
= 'c qxx asm cxxshlib',
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')])),
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',
293 bld(features
= 'c cxxshlib',
294 includes
= 'include',
295 use
= ['vapoursynth'],
296 source
= os
.path
.join('sdk', 'invert_example.c'),
297 target
= 'example_invert',
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
,