]> git.proxmox.com Git - libgit2.git/blobdiff - wscript
config: Cleanup & renaming of the external API
[libgit2.git] / wscript
diff --git a/wscript b/wscript
index b02856862e7598dc477c45fa29291bb752745a7f..fd877e468e7e6182a2d2468509411591de3d3dea 100644 (file)
--- a/wscript
+++ b/wscript
@@ -1,15 +1,23 @@
+from __future__ import with_statement
 from waflib.Context import Context
 from waflib.Build import BuildContext, CleanContext, \
         InstallContext, UninstallContext
 
-CFLAGS_UNIX = ["-O2", "-Wall", "-Wextra"]
-CFLAGS_WIN32 = ['/TC', '/W4', '/RTC1', '/nologo']
+# Unix flags
+CFLAGS_UNIX = ["-O2", "-Wall", "-Wextra", "-fPIC"]
+CFLAGS_UNIX_DBG = ['-g', '-O0']
 
-CFLAGS_UNIX_DBG = ['-g']
-CFLAGS_WIN32_DBG = ['/Zi', '/DEBUG']
+# Windows MSVC flags
+CFLAGS_WIN32_COMMON = ['/TC', '/W4', '/WX', '/nologo', '/Zi']
+CFLAGS_WIN32_RELEASE = ['/O2', '/MD']
+
+# Note: /RTC* cannot be used with optimization on.
+CFLAGS_WIN32_DBG = ['/Od', '/RTC1', '/RTCc', '/DEBUG', '/MDd']
+CFLAGS_WIN32_L = ['/RELEASE']  # used for /both/ debug and release builds.
+                               # sets the module's checksum in the header.
 CFLAGS_WIN32_L_DBG = ['/DEBUG']
 
-ALL_LIBS = ['z', 'crypto', 'pthread']
+ALL_LIBS = ['crypto', 'pthread', 'sqlite3', 'hiredis']
 
 def options(opt):
     opt.load('compiler_c')
@@ -22,6 +30,12 @@ PPC optimized version (ppc) or the SHA1 functions from OpenSSL (openssl)")
         help='Force a specific MSVC++ version (7.1, 8.0, 9.0, 10.0), if more than one is installed')
     opt.add_option('--arch', action='store', default='x86',
         help='Select target architecture (ia64, x64, x86, x86_amd64, x86_ia64)')
+    opt.add_option('--with-sqlite', action='store_true', default=False,
+        dest='use_sqlite', help='Enable sqlite support')
+    opt.add_option('--with-hiredis', action='store_true', default=False,
+        dest='use_hiredis', help='Enable redis support using hiredis')
+    opt.add_option('--threadsafe', action='store_true', default=False,
+        help='Make libgit2 thread-safe (requires pthreads)')
 
 def configure(conf):
 
@@ -35,30 +49,43 @@ def configure(conf):
     conf.load('compiler_c')
 
     dbg = conf.options.debug
-    zlib_name = 'z'
 
-    conf.env.CFLAGS = CFLAGS_UNIX + (CFLAGS_UNIX_DBG if dbg else [])
+    conf.env.CFLAGS += CFLAGS_UNIX + (CFLAGS_UNIX_DBG if dbg else [])
 
     if conf.env.DEST_OS == 'win32':
         conf.env.PLATFORM = 'win32'
 
         if conf.env.CC_NAME == 'msvc':
-            conf.env.CFLAGS = CFLAGS_WIN32 + (CFLAGS_WIN32_DBG if dbg else [])
-            conf.env.LINKFLAGS += CFLAGS_WIN32_L_DBG if dbg else []
-            conf.env.DEFINES += ['WIN32', '_DEBUG', '_LIB', 'ZLIB_WINAPI']
-            zlib_name = 'zlibwapi'
-
-        elif conf.env.CC_NAME == 'gcc':
-            conf.check(features='c cprogram', lib='pthread', uselib_store='pthread')
+            conf.env.CFLAGS = CFLAGS_WIN32_COMMON + \
+              (CFLAGS_WIN32_DBG if dbg else CFLAGS_WIN32_RELEASE)
+            conf.env.LINKFLAGS += CFLAGS_WIN32_L + \
+              (CFLAGS_WIN32_L_DBG if dbg else [])
+            conf.env.DEFINES += ['WIN32', '_DEBUG', '_LIB']
 
     else:
         conf.env.PLATFORM = 'unix'
 
