1#! /usr/bin/env python
2# Build Python extension with configuration file input
3#
4#  Copyright (C) 2006  Peter Johnson
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9# 1. Redistributions of source code must retain the above copyright
10#    notice, this list of conditions and the following disclaimer.
11# 2. Redistributions in binary form must reproduce the above copyright
12#    notice, this list of conditions and the following disclaimer in the
13#    documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
16# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
19# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26
27from distutils.core import setup
28from distutils.extension import Extension
29from Cython.Distutils import build_ext
30from os.path import basename, join, exists
31
32def ReadSetup(filename):
33    """ReadSetup goes through filename and parses out the values stored
34    in the file.  Values need to be stored in a
35    \"key=value format\""""
36    return dict(line.split('=', 1) for line in open(filename))
37
38def ParseCPPFlags(flags):
39    """parse the CPPFlags macro"""
40    incl_dir = [x[2:] for x in flags.split() if x.startswith("-I")]
41    cppflags = [x for x in flags.split() if not x.startswith("-I")]
42    cppflags.append("-DYASM_LIB_INTERNAL")
43    cppflags.append("-DYASM_BC_INTERNAL")
44    cppflags.append("-DYASM_EXPR_INTERNAL")
45    return (incl_dir, cppflags)
46
47def ParseSources(src, srcdir):
48    """parse the Sources macro"""
49    # do the dance of detecting if the source file is in the current
50    # directory, and if it's not, prepend srcdir
51    sources = []
52    for tok in src.split():
53        if tok.endswith(".c"):
54            fn = tok
55        else:
56            continue
57        if not exists(fn):
58            fn = join(srcdir, fn)
59        sources.append(fn)
60
61    return sources
62
63def RunSetup(incldir, cppflags, sources):
64    setup(
65          name='yasm',
66          version='0.0',
67          description='Python bindings for Yasm',
68          author='Michael Urman, Peter Johnson',
69          url='http://www.tortall.net/projects/yasm',
70          ext_modules=[
71                       Extension('yasm',
72                                 sources=sources,
73                                 extra_compile_args=cppflags,
74                                 include_dirs=incldir,
75                       ),
76                      ],
77          cmdclass = dict(build_ext=build_ext),
78         )
79
80if __name__ == "__main__":
81    opts = ReadSetup("python-setup.txt")
82    incldir, cppflags = ParseCPPFlags(opts["includes"])
83    sources = ParseSources(opts["sources"], opts["srcdir"].strip())
84    sources.append('yasm_python.c')
85    if opts["gcc"].strip() == "yes":
86        cppflags.append('-w')
87    RunSetup(incldir, cppflags, sources)
88
89