Compare commits

...

8 Commits

7 changed files with 198 additions and 43 deletions

View File

@ -1,15 +1,15 @@
#!/bin/bash
TOOLS="msvs,clang_compilation_database,color_msvc"
PRELUDE=$'\tContext.WAIFUVERSION=\'1.0.0\'\n\tsys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), \'scripts\', \'waifulib\'))'
TOOLS="msvs,clang_compilation_database,color_msvc,msvc_pdb"
PRELUDE=$'\tContext.WAIFUVERSION=\'1.1.0\'\n\tsys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), \'scripts\', \'waifulib\'))'
# a set of relatively stable tools
# TODO: make it possible to override this list
WAIFU_TOOLS="gitversion,reconfigure,msdev,fwgslib,cxx11,force_32bit,subproject,strip_on_install,sdl2,msvcfix"
WAIFU_TOOLS="gitversion,reconfigure,msdev,fwgslib,cxx11,force_32bit,subproject,strip_on_install,sdl2,pthreads"
pushd wafsrc
echo "-- Building waf without waifu extensions: $TOOLS"
./waf-light "--tools=$TOOLS" "--prelude=$PRELUDE" "--set-name=waifu"
./waf-light "--tools=$TOOLS" "--prelude=$PRELUDE" "--set-name=waifu" --nostrip
mv waf ../waf-noext
popd
@ -27,6 +27,6 @@ get_waifu_tools()
TOOLS=$TOOLS$(get_waifu_tools)
echo "-- Building waf with waifu extensions: $TOOLS"
pushd wafsrc
./waf-light "--tools=$TOOLS" "--prelude=$PRELUDE" "--set-name=waifu"
./waf-light "--tools=$TOOLS" "--prelude=$PRELUDE" "--set-name=waifu" --nostrip
mv waf ../waf-ext
popd

View File

@ -25,22 +25,43 @@ modern_cpp_flags = {
'default': ['-std=c++11']
}
CXX11_LAMBDA_FRAGMENT='''
class T
{
static void M(){}
public:
void t()
{
auto l = []()
{
T::M();
};
}
};
int main()
{
T t;
t.t();
}
'''
@Configure.conf
def check_cxx11(ctx, *k, **kw):
if not 'msg' in kw:
kw['msg'] = 'Checking if \'%s\' supports C++11' % ctx.env.COMPILER_CXX
if not 'mandatory' in kw:
kw['mandatory'] = False
# not best way, but this check
# was written for exactly mainui_cpp,
# where lambdas are mandatory
return ctx.check_cxx(fragment='int main( void ){ auto pfnLambda = [](){}; return 0;}', *k, **kw)
return ctx.check_cxx(fragment=CXX11_LAMBDA_FRAGMENT, *k, **kw)
def configure(conf):
flags = get_flags_by_compiler(modern_cpp_flags, conf.env.COMPILER_CXX)
flags = get_flags_by_compiler(modern_cpp_flags, conf.env.COMPILER_CXX)
if conf.check_cxx11():
conf.env.HAVE_CXX11 = True
elif len(flags) != 0 and conf.check_cxx11(msg='...trying with additional flags', cxxflags = flags):
@ -48,7 +69,6 @@ def configure(conf):
conf.env.CXXFLAGS += flags
else:
conf.env.HAVE_CXX11 = False
if conf.env.CXX11_MANDATORY:
conf.fatal('C++11 support not available!')

View File

