Compare commits
8 Commits
Author | SHA1 | Date |
---|---|---|
Alibek Omarov | 2d1d6828e1 | |
Alibek Omarov | daf4380c19 | |
Alibek Omarov | 354a8e5eb1 | |
Alibek Omarov | 0b31ad1a27 | |
Alibek Omarov | d5cf82dc92 | |
Alibek Omarov | a03cfd164a | |
Alibek Omarov | a1041073b1 | |
Alibek Omarov | 75a36dd255 |
10
build-waf.sh
10
build-waf.sh
|
@ -1,15 +1,15 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
TOOLS="msvs,clang_compilation_database,color_msvc"
|
TOOLS="msvs,clang_compilation_database,color_msvc,msvc_pdb"
|
||||||
PRELUDE=$'\tContext.WAIFUVERSION=\'1.0.0\'\n\tsys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), \'scripts\', \'waifulib\'))'
|
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
|
# a set of relatively stable tools
|
||||||
# TODO: make it possible to override this list
|
# 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
|
pushd wafsrc
|
||||||
echo "-- Building waf without waifu extensions: $TOOLS"
|
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
|
mv waf ../waf-noext
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
@ -27,6 +27,6 @@ get_waifu_tools()
|
||||||
TOOLS=$TOOLS$(get_waifu_tools)
|
TOOLS=$TOOLS$(get_waifu_tools)
|
||||||
echo "-- Building waf with waifu extensions: $TOOLS"
|
echo "-- Building waf with waifu extensions: $TOOLS"
|
||||||
pushd wafsrc
|
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
|
mv waf ../waf-ext
|
||||||
popd
|
popd
|
||||||
|
|
|
@ -25,6 +25,27 @@ modern_cpp_flags = {
|
||||||
'default': ['-std=c++11']
|
'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
|
@Configure.conf
|
||||||
def check_cxx11(ctx, *k, **kw):
|
def check_cxx11(ctx, *k, **kw):
|
||||||
if not 'msg' in kw:
|
if not 'msg' in kw:
|
||||||
|
@ -36,7 +57,7 @@ def check_cxx11(ctx, *k, **kw):
|
||||||
# not best way, but this check
|
# not best way, but this check
|
||||||
# was written for exactly mainui_cpp,
|
# was written for exactly mainui_cpp,
|
||||||
# where lambdas are mandatory
|
# 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):
|
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)
|
||||||
|
@ -51,4 +72,3 @@ def configure(conf):
|
||||||
|
|
||||||
if conf.env.CXX11_MANDATORY:
|
if conf.env.CXX11_MANDATORY:
|
||||||
conf.fatal('C++11 support not available!')
|
conf.fatal('C++11 support not available!')
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
import os
|
import os
|
||||||
from waflib import Utils, Errors, Configure, Build
|
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
|
'''Returns a list of compile flags, depending on compiler
|
||||||
|
|
||||||
:param flags: compiler flags
|
:param flags: compiler flags
|
||||||
|
@ -25,12 +25,21 @@ def get_flags_by_compiler(flags, compiler):
|
||||||
'''
|
'''
|
||||||
out = []
|
out = []
|
||||||
if compiler in flags:
|
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:
|
elif 'default' in flags:
|
||||||
out += flags['default']
|
out += flags['default']
|
||||||
return out
|
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
|
'''Returns a list of compile flags, depending on compiler and build type
|
||||||
|
|
||||||
:param flags: compiler flags
|
:param flags: compiler flags
|
||||||
|
@ -42,9 +51,9 @@ def get_flags_by_type(flags, type, compiler):
|
||||||
'''
|
'''
|
||||||
out = []
|
out = []
|
||||||
if 'common' in flags:
|
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:
|
if type in flags:
|
||||||
out += get_flags_by_compiler(flags[type], compiler)
|
out += get_flags_by_compiler(flags[type], compiler, major_version)
|
||||||
return out
|
return out
|
||||||
|
|
||||||
@Configure.conf
|
@Configure.conf
|
||||||
|
@ -74,20 +83,18 @@ def filter_cflags(conf, flags, required_flags = []):
|
||||||
def filter_cxxflags(conf, flags, required_flags = []):
|
def filter_cxxflags(conf, flags, required_flags = []):
|
||||||
return conf.filter_flags(flags, required_flags, 'cxx', 'cxxflags', conf.env.COMPILER_CXX)
|
return conf.filter_flags(flags, required_flags, 'cxx', 'cxxflags', conf.env.COMPILER_CXX)
|
||||||
|
|
||||||
def conf_get_flags_by_compiler(unused, flags, compiler):
|
def conf_get_flags_by_compiler(unused, flags, compiler, major_version=None):
|
||||||
return get_flags_by_compiler(flags, compiler)
|
return get_flags_by_compiler(flags, compiler, major_version)
|
||||||
|
|
||||||
setattr(Configure.ConfigurationContext, 'get_flags_by_compiler', conf_get_flags_by_compiler)
|
setattr(Configure.ConfigurationContext, 'get_flags_by_compiler', conf_get_flags_by_compiler)
|
||||||
setattr(Build.BuildContext, '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):
|
def conf_get_flags_by_type(unused, flags, type, compiler, major_version=None):
|
||||||
return get_flags_by_type(flags, type, compiler)
|
return get_flags_by_type(flags, type, compiler, major_version)
|
||||||
|
|
||||||
setattr(Configure.ConfigurationContext, 'get_flags_by_type', conf_get_flags_by_type)
|
setattr(Configure.ConfigurationContext, 'get_flags_by_type', conf_get_flags_by_type)
|
||||||
setattr(Build.BuildContext, '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):
|
def get_deps(bld, target):
|
||||||
'''Returns a list of (nested) targets on which this target depends.
|
'''Returns a list of (nested) targets on which this target depends.
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -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')
|
|
@ -11,8 +11,11 @@ from waflib import Build, Utils, Context, Errors, Logs
|
||||||
|
|
||||||
def options(opt):
|
def options(opt):
|
||||||
grp = opt.option_groups['install/uninstall options']
|
grp = opt.option_groups['install/uninstall options']
|
||||||
grp.add_option('--no-strip', dest='no_strip', action='store_true', default=False,
|
grp.add_option('--strip', dest='strip', action='store_true', default=False,
|
||||||
help='don\'t strip binaries. You must pass this flag to install command(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):
|
def configure(conf):
|
||||||
if conf.env.DEST_BINFMT in ['elf', 'mac-o']:
|
if conf.env.DEST_BINFMT in ['elf', 'mac-o']:
|
||||||
|
@ -20,27 +23,53 @@ def configure(conf):
|
||||||
if not conf.env.STRIPFLAGS:
|
if not conf.env.STRIPFLAGS:
|
||||||
conf.env.STRIPFLAGS = os.environ['STRIPFLAGS'] if 'STRIPFLAGS' in os.environ else []
|
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):
|
def copy_fun(self, src, tgt):
|
||||||
inst_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
|
return
|
||||||
|
|
||||||
if self.env.DEST_BINFMT not in ['elf', 'mac-o']: # don't strip unknown formats or PE
|
if self.env.DEST_BINFMT not in ['elf', 'mac-o']: # don't strip unknown formats or PE
|
||||||
return
|
return
|
||||||
|
|
||||||
if getattr(self.generator, 'link_task', None) and self.generator.link_task.outputs[0] in self.inputs:
|
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'
|
||||||
try:
|
strip_cmd = self.env.STRIP + self.env.STRIPFLAGS + [tgt]
|
||||||
self.generator.bld.cmd_and_log(cmd, output=Context.BOTH, quiet=Context.BOTH)
|
ocopy_cmd = self.env.OBJCOPY + ['--only-keep-debug', tgt, tgt_debug]
|
||||||
if not self.generator.bld.progress_bar:
|
ocopy_debuglink_cmd = self.env.OBJCOPY + ['--add-gnu-debuglink=%s' % tgt_debug, tgt]
|
||||||
c1 = Logs.colors.NORMAL
|
c1 = Logs.colors.NORMAL
|
||||||
c2 = Logs.colors.CYAN
|
c2 = Logs.colors.CYAN
|
||||||
|
c3 = Logs.colors.YELLOW
|
||||||
|
c4 = Logs.colors.BLUE
|
||||||
|
try:
|
||||||
|
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:
|
||||||
f1 = os.path.getsize(src)
|
f1 = os.path.getsize(src)
|
||||||
f2 = os.path.getsize(tgt)
|
f2 = os.path.getsize(tgt)
|
||||||
|
|
||||||
Logs.info('%s+ strip %s%s%s (%d bytes change)', c1, c2, tgt, c1, f2 - f1)
|
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:
|
except Errors.WafError as e:
|
||||||
print(e.stdout, e.stderr)
|
print(e.stdout, e.stderr)
|
||||||
|
|
||||||
|
|
2
wafsrc
2
wafsrc
|
@ -1 +1 @@
|
||||||
Subproject commit fbee1a19d208af00209b895de811f56e4dfe0da2
|
Subproject commit 00501901eb8ea3051ac023e804f9d572ddb61d89
|
Loading…
Reference in New Issue