From b70f85bce27480c6c616a46807b3da9d2732d851 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 7 Feb 2014 15:59:44 +0000 Subject: [PATCH 1/1] Add basic stuff to build RPMs for Centos. Suggested-by: Manuel Weber --- ChangeLog | 4 + cscript | 110 ++++--- platform/linux/dcpomatic.desktop.in | 2 +- platform/linux/dcpomatic.spec.in | 69 +++++ platform/linux/dcpomatic_batch.desktop.in | 2 +- platform/linux/dcpomatic_server.desktop.in | 2 +- platform/linux/wscript | 14 +- src/lib/wscript | 4 +- src/tools/wscript | 8 +- src/wx/wscript | 8 +- test/wscript | 2 +- wscript | 334 +++++++++++++-------- 12 files changed, 381 insertions(+), 178 deletions(-) create mode 100644 platform/linux/dcpomatic.spec.in diff --git a/ChangeLog b/ChangeLog index 399b720ee..d04c76fb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2014-02-07 Carl Hetherington + + * Add basic stuff to build RPMs for Centos. + 2014-02-05 Carl Hetherington * Version 1.64.2 released. diff --git a/cscript b/cscript index 4103f9366..9595cb162 100644 --- a/cscript +++ b/cscript @@ -137,52 +137,88 @@ def build(target, options): if target.platform == 'windows': cmd += ' --target-windows' elif target.platform == 'linux': - cmd += ' --static' - target.command(cmd) + if target.distro == 'debian' or target.distro == 'ubuntu': + cmd += ' --target-debian' + elif target.distro == 'centos': + cmd += ' --target-centos' + target.command(cmd) target.command('./waf') if target.platform == 'linux' or target.platform == 'osx': target.command('./waf install') +def package_windows(target): + shutil.copyfile('build/platform/windows/installer.%s.nsi' % target.bits, 'build/platform/windows/installer2.%s.nsi' % target.bits) + target.command('sed -i "s~%%resources%%~%s/platform/windows~g" build/platform/windows/installer2.%s.nsi' % (os.getcwd(), target.bits)) + target.command('sed -i "s~%%static_deps%%~%s~g" build/platform/windows/installer2.%s.nsi' % (target.windows_prefix, target.bits)) + target.command('sed -i "s~%%cdist_deps%%~%s~g" build/platform/windows/installer2.%s.nsi' % (target.work_dir_cscript(), target.bits)) + target.command('sed -i "s~%%binaries%%~%s/build~g" build/platform/windows/installer2.%s.nsi' % (os.getcwd(), target.bits)) + target.command('sed -i "s~%%bits%%~32~g" build/platform/windows/installer2.%s.nsi' % target.bits) + target.command('makensis build/platform/windows/installer2.%s.nsi' % target.bits) + return os.path.abspath(glob.glob('build/platform/windows/*%s*.exe' % target.bits)[0]) + +def package_debian(target, cpu): + make_control(target.version, target.bits, 'debian/control') + target.command('./waf dist') + f = open('debian/files', 'w') + print >>f,'dcpomatic_%s-1_%s.deb video extra' % (version, cpu) + shutil.rmtree('build/deb', ignore_errors=True) + + os.makedirs('build/deb') + os.chdir('build/deb') + shutil.move('../../dcpomatic-%s.tar.bz2' % version, 'dcpomatic_%s.orig.tar.bz2' % version) + target.command('tar xjf dcpomatic_%s.orig.tar.bz2' % version) + os.chdir('dcpomatic-%s' % version) + target.command('dch -b -v %s-1 "New upstream release."' % version) + target.set('CDIST_LINKFLAGS', target.get('LINKFLAGS')) + target.set('CDIST_CXXFLAGS', target.get('CXXFLAGS')) + target.set('CDIST_PKG_CONFIG_PATH', target.get('PKG_CONFIG_PATH')) + target.command('dpkg-buildpackage') + + debs = [] + for p in glob.glob('../*.deb'): + debs.append(os.path.abspath(p)) + + return debs + +def package_centos(target, cpu, version): + os.makedirs('%s/rpmbuild/BUILD' % target.work_dir_cdist()) + os.makedirs('%s/rpmbuild/RPMS' % target.work_dir_cdist()) + os.makedirs('%s/rpmbuild/SOURCES' % target.work_dir_cdist()) + os.makedirs('%s/rpmbuild/SPECS' % target.work_dir_cdist()) + os.makedirs('%s/rpmbuild/SRPMS' % target.work_dir_cdist()) + + f = open('%s/.rpmmacros' % target.dir_in_chroot, 'w') + print >>f,"%%_topdir %srpmbuild" % target.dir_in_chroot + f.close() + + target.command('./waf dist') + shutil.copyfile( + "%s/src/dcpomatic/dcpomatic-%s.tar.bz2" % (target.work_dir_cdist(), version), + "%s/rpmbuild/SOURCES/dcpomatic-%s.tar.bz2" % (target.work_dir_cdist(), version) + ) + + target.command('rpmbuild -bb build/platform/linux/dcpomatic.spec') + rpms = [] + for p in glob.glob('%s/rpmbuild/RPMS/x86_64/*.rpm' % target.work_dir_cdist()): + rpms.append(os.path.abspath(p)) + + return rpms + def package(target, version): + if target.bits == 32: + cpu = 'i386' + else: + cpu = 'amd64' + if target.platform == 'windows': - shutil.copyfile('build/platform/windows/installer.%s.nsi' % target.bits, 'build/platform/windows/installer2.%s.nsi' % target.bits) - target.command('sed -i "s~%%resources%%~%s/platform/windows~g" build/platform/windows/installer2.%s.nsi' % (os.getcwd(), target.bits)) - target.command('sed -i "s~%%static_deps%%~%s~g" build/platform/windows/installer2.%s.nsi' % (target.windows_prefix, target.bits)) - target.command('sed -i "s~%%cdist_deps%%~%s~g" build/platform/windows/installer2.%s.nsi' % (target.work_dir_cscript(), target.bits)) - target.command('sed -i "s~%%binaries%%~%s/build~g" build/platform/windows/installer2.%s.nsi' % (os.getcwd(), target.bits)) - target.command('sed -i "s~%%bits%%~32~g" build/platform/windows/installer2.%s.nsi' % target.bits) - target.command('makensis build/platform/windows/installer2.%s.nsi' % target.bits) - return os.path.abspath(glob.glob('build/platform/windows/*%s*.exe' % target.bits)[0]) + return package_windows(target) elif target.platform == 'linux': - if target.bits == 32: - cpu = 'i386' - else: - cpu = 'amd64' - - make_control(target.version, target.bits, 'debian/control', target.debug) - target.command('./waf dist') - f = open('debian/files', 'w') - print >>f,'dcpomatic_%s-1_%s.deb video extra' % (version, cpu) - shutil.rmtree('build/deb', ignore_errors=True) - - os.makedirs('build/deb') - os.chdir('build/deb') - shutil.move('../../dcpomatic-%s.tar.bz2' % version, 'dcpomatic_%s.orig.tar.bz2' % version) - target.command('tar xjf dcpomatic_%s.orig.tar.bz2' % version) - os.chdir('dcpomatic-%s' % version) - target.command('dch -b -v %s-1 "New upstream release."' % version) - target.set('CDIST_LINKFLAGS', target.get('LINKFLAGS')) - target.set('CDIST_CXXFLAGS', target.get('CXXFLAGS')) - target.set('CDIST_PKG_CONFIG_PATH', target.get('PKG_CONFIG_PATH')) - target.command('dpkg-buildpackage') - - debs = [] - for p in glob.glob('../*.deb'): - debs.append(os.path.abspath(p)) - - return debs + if target.distro == 'debian' or target.distro == 'ubuntu': + return package_debian(target, cpu) + elif target.distro == 'centos': + return package_centos(target, cpu, version) elif target.platform == 'osx': target.command('bash platform/osx/make_dmg.sh %s' % target.work_dir_cscript()) return os.path.abspath(glob.glob('build/platform/osx/DCP-o-matic*.dmg')[0]) diff --git a/platform/linux/dcpomatic.desktop.in b/platform/linux/dcpomatic.desktop.in index aabd992f5..76e629404 100644 --- a/platform/linux/dcpomatic.desktop.in +++ b/platform/linux/dcpomatic.desktop.in @@ -3,7 +3,7 @@ Encoding=UTF-8 Version=1.0 Type=Application Terminal=false -Exec=@PREFIX@/bin/dcpomatic +Exec=@INSTALL_PREFIX@/bin/dcpomatic Name=DCP-o-matic Icon=dcpomatic Comment=DCP generator diff --git a/platform/linux/dcpomatic.spec.in b/platform/linux/dcpomatic.spec.in new file mode 100644 index 000000000..f373ebd67 --- /dev/null +++ b/platform/linux/dcpomatic.spec.in @@ -0,0 +1,69 @@ +Summary:A program that generates Digital Cinema Packages (DCPs) from video and audio files +Name:dcpomatic +Version:@version@ +Release:1%{?dist} +License:GPL +Group:Applications/Multimedia +URL:http://dcpomatic.com/ + +%description +DCP-o-matic generates Digital Cinema Packages (DCPs) from video and audio +files (such as those from DVDs or Blu-Rays) for presentation on DCI-compliant +digital projectors. + +%files +%{_bindir}/dcpomatic +%{_bindir}/dcpomatic_batch +%{_bindir}/dcpomatic_cli +%{_bindir}/dcpomatic_create +%{_bindir}/dcpomatic_kdm +%{_bindir}/dcpomatic_server +%{_bindir}/dcpomatic_server_cli +%{_datadir}/applications/dcpomatic.desktop +%{_datadir}/applications/dcpomatic_batch.desktop +%{_datadir}/applications/dcpomatic_server.desktop +%{_datadir}/dcpomatic/taskbar_icon.png +%{_datadir}/icons/hicolor/128x128/apps/dcpomatic.png +%{_datadir}/icons/hicolor/22x22/apps/dcpomatic.png +%{_datadir}/icons/hicolor/32x32/apps/dcpomatic.png +%{_datadir}/icons/hicolor/48x48/apps/dcpomatic.png +%{_datadir}/icons/hicolor/64x64/apps/dcpomatic.png +%{_datadir}/locale/de_DE/LC_MESSAGES/dcpomatic.mo +%{_datadir}/locale/de_DE/LC_MESSAGES/libdcpomatic-wx.mo +%{_datadir}/locale/de_DE/LC_MESSAGES/libdcpomatic.mo +%{_datadir}/locale/es_ES/LC_MESSAGES/dcpomatic.mo +%{_datadir}/locale/es_ES/LC_MESSAGES/libdcpomatic-wx.mo +%{_datadir}/locale/es_ES/LC_MESSAGES/libdcpomatic.mo +%{_datadir}/locale/fr_FR/LC_MESSAGES/dcpomatic.mo +%{_datadir}/locale/fr_FR/LC_MESSAGES/libdcpomatic-wx.mo +%{_datadir}/locale/fr_FR/LC_MESSAGES/libdcpomatic.mo +%{_datadir}/locale/it_IT/LC_MESSAGES/dcpomatic.mo +%{_datadir}/locale/it_IT/LC_MESSAGES/libdcpomatic-wx.mo +%{_datadir}/locale/it_IT/LC_MESSAGES/libdcpomatic.mo +%{_datadir}/locale/sv_SE/LC_MESSAGES/dcpomatic.mo +%{_datadir}/locale/sv_SE/LC_MESSAGES/libdcpomatic-wx.mo +%{_datadir}/locale/sv_SE/LC_MESSAGES/libdcpomatic.mo + +%prep +rm -rf $RPM_BUILD_DIR/dcpomatic-@version@ +tar xjf $RPM_SOURCE_DIR/dcpomatic-@version@.tar.bz2 +%build +cd dcpomatic-@version@ +export PKG_CONFIG_PATH=/home/carl/lib/pkgconfig:/usr/local/lib/pkgconfig +CXXFLAGS="-I/home/carl/include" LDFLAGS="-L/home/carl/lib" ./waf configure --prefix=%{buildroot}/usr --install-prefix=/usr --target-centos +./waf +%install +cd dcpomatic-@version@ +./waf install + +%post +/bin/touch --no-create %{_datadir}/icons/hicolor &>/dev/null || : + +%postun +if [ $1 -eq 0 ] ; then + /bin/touch --no-create %{_datadir}/icons/hicolor &>/dev/null + /usr/bin/gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : +fi + +%posttrans +/usr/bin/gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : \ No newline at end of file diff --git a/platform/linux/dcpomatic_batch.desktop.in b/platform/linux/dcpomatic_batch.desktop.in index bab136e8a..ec32a7353 100644 --- a/platform/linux/dcpomatic_batch.desktop.in +++ b/platform/linux/dcpomatic_batch.desktop.in @@ -3,7 +3,7 @@ Encoding=UTF-8 Version=1.0 Type=Application Terminal=false -Exec=@PREFIX@/bin/dcpomatic_batch +Exec=@INSTALL_PREFIX@/bin/dcpomatic_batch Name=DCP-o-matic Batch Converter Icon=dcpomatic Comment=DCP generator diff --git a/platform/linux/dcpomatic_server.desktop.in b/platform/linux/dcpomatic_server.desktop.in index 7b8215e8f..c51c2778a 100644 --- a/platform/linux/dcpomatic_server.desktop.in +++ b/platform/linux/dcpomatic_server.desktop.in @@ -3,7 +3,7 @@ Encoding=UTF-8 Version=1.0 Type=Application Terminal=false -Exec=@PREFIX@/bin/dcpomatic_server +Exec=@INSTALL_PREFIX@/bin/dcpomatic_server Name=DCP-o-matic Encode Server Icon=dcpomatic Comment=DCP generator diff --git a/platform/linux/wscript b/platform/linux/wscript index 53a6efeac..fe6f4e2db 100644 --- a/platform/linux/wscript +++ b/platform/linux/wscript @@ -1,19 +1,25 @@ def build(bld): - d = { 'PREFIX' : '${PREFIX' } + d = { 'INSTALL_PREFIX' : bld.env.INSTALL_PREFIX } + d = { 'VERSION' : bld.env.VERSION } - obj = bld(features = 'subst') + obj = bld(features='subst') obj.source = 'dcpomatic.desktop.in' obj.target = 'dcpomatic.desktop' obj.dict = d - obj = bld(features = 'subst') + obj = bld(features='subst') obj.source = 'dcpomatic_batch.desktop.in' obj.target = 'dcpomatic_batch.desktop' obj.dict = d - obj = bld(features = 'subst') + obj = bld(features='subst') obj.source = 'dcpomatic_server.desktop.in' obj.target = 'dcpomatic_server.desktop' obj.dict = d + obj = bld(features='subst') + obj.source = 'dcpomatic.spec.in' + obj.target = 'dcpomatic.spec' + obj.dict = d + bld.install_files('${PREFIX}/share/applications', ['dcpomatic.desktop', 'dcpomatic_batch.desktop', 'dcpomatic_server.desktop']) diff --git a/src/lib/wscript b/src/lib/wscript index 81a55a160..4921afaee 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -65,7 +65,7 @@ sources = """ """ def build(bld): - if bld.env.STATIC: + if bld.env.BUILD_STATIC: obj = bld(features = 'cxx cxxstlib') else: obj = bld(features = 'cxx cxxshlib') @@ -84,7 +84,7 @@ def build(bld): if bld.env.TARGET_WINDOWS: obj.uselib += ' WINSOCK2 BFD DBGHELP IBERTY SHLWAPI MSWSOCK BOOST_LOCALE' obj.source += ' stack.cpp' - if bld.env.STATIC: + if bld.env.BUILD_STATIC: obj.uselib += ' XML++' obj.target = 'dcpomatic' diff --git a/src/tools/wscript b/src/tools/wscript index 0fd336676..131d02b81 100644 --- a/src/tools/wscript +++ b/src/tools/wscript @@ -11,17 +11,19 @@ def configure(conf): def build(bld): for t in ['dcpomatic_cli', 'dcpomatic_server_cli', 'server_test', 'dcpomatic_kdm', 'dcpomatic_create']: obj = bld(features = 'cxx cxxprogram') - obj.uselib = 'BOOST_THREAD OPENJPEG DCP CXML AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC WXWIDGETS QUICKMAIL' + obj.uselib = 'BOOST_THREAD BOOST_DATETIME OPENJPEG DCP CXML AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC WXWIDGETS QUICKMAIL' obj.includes = ['..'] obj.use = ['libdcpomatic'] obj.source = '%s.cc' % t obj.target = t + if t == 'server_test': + obj.install_path = None if not bld.env.DISABLE_GUI: for t in ['dcpomatic', 'dcpomatic_batch', 'dcpomatic_server']: obj = bld(features = 'cxx cxxprogram') - obj.uselib = 'DCP OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC CXML WXWIDGETS QUICKMAIL' - if bld.env.STATIC: + obj.uselib = 'BOOST_THREAD BOOST_DATETIME OPENJPEG DCP CXML AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC CXML WXWIDGETS QUICKMAIL' + if bld.env.BUILD_STATIC: obj.uselib += ' GTK' obj.includes = ['..'] obj.use = ['libdcpomatic', 'libdcpomatic-wx'] diff --git a/src/wx/wscript b/src/wx/wscript index 9de32d39e..1ffaa6097 100644 --- a/src/wx/wscript +++ b/src/wx/wscript @@ -47,13 +47,13 @@ sources = """ def configure(conf): args = '--cppflags --cxxflags' - if not conf.env.STATIC: + if not conf.env.BUILD_STATIC: args += ' --libs std,richtext' conf.check_cfg(msg='Checking for wxWidgets', package='', path=conf.options.wx_config, args=args, uselib_store='WXWIDGETS', mandatory=True) - if conf.env.STATIC: + if conf.env.BUILD_STATIC: # wx-config returns its static libraries as full paths, without -l prefixes, which confuses # check_cfg(), so just hard-code it all. conf.env.STLIB_WXWIDGETS = ['wx_gtk2u_richtext-3.0', 'wx_gtk2u_xrc-3.0', 'wx_gtk2u_qa-3.0', 'wx_baseu_net-3.0', 'wx_gtk2u_html-3.0', @@ -67,14 +67,14 @@ def configure(conf): conf.fatal('wxwidgets version 3.0.0 is required; %s found' % wx_version) def build(bld): - if bld.env.STATIC: + if bld.env.BUILD_STATIC: obj = bld(features = 'cxx cxxstlib') else: obj = bld(features = 'cxx cxxshlib') obj.name = 'libdcpomatic-wx' obj.export_includes = ['..'] - obj.uselib = 'WXWIDGETS' + obj.uselib = 'WXWIDGETS DCP' if bld.env.TARGET_LINUX: obj.uselib += ' GTK' obj.use = 'libdcpomatic' diff --git a/test/wscript b/test/wscript index c07f2cc33..676f47104 100644 --- a/test/wscript +++ b/test/wscript @@ -12,7 +12,7 @@ def configure(conf): def build(bld): obj = bld(features = 'cxx cxxprogram') obj.name = 'unit-tests' - obj.uselib = 'BOOST_TEST DCP OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC CXML' + obj.uselib = 'BOOST_TEST BOOST_THREAD DCP OPENJPEG AVFORMAT AVFILTER AVCODEC AVUTIL SWSCALE POSTPROC CXML' obj.use = 'libdcpomatic' obj.source = """ 4k_test.cc diff --git a/wscript b/wscript index 076948395..95fb7f92c 100644 --- a/wscript +++ b/wscript @@ -11,29 +11,166 @@ def options(opt): opt.add_option('--enable-debug', action='store_true', default=False, help='build with debugging information and without optimisation') opt.add_option('--disable-gui', action='store_true', default=False, help='disable building of GUI tools') - opt.add_option('--target-windows', action='store_true', default=False, help='set up to do a cross-compile to Windows') - opt.add_option('--static', action='store_true', default=False, help='build statically, and link statically to libdcp and FFmpeg') + opt.add_option('--target-windows', action='store_true', default=False, help='set up to do a cross-compile to make a Windows package') + opt.add_option('--target-debian', action='store_true', default=False, help='set up to compile for a Debian/Ubuntu package') + opt.add_option('--target-centos', action='store_true', default=False, help='set up to compile for a Centos package') opt.add_option('--magickpp-config', action='store', default='Magick++-config', help='path to Magick++-config') opt.add_option('--wx-config', action='store', default='wx-config', help='path to wx-config') opt.add_option('--address-sanitizer', action='store_true', default=False, help='build with address sanitizer') + opt.add_option('--install-prefix', default=None, help='prefix of where DCP-o-matic will be installed') + +def static_ffmpeg(conf): + conf.check_cfg(package='libavformat', args='--cflags', uselib_store='AVFORMAT', mandatory=True) + conf.env.STLIB_AVFORMAT = ['avformat'] + conf.check_cfg(package='libavfilter', args='--cflags', uselib_store='AVFILTER', mandatory=True) + conf.env.STLIB_AVFILTER = ['avfilter', 'swresample'] + conf.check_cfg(package='libavcodec', args='--cflags', uselib_store='AVCODEC', mandatory=True) + conf.env.STLIB_AVCODEC = ['avcodec'] + conf.env.LIB_AVCODEC = ['z'] + conf.check_cfg(package='libavutil', args='--cflags', uselib_store='AVUTIL', mandatory=True) + conf.env.STLIB_AVUTIL = ['avutil'] + conf.check_cfg(package='libswscale', args='--cflags', uselib_store='SWSCALE', mandatory=True) + conf.env.STLIB_SWSCALE = ['swscale'] + conf.check_cfg(package='libswresample', args='--cflags', uselib_store='SWRESAMPLE', mandatory=True) + conf.env.STLIB_SWRESAMPLE = ['swresample'] + conf.check_cfg(package='libpostproc', args='--cflags', uselib_store='POSTPROC', mandatory=True) + conf.env.STLIB_POSTPROC = ['postproc'] + +def dynamic_ffmpeg(conf): + conf.check_cfg(package='libavformat', args='--cflags --libs', uselib_store='AVFORMAT', mandatory=True) + conf.check_cfg(package='libavfilter', args='--cflags --libs', uselib_store='AVFILTER', mandatory=True) + conf.check_cfg(package='libavcodec', args='--cflags --libs', uselib_store='AVCODEC', mandatory=True) + conf.check_cfg(package='libavutil', args='--cflags --libs', uselib_store='AVUTIL', mandatory=True) + conf.check_cfg(package='libswscale', args='--cflags --libs', uselib_store='SWSCALE', mandatory=True) + conf.check_cfg(package='libswresample', args='--cflags --libs', uselib_store='SWRESAMPLE', mandatory=True) + conf.check_cfg(package='libpostproc', args='--cflags --libs', uselib_store='POSTPROC', mandatory=True) + +def static_openjpeg(conf): + conf.check_cfg(package='libopenjpeg', args='--cflags', atleast_version='1.5.0', uselib_store='OPENJPEG', mandatory=True) + conf.check_cfg(package='libopenjpeg', args='--cflags', max_version='1.5.1', mandatory=True) + conf.env.STLIB_OPENJPEG = ['openjpeg'] + +def static_dcp(conf, static_boost, static_xmlpp, static_xmlsec, static_ssh): + conf.check_cfg(package='libdcp', atleast_version='0.92', args='--cflags', uselib_store='DCP', mandatory=True) + conf.env.DEFINES_DCP = [f.replace('\\', '') for f in conf.env.DEFINES_DCP] + conf.env.STLIB_DCP = ['dcp', 'asdcp-libdcp', 'kumu-libdcp'] + conf.env.LIB_DCP = ['glibmm-2.4', 'ssl', 'crypto', 'bz2', 'xslt'] + + if static_boost: + conf.env.STLIB_DCP.append('boost_system') -def pkg_config_args(conf): - if conf.env.STATIC: - return '--cflags' + if static_xmlpp: + conf.env.STLIB_DCP.append('xml++-2.6') else: - return '--cflags --libs' + conf.env.LIB_DCP.append('xml++-2.6') + + if static_xmlsec: + conf.env.STLIB_DCP.append('xmlsec1-openssl') + conf.env.STLIB_DCP.append('xmlsec1') + else: + conf.env.LIB_DCP.append('xmlsec1-openssl') + conf.env.LIB_DCP.append('xmlsec1') + + if static_ssh: + conf.env.STLIB_DCP.append('ssh') + else: + conf.env.LIB_DCP.append('ssh') + + + +def dynamic_dcp(conf): + conf.check_cfg(package='libdcp', atleast_version='0.92', args='--cflags --libs', uselib_store='DCP', mandatory=True) + conf.env.DEFINES_DCP = [f.replace('\\', '') for f in conf.env.DEFINES_DCP] + +def dynamic_ssh(conf): + conf.check_cc(fragment=""" + #include \n + int main () {\n + ssh_session s = ssh_new ();\n + return 0;\n + } + """, msg='Checking for library libssh', mandatory=True, lib='ssh', uselib_store='SSH') + +def dynamic_boost(conf, lib_suffix, thread): + conf.check_cxx(fragment=""" + #include \n + #if BOOST_VERSION < 104500\n + #error boost too old\n + #endif\n + int main(void) { return 0; }\n + """, + mandatory=True, + msg='Checking for boost library >= 1.45', + okmsg='yes', + errmsg='too old\nPlease install boost version 1.45 or higher.') + + conf.check_cxx(fragment=""" + #include \n + int main() { boost::thread t (); }\n + """, msg='Checking for boost threading library', + libpath='/usr/local/lib', + lib=[thread, 'boost_system%s' % lib_suffix], + uselib_store='BOOST_THREAD') + + conf.check_cxx(fragment=""" + #include \n + int main() { boost::filesystem::copy_file ("a", "b"); }\n + """, msg='Checking for boost filesystem library', + libpath='/usr/local/lib', + lib=['boost_filesystem%s' % lib_suffix, 'boost_system%s' % lib_suffix], + uselib_store='BOOST_FILESYSTEM') + + conf.check_cxx(fragment=""" + #include \n + int main() { boost::gregorian::day_clock::local_day(); }\n + """, msg='Checking for boost datetime library', + libpath='/usr/local/lib', + lib=['boost_date_time%s' % lib_suffix, 'boost_system%s' % lib_suffix], + uselib_store='BOOST_DATETIME') + + conf.check_cxx(fragment=""" + #include \n + int main() { boost::signals2::signal x; }\n + """, + msg='Checking for boost signals2 library', + uselib_store='BOOST_SIGNALS2') + +def static_boost(conf, lib_suffix): + conf.env.STLIB_BOOST_THREAD = ['boost_thread'] + conf.env.STLIB_BOOST_FILESYSTEM = ['boost_filesystem%s' % lib_suffix] + conf.env.STLIB_BOOST_DATETIME = ['boost_date_time%s' % lib_suffix, 'boost_system%s' % lib_suffix] + conf.env.STLIB_BOOST_SIGNALS2 = ['boost_signals2'] + +def dynamic_quickmail(conf): + conf.check_cxx(fragment=""" + #include + int main(void) { quickmail_initialize (); } + """, + mandatory=True, + msg='Checking for libquickmail', + libpath='/usr/local/lib', + lib=['quickmail', 'curl'], + uselib_store='QUICKMAIL') def configure(conf): conf.load('compiler_cxx') if conf.options.target_windows: conf.load('winres') + # conf.options -> conf.env conf.env.TARGET_WINDOWS = conf.options.target_windows conf.env.DISABLE_GUI = conf.options.disable_gui - conf.env.STATIC = conf.options.static + conf.env.TARGET_DEBIAN = conf.options.target_debian + conf.env.TARGET_CENTOS = conf.options.target_centos conf.env.VERSION = VERSION conf.env.TARGET_OSX = sys.platform == 'darwin' conf.env.TARGET_LINUX = not conf.env.TARGET_WINDOWS and not conf.env.TARGET_OSX + # true if we should build dcpomatic/libdcpomatic/libdcpomatic-wx statically + conf.env.BUILD_STATIC = conf.options.target_debian or conf.options.target_centos + if conf.options.install_prefix is None: + conf.env.INSTALL_PREFIX = conf.env.PREFIX + else: + conf.env.INSTALL_PREFIX = conf.options.install_prefix # Common CXXFLAGS conf.env.append_value('CXXFLAGS', ['-D__STDC_CONSTANT_MACROS', '-D__STDC_LIMIT_MACROS', '-msse', '-mfpmath=sse', '-ffast-math', '-fno-strict-aliasing', @@ -48,7 +185,11 @@ def configure(conf): conf.env.append_value('CXXFLAGS', ['-fsanitize=address', '-fno-omit-frame-pointer']) conf.env.append_value('LINKFLAGS', ['-fsanitize=address']) - # Windows-specific + # + # Platform-specific CFLAGS hacks and other tinkering + # + + # Windows if conf.env.TARGET_WINDOWS: conf.env.append_value('CXXFLAGS', ['-DDCPOMATIC_WINDOWS', '-DWIN32_LEAN_AND_MEAN', '-DBOOST_USE_WINDOWS_H', '-DUNICODE', '-DBOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN']) wxrc = os.popen('wx-config --rescomp').read().split()[1:] @@ -65,7 +206,7 @@ def configure(conf): boost_lib_suffix = '-mt' boost_thread = 'boost_thread_win32-mt' - # POSIX-specific + # POSIX if conf.env.TARGET_LINUX or conf.env.TARGET_OSX: conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_POSIX') conf.env.append_value('CXXFLAGS', '-DPOSIX_LOCALE_PREFIX="%s/share/locale"' % conf.env['PREFIX']) @@ -74,125 +215,55 @@ def configure(conf): boost_thread = 'boost_thread' conf.env.append_value('LINKFLAGS', '-pthread') - # Linux-specific + # Linux if conf.env.TARGET_LINUX: conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_LINUX') + + if conf.env.TARGET_DEBIAN: # libxml2 seems to be linked against this on Ubuntu but it doesn't mention it in its .pc file conf.check_cfg(package='liblzma', args='--cflags --libs', uselib_store='LZMA', mandatory=True) - if not conf.env.DISABLE_GUI: - if conf.env.STATIC: - conf.check_cfg(package='gtk+-2.0', args='--cflags --libs', uselib_store='GTK', mandatory=True) - else: - # On Linux we need to be able to include to check GTK's version - conf.check_cfg(package='gtk+-2.0', args='--cflags', uselib_store='GTK', mandatory=True) - - # OSX-specific + + if not conf.env.DISABLE_GUI: + if conf.env.TARGET_DEBIAN or conf.env.TARGET_CENTOS: + conf.check_cfg(package='gtk+-2.0', args='--cflags --libs', uselib_store='GTK', mandatory=True) + + # OSX if conf.env.TARGET_OSX: conf.env.append_value('CXXFLAGS', '-DDCPOMATIC_OSX') conf.env.append_value('LINKFLAGS', '-headerpad_max_install_names') - # Dependencies which are dynamically linked everywhere except --static - # Get libs only when we are dynamically linking - conf.check_cfg(package='libdcp', atleast_version='0.92', args=pkg_config_args(conf), uselib_store='DCP', mandatory=True) - # Remove erroneous escaping of quotes from xmlsec1 defines - conf.env.DEFINES_DCP = [f.replace('\\', '') for f in conf.env.DEFINES_DCP] - conf.check_cfg(package='libcxml', atleast_version='0.08', args=pkg_config_args(conf), uselib_store='CXML', mandatory=True) - conf.check_cfg(package='libavformat', args=pkg_config_args(conf), uselib_store='AVFORMAT', mandatory=True) - conf.check_cfg(package='libavfilter', args=pkg_config_args(conf), uselib_store='AVFILTER', mandatory=True) - conf.check_cfg(package='libavcodec', args=pkg_config_args(conf), uselib_store='AVCODEC', mandatory=True) - conf.check_cfg(package='libavutil', args=pkg_config_args(conf), uselib_store='AVUTIL', mandatory=True) - conf.check_cfg(package='libswscale', args=pkg_config_args(conf), uselib_store='SWSCALE', mandatory=True) - conf.check_cfg(package='libswresample', args=pkg_config_args(conf), uselib_store='SWRESAMPLE', mandatory=True) - conf.check_cfg(package='libpostproc', args=pkg_config_args(conf), uselib_store='POSTPROC', mandatory=True) - conf.check_cfg(package='libopenjpeg', args=pkg_config_args(conf), atleast_version='1.5.0', uselib_store='OPENJPEG', mandatory=True) - conf.check_cfg(package='libopenjpeg', args=pkg_config_args(conf), max_version='1.5.1', mandatory=True) - - if conf.env.STATIC: - # This is hackio grotesquio for static builds (ie for .deb packages). We need to link some things - # statically and some dynamically, or things get horribly confused and the dynamic linker (I think) - # crashes. These calls do what the check_cfg calls would have done, but specify the - # different bits as static or dynamic as required. It'll break if you look at it funny, but - # I think anyone else who builds would do so dynamically. - conf.env.STLIB_CXML = ['cxml'] - conf.env.STLIB_DCP = ['dcp', 'asdcp-libdcp', 'kumu-libdcp'] - conf.env.LIB_DCP = ['glibmm-2.4', 'xml++-2.6', 'ssl', 'crypto', 'bz2', 'xmlsec1', 'xmlsec1-openssl', 'xslt'] - conf.env.STLIB_CXML = ['cxml'] - conf.env.STLIB_AVFORMAT = ['avformat'] - conf.env.STLIB_AVFILTER = ['avfilter', 'swresample'] - conf.env.STLIB_AVCODEC = ['avcodec'] - conf.env.LIB_AVCODEC = ['z'] - conf.env.STLIB_AVUTIL = ['avutil'] - conf.env.STLIB_SWSCALE = ['swscale'] - conf.env.STLIB_POSTPROC = ['postproc'] - conf.env.STLIB_SWRESAMPLE = ['swresample'] - conf.env.STLIB_OPENJPEG = ['openjpeg'] - conf.env.STLIB_QUICKMAIL = ['quickmail'] - else: - conf.check_cxx(fragment=""" - #include - int main(void) { quickmail_initialize (); } - """, - mandatory=True, - msg='Checking for libquickmail', - libpath='/usr/local/lib', - lib=['quickmail', 'curl'], - uselib_store='QUICKMAIL') - - # Dependencies which are always dynamically linked - conf.check_cfg(package='sndfile', args='--cflags --libs', uselib_store='SNDFILE', mandatory=True) - conf.check_cfg(package='glib-2.0', args='--cflags --libs', uselib_store='GLIB', mandatory=True) - conf.check_cfg(package= '', path=conf.options.magickpp_config, args='--cppflags --cxxflags --libs', uselib_store='MAGICK', mandatory=True) - conf.check_cfg(package='libxml++-2.6', args='--cflags --libs', uselib_store='XML++', mandatory=True) - conf.check_cfg(package='libcurl', args='--cflags --libs', uselib_store='CURL', mandatory=True) - conf.check_cfg(package='libzip', args='--cflags --libs', uselib_store='ZIP', mandatory=True) - - conf.check_cxx(fragment=""" - #include \n - #if BOOST_VERSION < 104500\n - #error boost too old\n - #endif\n - int main(void) { return 0; }\n - """, - mandatory=True, - msg='Checking for boost library >= 1.45', - okmsg='yes', - errmsg='too old\nPlease install boost version 1.45 or higher.') - - conf.check_cc(fragment=""" - #include \n - int main () {\n - ssh_session s = ssh_new ();\n - return 0;\n - } - """, msg='Checking for library libssh', mandatory=True, lib='ssh', uselib_store='SSH') - - conf.check_cxx(fragment=""" - #include \n - int main() { boost::thread t (); }\n - """, msg='Checking for boost threading library', - libpath='/usr/local/lib', - lib=[boost_thread, 'boost_system%s' % boost_lib_suffix], - uselib_store='BOOST_THREAD') + # + # Dependencies. + # There's probably a neater way of expressing these, but I've gone for brute force for now. + # + + if conf.env.TARGET_DEBIAN: + conf.check_cfg(package='libcxml', atleast_version='0.08', args='--cflags', uselib_store='CXML', mandatory=True) + conf.env.STLIB_CXML = ['cxml'] + conf.check_cfg(package='libxml++-2.6', args='--cflags --libs', uselib_store='XML++', mandatory=True) + conf.check_cfg(package='libcurl', args='--cflags --libs', uselib_store='CURL', mandatory=True) + conf.env.STLIB_QUICKMAIL = ['quickmail'] + static_ffmpeg(conf) + static_openjpeg(conf) + static_dcp(conf, False, False, False, False) + dynamic_boost(conf, boost_lib_suffix, boost_thread) + + if conf.env.TARGET_CENTOS: + conf.check_cfg(package='libcxml', atleast_version='0.08', args='--cflags --libs-only-L', uselib_store='CXML', mandatory=True) + conf.env.STLIB_CXML = ['cxml', 'boost_filesystem'] + conf.check_cfg(package='libcurl', args='--cflags --libs-only-L', uselib_store='CURL', mandatory=True) + conf.env.STLIB_CURL = ['curl'] + conf.env.LIB_CURL = ['ssh2', 'idn'] + conf.env.STLIB_QUICKMAIL = ['quickmail', 'curl'] + conf.env.LIB_QUICKMAIL = ['ssh2', 'idn'] + static_ffmpeg(conf) + static_openjpeg(conf) + static_dcp(conf, True, True, True, True) + static_boost(conf, boost_lib_suffix) - conf.check_cxx(fragment=""" - #include \n - int main() { boost::filesystem::copy_file ("a", "b"); }\n - """, msg='Checking for boost filesystem library', - libpath='/usr/local/lib', - lib=['boost_filesystem%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix], - uselib_store='BOOST_FILESYSTEM') - - conf.check_cxx(fragment=""" - #include \n - int main() { boost::gregorian::day_clock::local_day(); }\n - """, msg='Checking for boost datetime library', - libpath='/usr/local/lib', - lib=['boost_date_time%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix], - uselib_store='BOOST_DATETIME') - - # Only Windows versions require boost::locale, which is handy, as it was only introduced in - # boost 1.48 and so isn't (easily) available on old Ubuntus. if conf.env.TARGET_WINDOWS: + conf.check_cfg(package='libxml++-2.6', args='--cflags --libs', uselib_store='XML++', mandatory=True) + conf.check_cfg(package='libcurl', args='--cflags --libs', uselib_store='CURL', mandatory=True) conf.check_cxx(fragment=""" #include \n int main() { std::locale::global (boost::locale::generator().generate ("")); }\n @@ -200,13 +271,28 @@ def configure(conf): libpath='/usr/local/lib', lib=['boost_locale%s' % boost_lib_suffix, 'boost_system%s' % boost_lib_suffix], uselib_store='BOOST_LOCALE') + dynamic_quickmail(conf) + dynamic_boost(conf, boost_lib_suffix, boost_thread) + dynamic_ffmpeg(conf) + dynamic_dcp(conf) + dynamic_ssh(conf) + + # Not packaging; just a straight build + if not conf.env.TARGET_WINDOWS and not conf.env.TARGET_DEBIAN and not conf.env.TARGET_CENTOS: + conf.check_cfg(package='libcxml', atleast_version='0.08', args='--cflags --libs', uselib_store='CXML', mandatory=True) + conf.check_cfg(package='libxml++-2.6', args='--cflags --libs', uselib_store='XML++', mandatory=True) + conf.check_cfg(package='libcurl', args='--cflags --libs', uselib_store='CURL', mandatory=True) + dynamic_quickmail(conf) + dynamic_boost(conf, boost_lib_suffix, boost_thread) + dynamic_ffmpeg(conf) + dynamic_dcp(conf) + dynamic_ssh(conf) - conf.check_cxx(fragment=""" - #include \n - int main() { boost::signals2::signal x; }\n - """, - msg='Checking for boost signals2 library', - uselib_store='BOOST_SIGNALS2') + # Dependencies which are always dynamically linked + conf.check_cfg(package='sndfile', args='--cflags --libs', uselib_store='SNDFILE', mandatory=True) + conf.check_cfg(package='glib-2.0', args='--cflags --libs', uselib_store='GLIB', mandatory=True) + conf.check_cfg(package= '', path=conf.options.magickpp_config, args='--cppflags --cxxflags --libs', uselib_store='MAGICK', mandatory=True) + conf.check_cfg(package='libzip', args='--cflags --libs', uselib_store='ZIP', mandatory=True) conf.check_cc(fragment=""" #include -- 2.30.2