@ -14,7 +14,7 @@
import os
from waflib import Utils, Errors, Configure, Build
def get_flags_by_compiler(flags, compiler):
def get_flags_by_compiler(flags, compiler, major_version=None):
'''Returns a list of compile flags, depending on compiler
:param flags: compiler flags
@ -25,12 +25,21 @@ def get_flags_by_compiler(flags, compiler):
'''
out = []
if compiler in flags:
out += flags[compiler]
f = flags[compiler]
if type(f) is list:
out += f
elif type(f) is dict:
if major_version in f:
out += f[major_version]
elif 'default' in flags:
out += f['default']
else:
raise TypeError('unknown type, expected list or dict, got %s' % type(f))
elif 'default' in flags:
out += flags['default']
return out
def get_flags_by_type(flags, type, compiler):
def get_flags_by_type(flags, type, compiler, major_version=None):
'''Returns a list of compile flags, depending on compiler and build type
:param flags: compiler flags
@ -42,9 +51,9 @@ def get_flags_by_type(flags, type, compiler):
'''
out = []
if 'common' in flags:
out += get_flags_by_compiler(flags['common'], compiler)
out += get_flags_by_compiler(flags['common'], compiler, major_version)
if type in flags:
out += get_flags_by_compiler(flags[type], compiler)
out += get_flags_by_compiler(flags[type], compiler, major_version)
return out
@Configure.conf
@ -74,20 +83,18 @@ def filter_cflags(conf, flags, required_flags = []):
def filter_cxxflags(conf, flags, required_flags = []):
return conf.filter_flags(flags, required_flags, 'cxx', 'cxxflags', conf.env.COMPILER_CXX)
def conf_get_flags_by_compiler(unused, flags, compiler):
return get_flags_by_compiler(flags, compiler)
def conf_get_flags_by_compiler(unused, flags, compiler, major_version=None):
return get_flags_by_compiler(flags, compiler, major_version)
setattr(Configure.ConfigurationContext, 'get_flags_by_compiler', conf_get_flags_by_compiler)
setattr(Build.BuildContext, 'get_flags_by_compiler', conf_get_flags_by_compiler)
def conf_get_flags_by_type(unused, flags, type, compiler):
return get_flags_by_type(flags, type, compiler)
def conf_get_flags_by_type(unused, flags, type, compiler, major_version=None):
return get_flags_by_type(flags, type, compiler, major_version)
setattr(Configure.ConfigurationContext, 'get_flags_by_type', conf_get_flags_by_type)
setattr(Build.BuildContext, 'get_flags_by_type', conf_get_flags_by_type)
def get_deps(bld, target):
'''Returns a list of (nested) targets on which this target depends.

View File

@ -1,10 +0,0 @@
#!/usr/bin/env
from waflib.TaskGen import feature, after_method
@feature('c', 'cxx')
@after_method('apply_flags_msvc')
def make_pdb_unique(self):
for t in self.compiled_tasks:
pdb_unique_cflag = '/Fd' + t.outputs[0].change_ext('.pdb').abspath()
t.env.append_value('CFLAGS', pdb_unique_cflag)
t.env.append_value('CXXFLAGS', pdb_unique_cflag)

View File

@ -0,0 +1,109 @@
#!/usr/bin/env python
# encoding: utf-8
#
# partially based on boost.py written by Gernot Vormayr
# written by Ruediger Sonderfeld <ruediger@c-plusplus.de>, 2008
# modified by Bjoern Michaelsen, 2008
# modified by Luca Fossati, 2008
# rewritten for waf 1.5.1, Thomas Nagy, 2008
# rewritten for waf 1.6.2, Sylvain Rouquette, 2011
# split from boost.py to pthreads.py, Alibek Omarov, 2019
'''
This is an extra tool, not bundled with the default waf binary.
To add the boost tool to the waf file:
$ ./waf-light --tools=pthreads
When using this tool, the wscript will look like:
def configure(conf):
conf.load('compiler_cxx pthreads')
conf.check_pthread_flag()
def build(bld):
bld(source='main.cpp', target='app', use='PTHREAD')
'''
from waflib import Utils
from waflib.Configure import conf
PTHREAD_CODE = '''
#include <pthread.h>
static void* f(void* unused) {
(void)(unused);
return 0;
}
int main() {
pthread_t th;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&th, &attr, &f, 0);
pthread_join(th, 0);
pthread_cleanup_push(0, 0);
pthread_cleanup_pop(0);
pthread_attr_destroy(&attr);
}
'''
@conf
def check_pthread_flag(self, *k, **kw):
'''
Computes which flags should be added to CXXFLAGS and LINKFLAGS to compile in multi-threading mode
Yes, we *need* to put the -pthread thing in CPPFLAGS because with GCC3,
boost/thread.hpp will trigger a #error if -pthread isn't used:
boost/config/requires_threads.hpp:47:5: #error "Compiler threading support
is not turned on. Please set the correct command line options for
threading: -pthread (Linux), -pthreads (Solaris) or -mthreads (Mingw32)"
Based on _BOOST_PTHREAD_FLAG(): https://github.com/tsuna/boost.m4/blob/master/build-aux/boost.m4
'''
var = kw.get('uselib_store', 'PTHREAD')
self.start_msg('Checking the flags needed to use pthreads')
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# (none): in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -lpthreads: AIX (must check this before -lpthread)
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# -llthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: GNU Linux/GCC (kernel threads), BSD/GCC (userland threads)
# -pthreads: Solaris/GCC
# -mthreads: MinGW32/GCC, Lynx/GCC
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# -lpthread: GNU Linux, etc.
# --thread-safe: KAI C++
if Utils.unversioned_sys_platform() == "sunos":
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
boost_pthread_flags = ["-pthreads", "-lpthread", "-mt", "-pthread"]
else:
boost_pthread_flags = ["", "-lpthreads", "-Kthread", "-kthread", "-llthread", "-pthread",
"-pthreads", "-mthreads", "-lpthread", "--thread-safe", "-mt"]
for boost_pthread_flag in boost_pthread_flags:
try:
self.env.stash()
self.env.append_value('CFLAGS_%s' % var, boost_pthread_flag)
self.env.append_value('CXXFLAGS_%s' % var, boost_pthread_flag)
self.env.append_value('LINKFLAGS_%s' % var, boost_pthread_flag)
self.check_cxx(code=PTHREAD_CODE, msg=None, use=var, execute=False)
self.end_msg(boost_pthread_flag)
return
except self.errors.ConfigurationError:
self.env.revert()
self.end_msg('None')

View File

@ -11,36 +11,65 @@ from waflib import Build, Utils, Context, Errors, Logs
def options(opt):
grp = opt.option_groups['install/uninstall options']
grp.add_option('--no-strip', dest='no_strip', action='store_true', default=False,
help='don\'t strip binaries. You must pass this flag to install command(default: False)')
grp.add_option('--strip', dest='strip', action='store_true', default=False,
help='strip binaries. You must pass this flag to install command [default: %default]')
grp.add_option('--strip-to-file', dest='strip_to_file', action='store_true', default=False,
help='strip debug information to file *.debug. Implies --strip. You must pass this flag to install command [default: %default]')
def configure(conf):
if conf.env.DEST_BINFMT in ['elf', 'mac-o']:
conf.find_program('strip', var='STRIP')
if not conf.env.STRIPFLAGS:
conf.env.STRIPFLAGS = os.environ['STRIPFLAGS'] if 'STRIPFLAGS' in os.environ else []
# a1ba: I am lazy to add `export OBJCOPY=` everywhere in my scripts
# so just try to deduce which objcopy we have
try:
k = conf.env.STRIP[0].rfind('-')
if k >= 0:
objcopy_name = conf.env.STRIP[0][:k] + '-objcopy'
try: conf.find_program(objcopy_name, var='OBJCOPY')
except: conf.find_program('objcopy', var='OBJCOPY')
else:
conf.find_program('objcopy', var='OBJCOPY')
except:
conf.find_program('objcopy', var='OBJCOPY')
def copy_fun(self, src, tgt):
inst_copy_fun(self, src, tgt)
if self.generator.bld.options.no_strip:
if not self.generator.bld.options.strip and not self.generator.bld.options.strip_to_file:
return
if self.env.DEST_BINFMT not in ['elf', 'mac-o']: # don't strip unknown formats or PE
return
if getattr(self.generator, 'link_task', None) and self.generator.link_task.outputs[0] in self.inputs:
cmd = self.env.STRIP + self.env.STRIPFLAGS + [tgt]
tgt_debug = tgt + '.debug'
strip_cmd = self.env.STRIP + self.env.STRIPFLAGS + [tgt]
ocopy_cmd = self.env.OBJCOPY + ['--only-keep-debug', tgt, tgt_debug]
ocopy_debuglink_cmd = self.env.OBJCOPY + ['--add-gnu-debuglink=%s' % tgt_debug, tgt]
c1 = Logs.colors.NORMAL
c2 = Logs.colors.CYAN
c3 = Logs.colors.YELLOW
c4 = Logs.colors.BLUE
try:
self.generator.bld.cmd_and_log(cmd, output=Context.BOTH, quiet=Context.BOTH)
if self.generator.bld.options.strip_to_file:
self.generator.bld.cmd_and_log(ocopy_cmd, output=Context.BOTH, quiet=Context.BOTH)
if not self.generator.bld.progress_bar:
Logs.info('%s+ objcopy --only-keep-debug %s%s%s %s%s%s', c1, c4, tgt, c1, c3, tgt_debug, c1)
self.generator.bld.cmd_and_log(strip_cmd, output=Context.BOTH, quiet=Context.BOTH)
if not self.generator.bld.progress_bar:
c1 = Logs.colors.NORMAL
c2 = Logs.colors.CYAN
f1 = os.path.getsize(src)
f2 = os.path.getsize(tgt)
Logs.info('%s+ strip %s%s%s (%d bytes change)', c1, c2, tgt, c1, f2 - f1)
if self.generator.bld.options.strip_to_file:
self.generator.bld.cmd_and_log(ocopy_debuglink_cmd, output=Context.BOTH, quiet=Context.BOTH)
if not self.generator.bld.progress_bar:
Logs.info('%s+ objcopy --add-gnu-debuglink=%s%s%s %s%s%s', c1, c3, tgt_debug, c1, c2, tgt, c1)
except Errors.WafError as e:
print(e.stdout, e.stderr)

2
wafsrc

@ -1 +1 @@
Subproject commit fbee1a19d208af00209b895de811f56e4dfe0da2
Subproject commit 00501901eb8ea3051ac023e804f9d572ddb61d89