-    # check for Z lib
-    conf.check(features='c cprogram', lib=zlib_name, uselib_store='z', install_path=None)
+    if conf.env.DEST_OS == 'sunos':
+        conf.env.DEFINES += ['NO_VIZ']
+
+    if conf.options.threadsafe:
+        if conf.env.PLATFORM == 'unix':
+            conf.check_cc(lib='pthread', uselib_store='pthread')
+        conf.env.DEFINES += ['GIT_THREADS']
+
+    # check for sqlite3
+    if conf.options.use_sqlite and conf.check_cc(
+        lib='sqlite3', uselib_store='sqlite3', install_path=None, mandatory=False):
+        conf.env.DEFINES += ['GIT2_SQLITE_BACKEND']
+
+    # check for hiredis
+    if conf.options.use_hiredis and conf.check_cc(
+        lib='hiredis', uselib_store='hiredis', install_path=None, mandatory=False):
+        conf.env.DEFINES += ['GIT2_HIREDIS_BACKEND']
+
 
     if conf.options.sha1 not in ['openssl', 'ppc', 'builtin']:
-        ctx.fatal('Invalid SHA1 option')
+        conf.fatal('Invalid SHA1 option')
 
     # check for libcrypto (openssl) if we are using its SHA1 functions
     if conf.options.sha1 == 'openssl':
@@ -81,9 +108,9 @@ def build(bld):
         build_library(bld, 'shared')
 
     # command '[build|clean]-tests'
-    elif bld.variant == 'tests':
+    elif bld.variant == 'test':
         build_library(bld, 'objects')
-        build_tests(bld)
+        build_test(bld)
 
     # command 'build|clean|install|uninstall': by default, run
     # the same command for both the static and the shared lib
@@ -91,6 +118,19 @@ def build(bld):
         from waflib import Options
         Options.commands = [bld.cmd + '-shared', bld.cmd + '-static'] + Options.commands
 
