Be more general when specifying icu- libraries.
[libsub.git] / wscript
1 import subprocess
2 import os
3 from waflib import Context
4
5 APPNAME = 'libsub'
6 VERSION = '1.2.4devel'
7 API_VERSION = '-1.0'
8
9 def options(opt):
10     opt.load('compiler_cxx')
11     opt.add_option('--enable-debug', action='store_true', default=False, help='build with debugging information and without optimisation')
12     opt.add_option('--static', action='store_true', default=False, help='build libsub statically and link statically to cxml and dcp')
13     opt.add_option('--target-windows', action='store_true', default=False, help='set up to do a cross-compile to make a Windows package')
14     opt.add_option('--disable-tests', action='store_true', default=False, help='disable building of tests')
15
16 def configure(conf):
17     conf.load('compiler_cxx')
18     conf.env.append_value('CXXFLAGS', ['-Wall', '-Wextra', '-D_FILE_OFFSET_BITS=64', '-D__STDC_FORMAT_MACROS'])
19     conf.env.append_value('CXXFLAGS', ['-DLIBSUB_VERSION="%s"' % VERSION])
20
21     conf.env.ENABLE_DEBUG = conf.options.enable_debug
22     conf.env.STATIC = conf.options.static
23     conf.env.TARGET_WINDOWS = conf.options.target_windows
24     conf.env.DISABLE_TESTS = conf.options.disable_tests
25     conf.env.API_VERSION = API_VERSION
26
27     if conf.options.enable_debug:
28         conf.env.append_value('CXXFLAGS', '-g')
29     else:
30         conf.env.append_value('CXXFLAGS', '-O3')
31
32     # Disable libxml++ deprecation warnings for now
33     conf.env.append_value('CXXFLAGS', ['-Wno-deprecated-declarations'])
34
35     conf.check_cfg(package='openssl', args='--cflags --libs', uselib_store='OPENSSL', mandatory=True)
36
37     if conf.options.static:
38         conf.check_cfg(package='libcxml', atleast_version='0.14.0', args='--cflags', uselib_store='CXML', mandatory=True)
39         conf.env.HAVE_CXML = 1
40         conf.env.LIB_CXML = ['glibmm-2.4', 'glib-2.0', 'pcre', 'sigc-2.0', 'rt', 'xml++-2.6', 'xml2', 'pthread', 'lzma', 'dl', 'z']
41         conf.env.STLIB_CXML = ['cxml']
42         conf.check_cfg(package='libdcp-1.0', atleast_version='1.4.4', args='--cflags', uselib_store='DCP', mandatory=True)
43         conf.env.HAVE_DCP = 1
44         conf.env.STLIB_DCP = ['dcp-1.0', 'asdcp-cth', 'kumu-cth', 'openjp2']
45         conf.env.LIB_DCP = ['ssl', 'crypto', 'xmlsec1-openssl', 'xmlsec1']
46     else:
47         conf.check_cfg(package='libcxml', atleast_version='0.15.2', args='--cflags --libs', uselib_store='CXML', mandatory=True)
48         conf.check_cfg(package='libdcp-1.0', atleast_version='1.4.4', args='--cflags --libs', uselib_store='DCP', mandatory=True)
49
50     conf.env.DEFINES_DCP = [f.replace('\\', '') for f in conf.env.DEFINES_DCP]
51
52     boost_lib_suffix = ''
53     if conf.env.TARGET_WINDOWS:
54         boost_lib_suffix = '-mt'
55
56     conf.check_cxx(fragment="""
57                             #include <boost/version.hpp>\n
58                             #if BOOST_VERSION < 104500\n
59                             #error boost too old\n
60                             #endif\n
61                             int main(void) { return 0; }\n
62                             """,
63                    mandatory=True,
64                    msg='Checking for boost library >= 1.45',
65                    okmsg='yes',
66                    errmsg='too old\nPlease install boost version 1.45 or higher.')
67
68     conf.check_cxx(fragment="""
69                             #include <boost/filesystem.hpp>\n
70                             int main() { boost::filesystem::copy_file ("a", "b"); }\n
71                             """,
72                    msg='Checking for boost filesystem library',
73                    libpath='/usr/local/lib',
74                    lib=['boost_filesystem%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix],
75                    uselib_store='BOOST_FILESYSTEM')
76
77     # Find the icu- libraries on the system as we need to link to them when we look for boost locale.
78     locale_libs = ['boost_locale%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix]
79     for pkg in subprocess.check_output(['pkg-config', '--list-all']).splitlines():
80         if pkg.startswith("icu-"):
81             for lib in subprocess.check_output(['pkg-config', '--libs', pkg.split()[0]]).split():
82                 name = lib[2:]
83                 if not name in locale_libs:
84                     locale_libs.append(name)
85
86     conf.check_cxx(fragment="""
87                             #include <boost/locale.hpp>\n
88                             int main() { boost::locale::conv::to_utf<char> ("a", "cp850"); }\n
89                             """,
90                    msg='Checking for boost locale library',
91                    libpath='/usr/local/lib',
92                    lib=locale_libs,
93                    uselib_store='BOOST_LOCALE')
94
95     conf.check_cxx(fragment="""
96                             #include <boost/regex.hpp>\n
97                             int main() { boost::regex re ("foo"); }\n
98                             """,
99                    msg='Checking for boost regex library',
100                    libpath='/usr/local/lib',
101                    lib=['boost_regex%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix],
102                    uselib_store='BOOST_REGEX')
103
104     if not conf.env.DISABLE_TESTS:
105         conf.recurse('test')
106
107     # libxml++ 2.39.1 and later must be built with -std=c++11
108     libxmlpp_version = conf.cmd_and_log(['pkg-config', '--modversion', 'libxml++-2.6'], output=Context.STDOUT, quiet=Context.BOTH)
109     s = libxmlpp_version.split('.')
110     v = (int(s[0]) << 16) | (int(s[1]) << 8) | int(s[2])
111     if v >= 0x022701:
112         conf.env.append_value('CXXFLAGS', '-std=c++11')
113
114 def build(bld):
115     create_version_cc(bld, VERSION)
116
117     if bld.env.TARGET_WINDOWS:
118         boost_lib_suffix = '-mt'
119     else:
120         boost_lib_suffix = ''
121
122     bld(source='libsub%s.pc.in' % bld.env.API_VERSION,
123         version=VERSION,
124         includedir='%s/include/libsub%s' % (bld.env.PREFIX, bld.env.API_VERSION),
125         libs="-L${libdir} -lsub%s -lboost_system%s" % (bld.env.API_VERSION, boost_lib_suffix),
126         install_path='${LIBDIR}/pkgconfig')
127
128     bld.recurse('src')
129     if not bld.env.DISABLE_TESTS:
130         bld.recurse('test')
131     bld.recurse('tools')
132
133     bld.add_post_fun(post)
134
135 def dist(ctx):
136     ctx.excl = 'TODO core *~ .git build .waf* .lock* doc/*~ src/*~ test/ref/*~ __pycache__ GPATH GRTAGS GSYMS GTAGS'
137
138 def create_version_cc(bld, version):
139     if os.path.exists('.git'):
140         cmd = "LANG= git log --abbrev HEAD^..HEAD ."
141         output = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0].splitlines()
142         o = output[0].decode('utf-8')
143         commit = o.replace ("commit ", "")[0:10]
144     else:
145         commit = "release"
146
147     try:
148         text =  '#include "version.h"\n'
149         text += 'char const * sub::git_commit = \"%s\";\n' % commit
150         text += 'char const * sub::version = \"%s\";\n' % version
151         if bld.env.ENABLE_DEBUG:
152             debug_string = 'true'
153         else:
154             debug_string = 'false'
155         text += 'bool const built_with_debug = %s;\n' % debug_string
156         print('Writing version information to src/version.cc')
157         o = open('src/version.cc', 'w')
158         o.write(text)
159         o.close()
160     except IOError:
161         print('Could not open src/version.cc for writing\n')
162         sys.exit(-1)
163
164 def post(ctx):
165     if ctx.cmd == 'install':
166         ctx.exec_command('/sbin/ldconfig')
167
168 def tags(bld):
169     os.system('etags src/*.cc src/*.h')