Port scons build files for Windows users

We disable:
- the tests (which require glib) although they can be
  reactivated with the `--tests` command line flag
- shared library (lack of export symbol declarations
  means that although it can be built, no symbol is
  exported and therefore it can't be used)

The `install` target installs the library and headers
under the `build` folder, because it's a traditional practice
to move libraries to a central location on Windows, unless
you are using cygwin. In which case pass `prefix` to the
command line.

We adapt tools\windows\build_examples.bat to take the library
that is built using scons or using tools\windows\build.bat
This commit is contained in:
nicolas 2016-05-22 13:29:12 +02:00
parent f31e3ba4bd
commit 69d3e70211
4 changed files with 76 additions and 21 deletions

View file

@ -4,9 +4,13 @@ import os.path
import platform
import sys
default_install_dir="/usr/local"
if platform.system() == 'Windows':
default_install_dir = "build" # no obvious place for installation on Windows
vars = Variables(None, ARGUMENTS)
vars.Add(PathVariable('DESTDIR', "Root directory to install in (useful for packaging scripts)", None, PathVariable.PathIsDirCreate))
vars.Add(PathVariable('prefix', "Where to install in the FHS", "/usr/local", PathVariable.PathAccept))
vars.Add(PathVariable('prefix', "Where to install in the FHS", default_install_dir, PathVariable.PathAccept))
vars.Add(ListVariable('bindings', 'Language bindings to build', 'none', ['cpp', 'dotnet', 'perl', 'php', 'python', 'ruby']))
tools = ['default', 'scanreplace']
@ -16,6 +20,9 @@ if 'dotnet' in ARGUMENTS.get('bindings', []):
envvars = {'PATH' : os.environ['PATH']}
if 'PKG_CONFIG_PATH' in os.environ:
envvars['PKG_CONFIG_PATH'] = os.environ['PKG_CONFIG_PATH']
if platform.system() == 'Windows':
# from the scons FAQ (keywords: LNK1104 TEMPFILE), needed by link.exe
envvars['TMP'] = os.environ['TMP']
env = Environment(ENV = envvars,
variables = vars,
@ -68,6 +75,12 @@ AddOption("--in-place",
action="store_true",
help="Build in-place, rather than in the build/<variant> tree")
AddOption("--tests",
dest="with_tests",
default=env['PLATFORM'] != 'win32',
action="store_true",
help="Build tests")
env["CC"] = os.getenv("CC") or env["CC"]
env["CXX"] = os.getenv("CXX") or env["CXX"]
@ -76,13 +89,29 @@ if os.getenv("CC") == "clang" or env['PLATFORM'] == 'darwin':
CXX="clang++")
# Language standard and warnings
env.MergeFlags("-std=gnu99 -Wall -Wextra -Werror -Wno-unused-parameter -Wno-attributes -Wno-unused-variable")
if env["CC"] == "cl":
env.MergeFlags("-W3 -WX")
env.Append(
CPPDEFINES=[
"_CRT_SECURE_NO_WARNINGS" # allow uses of sprintf
],
CFLAGS=[
"-wd4018", # 'expression' : signed/unsigned mismatch
"-wd4244", # 'argument' : conversion from 'type1' to 'type2', possible loss of data
"-wd4267", # 'var' : conversion from 'size_t' to 'type', possible loss of data
]
)
else:
env.MergeFlags("-std=gnu99 -Wall -Wextra -Werror -Wno-unused-parameter -Wno-attributes -Wno-unused-variable")
# Linker options
if env['PLATFORM'] == 'darwin':
env.Append(SHLINKFLAGS = '-install_name ' + env["libpath"] + '/${TARGET.file}')
elif platform.system() == "OpenBSD":
pass
elif env['PLATFORM'] == 'win32':
# no extra lib needed
pass
else:
env.MergeFlags("-lrt")
@ -96,10 +125,16 @@ if GetOption("coverage"):
env.ParseConfig('llvm-config --ldflags')
dbg = env.Clone(VARIANT='debug')
dbg.Append(CCFLAGS=['-g'])
if env["CC"] == "cl":
dbg.Append(CCFLAGS=["/Z7"])
else:
dbg.Append(CCFLAGS=['-g'])
opt = env.Clone(VARIANT='opt')
opt.Append(CCFLAGS=["-O3"])
if env["CC"] == "cl":
opt.Append(CCFLAGS=["/O2"])
else:
opt.Append(CCFLAGS=["-O3"])
if GetOption("variant") == 'debug':
env = dbg

View file

@ -1,5 +1,6 @@
# -*- python -*-
import os.path
Import('env testruns')
dist_headers = [
@ -48,7 +49,7 @@ parsers = ['parsers/%s.c'%s for s in
'unimplemented',
'whitespace',
'xor',
'value']]
'value']]
backends = ['backends/%s.c' % s for s in
['packrat', 'llk', 'regex', 'glr', 'lalr', 'lr', 'lr0']]
@ -63,11 +64,18 @@ misc_hammer_parts = [
'desugar.c',
'glue.c',
'hammer.c',
'platform_bsdlike.c',
'pprint.c',
'registry.c',
'system_allocator.c']
if env['PLATFORM'] == 'win32':
misc_hammer_parts += [
'platform_win32.c',
'tsearch.c',
]
else:
misc_hammer_parts += ['platform_bsdlike.c']
ctests = ['t_benchmark.c',
't_bitreader.c',
't_bitwriter.c',
@ -76,24 +84,36 @@ ctests = ['t_benchmark.c',
't_misc.c',
't_regression.c']
libhammer_shared = env.SharedLibrary('hammer', parsers + backends + misc_hammer_parts)
libhammer_static = env.StaticLibrary('hammer', parsers + backends + misc_hammer_parts)
Default(libhammer_shared, libhammer_static)
env.Install("$libpath", [libhammer_static, libhammer_shared])
static_library_name = 'hammer'
build_shared_library=True
if env['PLATFORM'] == 'win32':
build_shared_library=False # symbols in hammer are not exported yet, this shared lib would be useless
static_library_name = 'hammer_s' # prevent collision between .lib from dll and .lib for static lib
libhammer_shared = env.SharedLibrary('hammer', parsers + backends + misc_hammer_parts)
libhammer_static = env.StaticLibrary(static_library_name, parsers + backends + misc_hammer_parts)
if build_shared_library:
Default(libhammer_shared, libhammer_static)
env.Install("$libpath", [libhammer_static, libhammer_shared])
else:
Default(libhammer_static)
env.Install("$libpath", [libhammer_static])
env.Install("$incpath", dist_headers)
env.Install("$parsersincpath", parsers_headers)
env.Install("$backendsincpath", backends_headers)
env.Install("$pkgconfigpath", "../../../libhammer.pc")
testenv = env.Clone()
testenv.ParseConfig('pkg-config --cflags --libs glib-2.0')
testenv.Append(LIBS=['hammer'])
testenv.Prepend(LIBPATH=['.'])
ctestexec = testenv.Program('test_suite', ctests + ['test_suite.c'], LINKFLAGS="--coverage" if testenv.GetOption("coverage") else None)
ctest = Alias('testc', [ctestexec], "".join(["env LD_LIBRARY_PATH=", os.path.dirname(ctestexec[0].path), " ", ctestexec[0].path]))
AlwaysBuild(ctest)
testruns.append(ctest)
if GetOption("with_tests"):
testenv = env.Clone()
testenv.ParseConfig('pkg-config --cflags --libs glib-2.0')
testenv.Append(LIBS=['hammer'])
testenv.Prepend(LIBPATH=['.'])
ctestexec = testenv.Program('test_suite', ctests + ['test_suite.c'], LINKFLAGS="--coverage" if testenv.GetOption("coverage") else None)
ctest = Alias('testc', [ctestexec], "".join(["env LD_LIBRARY_PATH=", os.path.dirname(ctestexec[0].path), " ", ctestexec[0].path]))
AlwaysBuild(ctest)
testruns.append(ctest)
Export("libhammer_static libhammer_shared")

View file

@ -24,8 +24,8 @@ cl.exe -nologo -FC -EHsc -Z7 -Oi -GR- -Gm- %CLFLAGS% -c ^
-Fo%BUILD%\obj\
if %errorlevel% neq 0 goto err
lib.exe %BUILD%\obj\*.obj -OUT:%BUILD%\hammer.lib
echo STATIC_LIBRARY %BUILD%\hammer.lib
lib.exe %BUILD%\obj\*.obj -OUT:%BUILD%\lib\hammer_s.lib
echo STATIC_LIBRARY %BUILD%\lib\hammer_s.lib
if %errorlevel% neq 0 goto err
popd

View file

@ -15,7 +15,7 @@ call %HEREPATH%\clvars.bat
echo SRC=%SRC%, BUILD=%BUILD%
echo CLFLAGS=%CLFLAGS%
set HAMMERLIB=%BUILD%\hammer.lib
set HAMMERLIB=%BUILD%\lib\hammer_s.lib
REM Now let's build some example programs