+def get_libgit2_version(git2_h):
+    import re
+    line = None
+
+    with open(git2_h) as f:
+        line = re.search(r'^#define LIBGIT2_VERSION "(\d+\.\d+\.\d+)"$', f.read(), re.MULTILINE)
+
+    if line is None:
+        raise Exception("Failed to detect libgit2 version")
+
+    return line.group(1)
+
+
 def build_library(bld, build_type):
 
     BUILD = {
@@ -102,10 +142,15 @@ def build_library(bld, build_type):
     directory = bld.path
     sources = directory.ant_glob('src/*.c')
 
+    # Find the version of the library, from our header file
+    version = get_libgit2_version(directory.find_node("include/git2.h").abspath())
+
     # Compile platform-dependant code
     # E.g.  src/unix/*.c
     #       src/win32/*.c
     sources = sources + directory.ant_glob('src/%s/*.c' % bld.env.PLATFORM)
+    sources = sources + directory.ant_glob('src/backends/*.c')
+    sources = sources + directory.ant_glob('deps/zlib/*.c')
 
     # SHA1 methods source
     if bld.env.sha1 == "ppc":
@@ -120,67 +165,48 @@ def build_library(bld, build_type):
     BUILD[build_type](
         source=sources,
         target='git2',
-        includes='src',
+        includes=['src', 'include', 'deps/zlib'],
         install_path='${LIBDIR}',
-        use=ALL_LIBS
+        use=ALL_LIBS,
+        vnum=version,
     )
 
     # On Unix systems, build the Pkg-config entry file
     if bld.env.PLATFORM == 'unix' and bld.is_install:
-        bld(rule="""sed -e 's#@prefix@#${PREFIX}#' -e 's#@libdir@#${LIBDIR}#' < ${SRC} > ${TGT}""",
+        bld(rule="""sed -e 's#@prefix@#${PREFIX}#' -e 's#@libdir@#${LIBDIR}#' -e 's#@version@#%s#' < ${SRC} > ${TGT}""" % version,
             source='libgit2.pc.in',
             target='libgit2.pc',
             install_path='${LIBDIR}/pkgconfig',
         )
 
     # Install headers
-    bld.install_files('${PREFIX}/include', directory.find_node('src/git2.h'))
-    bld.install_files('${PREFIX}/include/git2', directory.ant_glob('src/git2/*.h'))
+    bld.install_files('${PREFIX}/include', directory.find_node('include/git2.h'))
+    bld.install_files('${PREFIX}/include/git2', directory.ant_glob('include/git2/*.h'))
 
     # On Unix systems, let them know about installation
-    if bld.env.PLATFORM == 'unix' and bld.cmd in ['install-static', 'install-shared']:
+    if bld.env.PLATFORM == 'unix' and bld.cmd == 'install-shared':
         bld.add_post_fun(call_ldconfig)
 
 def call_ldconfig(bld):
-    bld.exec_command('/sbin/ldconfig')
-
-def grep_test_header(text, test_file):
-    return '\n'.join(l for l in test_file.read().splitlines() if text in l)
-
-def build_tests(bld):
-    import os
-
-    if bld.is_install:
-        return
+    import distutils.spawn as s
+    ldconf = s.find_executable('ldconfig')
+    if ldconf:
+        bld.exec_command(ldconf)
 
+def build_test(bld):
     directory = bld.path
     resources_path = directory.find_node('tests/resources/').abspath().replace('\\', '/')
 
-    # Common object with the Test library methods
-    bld.objects(source=['tests/test_helpers.c', 'tests/test_lib.c'], includes=['src', 'tests'], target='test_helper')
-
-    # Build all tests in the tests/ folder
-    for test_file in directory.ant_glob('tests/t????-*.c'):
-        test_name, _ = os.path.splitext(os.path.basename(test_file.abspath()))
-
-        # Preprocess table of contents for each test
-        test_toc_file = directory.make_node('tests/%s.toc' % test_name)
-        if bld.cmd == 'clean-tests': # cleanup; delete the generated TOC file
-            test_toc_file.delete()
-        elif bld.cmd == 'build-tests': # build; create TOC
-            test_toc_file.write(grep_test_header('BEGIN_TEST', test_file))
-
-        # Build individual test (don't run)
-        bld.program(
-            source=[test_file, 'tests/test_main.c'],
-            target=test_name,
-            includes=['src', 'tests'],
-            defines=['TEST_TOC="%s.toc"' % test_name, 'TEST_RESOURCES="%s"' % resources_path],
-            install_path=None,
-            use=['test_helper', 'git2'] + ALL_LIBS  # link with all the libs we know
-                                            # libraries which are not enabled won't link
-        )
+    sources = ['tests/test_lib.c', 'tests/test_helpers.c', 'tests/test_main.c']
+    sources = sources + directory.ant_glob('tests/t??-*.c')
 
+    bld.program(
+        source=sources,
+        target='libgit2_test',
+        includes=['src', 'tests', 'include'],
+        defines=['TEST_RESOURCES="%s"' % resources_path],
+        use=['git2'] + ALL_LIBS
+    )
 
 class _test(BuildContext):
     cmd = 'test'
@@ -188,7 +214,7 @@ class _test(BuildContext):
 
 def test(bld):
     from waflib import Options
-    Options.commands = ['build-tests', 'run-tests'] + Options.commands
+    Options.commands = ['build-test', 'run-test'] + Options.commands
 
 class _build_doc(Context):
     cmd = 'doxygen'
@@ -204,21 +230,24 @@ def build_docs(ctx):
     ctx.exec_command("git push origin gh-pages")
     ctx.exec_command("git checkout master")
 
-class _run_tests(Context):
-    cmd = 'run-tests'
-    fun = 'run_tests'
+class _run_test(Context):
+    cmd = 'run-test'
+    fun = 'run_test'
 
-def run_tests(ctx):
-    import shutil, tempfile
+def run_test(ctx):
+    import shutil, tempfile, sys
 
     failed = False
+
+    test_path = 'build/test/libgit2_test'
+    if sys.platform == 'win32':
+        test_path += '.exe'
+
     test_folder = tempfile.mkdtemp()
-    test_glob = 'build/tests/t????-*'
+    test = ctx.path.find_node(test_path)
 
-    for test in ctx.path.ant_glob(test_glob):
-        if ctx.exec_command(test.abspath(), cwd=test_folder) != 0:
-            failed = True
-            break
+    if not test or ctx.exec_command(test.abspath(), cwd=test_folder) != 0:
+        failed = True
 
     shutil.rmtree(test_folder)
 
@@ -241,11 +270,11 @@ def build_command(command):
 
 build_command('build-static')
 build_command('build-shared')
-build_command('build-tests')
+build_command('build-test')
 
 build_command('clean-static')
 build_command('clean-shared')
-build_command('clean-tests')
+build_command('clean-test')
 
 build_command('install-static')
 build_command('install-shared')