Example #1
0
 def __init__(self, build, **kw):
     if platform.IS_MACOSX:
         kw.setdefault('stdlib', 'libc++')
     kw.setdefault('standard', 'c++11')
     super().__init__(build, **kw)
     if platform.IS_OSX and self.stdlib == 'libc++':
         prefix = path.join(path.dirname(path.absolute(self.binary, real = True)), '..', absolute = True)
         self.libraries.extend([
             self.find_library(
                 'libc++',
                 name_suffixes = ['', '.1'],
                 include_directories = [
                     path.join(prefix, 'lib/c++/v1'),
                     path.join(prefix, 'include/c++/v1'),
                 ],
                 find_includes = ['__config', 'cxxabi.h'],
                 prefixes = [
                     prefix,
                     path.join(prefix, 'usr')
                 ]
             ),
             #self.find_library('libc++abi'),
         ])
Example #2
0
 def static_stdlib_directory(self):
     if not hasattr(self, '_static_stdlib_directory'):
         import subprocess
         f = subprocess.check_output([self.binary, '--print-file-name=libstdc++.a']).decode('utf8')
         self._static_stdlib_directory = path.dirname(f)
     return self._static_stdlib_directory
Example #3
0
    def _set_directories_and_files(self, directories):
        dirs = self._env_directories()
        files = self._env_files()

        if dirs and files:
            self.directories = dirs
            self.files = files
            tools.debug("Found %s library directories and files from environment" % self.name)
            return
        else:
            self.directories = []
            self.files = []

        tools.debug("Searching %s library directories and files" % self.name)
        dirs.extend(directories)
        if self.macosx_framework:
            dirs.extend(path.join(p, 'Library', 'Frameworks') for p in self.prefixes)
        else:
            dirs.extend(path.join(p, 'lib') for p in self.prefixes)
        if self.use_system_paths:
            dirs.extend(self.library_system_paths())

        if self.macosx_framework:
            dirs = (path.join(dir_, self.name + '.framework', 'lib') for dir_ in dirs)

        dirs = list(path.clean(d) for d in tools.unique(dirs) if path.exists(d))

        if self.binary_file_names is not None:
            names = self.binary_file_names
        else:
            names = [self.name]

        extensions_list = []
        if self.macosx_framework:
            extensions_list = [None]
        if self.shared is not None:
            extensions_list = [
                (
                    self.shared,
                    self.compiler.library_extensions(
                        self.shared,
                        for_linker = True,
                    )
                )
            ]
        else:
            extensions_list = [
                (
                    self.preferred_shared,
                    self.compiler.library_extensions(self.preferred_shared, for_linker = True)
                ),
                (
                    not self.preferred_shared,
                    self.compiler.library_extensions(not self.preferred_shared, for_linker = True)
                ),
            ]

        for name in names:
            files = []
            for shared, extensions in extensions_list:
                for dir_ in dirs:
                    files.extend(self._find_files(dir_, name, extensions))
                    if files and self.only_one_binary_file:
                        if self.shared is None:
                            self.shared = shared
                        files = files[:1]
                        tools.debug("Stopping search for %s library files." % name)
                        break
                if files:
                    break # do not mix shared and non shared extensions


            if not files:
                    tools.fatal(
                        "Cannot find %s library files:" % self.name,
                        "\t* Set 'directories' when creating the library",
                        "\t* Set the environment variable '%s_DIRECTORY'" % self.name.upper(),
                        "\t* Set the environment variable '%s_DIRECTORIES'" % self.name.upper(),
                        "\t* Set the environment variable '%s_PREFIX'" % self.name.upper(),
                        "\t* Set the environment variable '%s_PREFIXES'" % self.name.upper(),
                        "\t* Set the environment variable 'PREFIX'",
                        "\t* Set the environment variable 'PREFIXES'",
                        "NOTE: Directories checked: %s" % ', '.join(dirs),
                        sep='\n'
                    )
            else:
                self.files.extend(files)
                self.directories.extend(path.dirname(f) for f in files)
Example #4
0
    def _get_link_flags(self, kw):
        link_flags = []
        if self.attr("allow_unresolved_symbols", kw):
            # link_flags.append('-Wl,--allow-shlib-undefined')
            # link_flags.append('-Wl,--unresolved-symbols=ignore-all')
            if self.name == "clang":
                link_flags.extend(["-undefined", "dynamic_lookup"])
            else:
                link_flags.extend(["-undefined=dynamic_lookup"])
        if self.attr("multithreading", kw):
            link_flags.append("-pthread")
        library_directories = self.library_directories[:]
        pic = self.attr("position_independent_code", kw)
        if pic and not platform.IS_WINDOWS:
            link_flags.append("-fPIC")
        if self.attr("hidden_visibility", kw):
            link_flags.append("-fvisibility=hidden")
            if self.lang == "c++":
                link_flags.append("-fvisibility-inlines-hidden")

        if platform.IS_MACOSX:
            link_flags.append("-headerpad_max_install_names")
        if platform.IS_WINDOWS:
            link_flags.append("--enable-stdcall-fixup")

        export_libraries = self.list_attr("export_libraries", kw)
        if self.name != "clang":
            excluded_libs = []
            for lib in self.list_attr("libraries", kw):
                if lib not in export_libraries:
                    if isinstance(lib, Target):
                        if not lib.shared:
                            excluded_libs.append(lib.path)
                    elif not (lib.macosx_framework or lib.system):
                        if not lib.shared:
                            excluded_libs.extend(lib.files)
            if excluded_libs:
                # Specifying multiple comma separated libs here does not work
                # Specifying full path does not work ... (but no error)
                link_flags.extend("-Wl,--exclude-libs,%s" % path.basename(f) for f in excluded_libs)

        rpath_dirs = []
        if self.attr("recursive_linking", kw):
            link_flags.append("-Wl,-(")
        for lib in self.list_attr("libraries", kw):
            if isinstance(lib, Target):
                if self.name == "clang" and lib in export_libraries:
                    if lib.shared:
                        link_flags.extend(["-Xlinker", "-reexport_library", "-Xlinker", lib])
                    else:
                        link_flags.extend(["-Xlinker", "-force_load", "-Xlinker", lib])
                else:
                    link_flags.append(lib)
                rpath_dirs.append(path.dirname(lib.path))
            elif lib.macosx_framework:
                link_flags.extend(["-framework", lib.name])
            elif lib.system == True:
                link_flags.append("-l%s" % lib.name)
            else:
                for f in lib.files:
                    # if not platform.IS_MACOSX:
                    #    if lib.shared:
                    #        link_flags.append('-Wl,-Bdynamic')
                    #    else:
                    #        link_flags.append('-Wl,-Bstatic')
                    if self.name == "clang" and lib in export_libraries:
                        if lib.shared:
                            link_flags.extend(["-Xlinker", "-reexport_library", "-Xlinker", f])
                        else:
                            link_flags.extend(["-Xlinker", "-force_load", "-Xlinker", f])
                    else:
                        link_flags.append(f)
                for dir_ in lib.directories:
                    library_directories.append(dir_)
        if self.attr("recursive_linking", kw):
            link_flags.append("-Wl,-)")

        # if not platform.IS_MACOSX:
        #    link_flags.append('-Wl,-Bdynamic')
        rpath_dirs.extend(library_directories)
        rpath_dirs = tools.unique(path.clean(p) for p in rpath_dirs)
        if rpath_dirs:
            if platform.IS_MACOSX:
                link_flags.extend(("-Wl,-rpath,%s" % d) for d in rpath_dirs)
            elif not platform.IS_WINDOWS:
                link_flags.append("-Wl,-rpath," + ":".join(rpath_dirs))
        link_flags.extend(self.additional_link_flags.get(self.name, []))
        if self.attr("static_libstd", kw):
            link_flags.append("-L%s" % self.static_stdlib_directory)
            link_flags.append("-static-libgcc")
        return link_flags
Example #5
0
 def __add_rpath(self, lib, **kw):
     return "-Wl,-rpath=\\$ORIGIN/" + path.dirname(lib.relpath(kw["target"], **kw))
Example #6
0
def main(build):
    build_type = build.env.get('BUILD_TYPE', 'DEBUG')
    build.env.BUILD_TYPE = build_type
    status("Configuring project", build.env.NAME, '(%s)' % build.env.VERSION_NAME,
           'in', build.directory, '(%s)' % build_type)

    from configure.lang import cxx


    if build.env.BUILD_TYPE == 'DEBUG':
        defines = [
            'ETC_DEBUG',
            'CUBE_DEBUG',
            'CUBEAPP_DEBUG',
        ]
        optimization = cxx.compiler.Compiler.dont_optimize
    elif build.env.BUILD_TYPE == 'RELEASE':
        defines = ['NDEBUG']
        if platform.IS_WINDOWS:
            defines.append(('_SCL_SECURE', '0'))
        optimization = cxx.compiler.Compiler.optimize_fastest
    else:
        raise Exception("Unknown build type '%s'" % build_type)

    defines += ['BOOST_ALL_NO_LIB', 'GLEW_NO_GLU', 'GLM_FORCE_RADIANS', ]

    if platform.IS_WINDOWS:
        defines.extend([
            'NOMINMAX'
        #    ('_WIN32_WINNT', '0x0600'),
        #    ('WINVER', '0x0600'),
        ])
    #if platform.IS_LINUX:
    #    defines += ['CUBE_WITH_GLX']

    library_directories = [
        #'/home/hotgloupi/sandbox/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/lib',
        #'/home/hotgloupi/sandbox/raspberry/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf',
        #'/home/hotgloupi/sandbox/raspberry/root/usr/lib',
        #'/home/hotgloupi/sandbox/raspberry/root/usr/lib/arm-linux-gnueabihf',
    ]
    include_directories = [
        path.join(build.directory, 'src'),
#        '/home/hotgloupi/sandbox/raspberry/root/usr/include',
#        '/home/hotgloupi/sandbox/raspberry/root/usr/include/arm-linux-gnueabihf',
        path.absolute(build.project.directory, 'src'),
        path.absolute(build.project.directory, 'src/glew'),
    ]
    compiler = cxx.find_compiler(
        build,
        position_independent_code = True,
        standard = 'c++11',
        defines = defines,
        library_directories = library_directories,
        include_directories = include_directories,
        static_libstd = False,
        hidden_visibility = (build_type != 'DEBUG'),
        optimization = optimization,
        #force_architecture = True,
        #target_architecture = '32bit',
        forbidden_warnings = ['return-type',]
#        additional_link_flags = {
#            'gcc': ['-ldl', '-lpthread', '-lutil', '-lz', '-lX11', '-Xlinker', '-export-dynamic'],
#        }
    )

    c_compiler = c.find_compiler(
        build,
        force_architecture = False,
        optimization = optimization
    )

    status("Using %s as C++ compiler" % compiler)
    status("Using %s as C compiler" % c_compiler)

    freetype2 = build.add_dependency(
        c.libraries.FreetypeDependency,
        c_compiler,
        'deps/freetype2'
    )

    zlib = build.add_dependency(
        ZLibDependency,
        c_compiler,
        'deps/zlib-1.2.8'
    )

    bz2 = build.add_dependency(
        BZ2Dependency,
        c_compiler,
        'deps/bzip2-1.0.6',
    )

    if not platform.IS_WINDOWS:
        idn = build.add_dependency(
            IDNDependency,
            c_compiler,
            'deps/libidn-1.28',
        )
    else:
        idn = None

    curl = build.add_dependency(
        c.libraries.CURLDependency,
        c_compiler,
        "deps/curl-7.35.0",
        shared = False, #platform.IS_WINDOWS,
        with_ldap = False,
        with_ldaps = False,
        with_ftp = False,
        with_tftp = False,
        with_telnet = False,
        with_dict = False,
        with_file = False,
        with_cookies = True,
        idn = idn,
    )

    bullet_physics = build.add_dependency(
        BulletPhysics,
        compiler,
        "deps/bullet-2.82-r2704",
        shared = False, #platform.IS_WINDOWS,
    )

    librocket = build.add_dependency(
        LibRocketDependency,
        compiler,
        "deps/libRocket",
        c_compiler = c_compiler,
        freetype2 = freetype2,
        shared = False, #platform.IS_WINDOWS,
    )

    if platform.IS_WINDOWS:
        python = c.libraries.PythonLibrary(c_compiler, shared = True)
    else:
        python = build.add_dependency(
            c.libraries.PythonDependency,
            c_compiler,
            'deps/Python-v3.4.0',
            shared = False,
            version = (3, 4),
            pymalloc = False,
            with_valgrind_support = False,
            threads = False,
        )

    boost = build.add_dependency(
        cxx.libraries.BoostDependency,
        compiler,
        'deps/boost_1_57_0',
        version = (1, 57),
        python = python,
        export_python = True,
        components = [
            'format',
            'timer',
            'system',
            'filesystem',
            'python',
            'signals2',
            'thread',
            'coroutine',
            'context',
        ],
        #preferred_shared = False,
        #        python3_shared = True,
        #thread_shared = True,
    )

    glm = build.add_dependency(GLM, compiler, "deps/glm")

    # XXX needed ?
    compiler.include_directories.extend(tools.unique(
        sum((l.include_directories for l in boost.libraries),  [])
    ))

    assimp = build.add_dependency(
        Assimp,
        compiler,
        'deps/assimp',
        boost = boost,
        c_compiler = c_compiler,
        zlib = zlib,
        shared = False, #platform.IS_WINDOWS
    )

    if platform.IS_OSX and platform.OSX_VERSION_MAJOR <= 10 and platform.OSX_VERSION_MINOR <= 6:
         sdl = c.libraries.SDLLibrary(
             c_compiler,
             macosx_framework = True,
             search_macosx_framework_files = True
         )
    else:
        sdl = build.add_dependency(
            c.libraries.SDLDependency,
            c_compiler,
            'deps/SDL',
            shared = platform.IS_WINDOWS,
            audio = False,
            haptic = False, # Fails on windows
            dynamic_api = False,
        )
    sdl_image = build.add_dependency(
        c.libraries.SDLImageDependency, c_compiler, 'deps/SDL_image',
        sdl = sdl,
        shared = False
    )
    #sdl = c.libraries.SDLLibrary(
    #    compiler,
    #    components=['image'],
    #    shared=True
    #)

    opengl = c.libraries.OpenGLLibrary(
        compiler,
        system = True,
        shared = compiler.name != 'msvc'
    )

    graphic_libraries = (
        sdl.libraries +
        sdl_image.libraries +
        opengl.libraries +
        #assimp.libraries +
        freetype2.libraries +
        glm.libraries +
        bullet_physics.libraries +
        librocket.libraries
    )
    #if not platform.IS_WINDOWS:
    #    list(c.libraries.simple(s, compiler) for s in ['png', 'jpeg'])

    base_libraries = zlib.libraries + bz2.libraries
    if platform.IS_WINDOWS:
        base_libraries.extend(
            c.libraries.simple(name, compiler, system = True) for name in [
                'Shlwapi',
                'ws2_32',
                'Gdi32',
                'mswsock',
                'Dbghelp',
                'winmm',
                'version',
                'imm32',
                'Shell32',
                'User32',
                'Ole32',
                'OleAut32',
                'Advapi32',
                'Kernel32',
                'msvcrt',
                'msvcprt',
                #'libcmt'
            ]
        )
    else: # OSX and Linux
        if platform.IS_LINUX:
            base_libraries.extend(
                c.libraries.simple(name, compiler, system = True) for name in [
                    'rt',
                    'util',
                ]
            )
            # SDL audio disabled
            #base_libraries.extend(
            #    c.libraries.simple(name, compiler, system = True) for name in ['audio',]
            #)
        elif platform.IS_MACOSX:
            base_libraries.extend(
                c.libraries.simple(name, compiler, macosx_framework = True)
                for name in [
                    'ForceFeedback', 'IOKit', 'Cocoa', 'Carbon', 'CoreVideo'
                    # 'AudioUnit', 'CoreAudio', 'AudioToolbox', # SDL Audio disabled
                ]
            )

    libglew = compiler.link_static_library(
        'libglew',
        ['src/glew/glew.c'],
        directory = 'release/lib',
        libraries = opengl.libraries,
        defines = ['GLEW_NO_GLU', 'GLEW_STATIC'],
    )

    graphic_libraries.insert(0, libglew)


    precompiled_headers = []

    with_pch = False
    if with_pch:
        precompiled_headers.append(
            compiler.generate_precompiled_header(
                "src/wrappers/stl.hpp",
                force_include = True,
            )
        )

    base_libraries.extend([
        boost.component_library('filesystem'),
        boost.component_library('system'),
        boost.component_library('thread'),
        boost.component_library('coroutine'),
        boost.component_library('context'),
    ])
    libetc = compiler.link_library(
        'libetc',
        rglob("src/etc/*.cpp"),
        directory  = 'release/lib',
        libraries = base_libraries + curl.libraries,
        defines = ['ETC_BUILD_DYNAMIC_LIBRARY', ('CURL_STATICLIB', 1)],
        shared = True,
        precompiled_headers = precompiled_headers,
    )
    libetc_static = compiler.link_library(
        'libetc-static',
        rglob("src/etc/*.cpp"),
        directory  = 'release/lib',
        object_directory = 'etc-static',
        libraries = base_libraries + curl.libraries,
        defines = ['ETC_BUILD_STATIC_LIBRARY', ('CURL_STATICLIB', 1)],
        shared = False,
        position_independent_code = True,
        static_libstd = not platform.IS_MACOSX,
        precompiled_headers = precompiled_headers,
    )

################### libcube
    if with_pch:
        precompiled_headers.extend([
            compiler.generate_precompiled_header(
                "src/wrappers/boost/signals2.hpp",
                libraries = boost.libraries
            ),
        ])

    libcube_libs = base_libraries + [libetc] + assimp.libraries + graphic_libraries

    libcube = compiler.link_dynamic_library(
        'libcube',
        rglob("src/cube/*.cpp"),
        directory  = 'release/lib',
        libraries = libcube_libs,
        precompiled_headers = precompiled_headers,
        defines = ['CUBE_BUILD_DYNAMIC_LIBRARY', 'ROCKET_STATIC_LIB'],
    )


    if with_pch:
        precompiled_headers.extend([
            compiler.generate_precompiled_header(
                "src/wrappers/boost/python.hpp",
                libraries = boost.libraries + python.libraries,
            ),
        ])

    python_module_libraries = boost.libraries
    if platform.IS_WINDOWS:
        python_module_libraries.extend([libcube, libetc])
    for binding in rglob("cube/*.py++", dir='src'):
        t = compiler.link_dynamic_library(
            path.splitext(path.basename(binding))[0],
            [binding],
            ext = python.ext,
            directory = path.dirname("release/lib/python", binding[4:]),
            libraries = python_module_libraries + base_libraries,
            include_directories = glm.libraries[0].include_directories,
            precompiled_headers = precompiled_headers,
            allow_unresolved_symbols = True,
        )

################### libcubeapp

    libcubeapp = compiler.link_dynamic_library(
        'libcubeapp',
        (src for src in rglob("src/cubeapp/*.cpp") if not src.endswith('main.cpp')),
        directory  = 'release/lib',
        libraries = [libetc, libcube] + boost.libraries + glm.libraries,
        precompiled_headers = precompiled_headers,
        defines = ['CUBEAPP_BUILD_DYNAMIC_LIBRARY'],
    )

    for binding in rglob("cubeapp/*.py++", dir='src'):
        compiler.link_dynamic_library(
            path.splitext(path.basename(binding))[0],
            [binding],
            ext = python.ext,
            directory = path.dirname("release/lib/python", binding[4:]),
            libraries=[libcubeapp, libcube, libetc] + graphic_libraries + boost.libraries + base_libraries,
            precompiled_headers = precompiled_headers,
        )


    infinit_cube_libraries = [
        libcubeapp,
        libcube,
        libetc,
    ] + graphic_libraries + boost.libraries + base_libraries

    cube_exe = compiler.link_executable(
        "8cube",
        ["src/cubeapp/main.cpp"],
        directory = "release/bin",
        libraries = infinit_cube_libraries,
        export_libraries = [boost.component_library('python')],
    )



    if platform.IS_WINDOWS:
        seen = set()
        for lib in infinit_cube_libraries + assimp.libraries:
            if not isinstance(lib, Target):
                #print("lib %s" % lib.files, lib.shared, lib.system)
                if lib.shared and not lib.system:
                    for f in lib.files:
                        if f not in seen:
                            seen.add(f)
                            build.fs.copy(f, dest_dir = 'release/bin')
            else:
                if lib.shared:
                    if lib.path not in seen:
                        seen.add(lib.path)
                        build.fs.copy(lib, dest_dir = 'release/bin')


    exts = ['py', 'bmp', 'ttf', 'rml']

    for ext in exts:
        for src in rglob("cube/*.%s" % ext, dir = 'src'):
            build.fs.copy(src, 'release/lib/python/' + src[4:])
        for src in rglob("cubeapp/*.%s" % ext, dir = 'src'):
            build.fs.copy(src, 'release/lib/python/' + src[4:])


    import os
    for ext in exts:
        for src in rglob(path.join('share/games/default', '*.%s' % ext)):
            build.fs.copy(src, "release/" + src[6:])


    # Default game launcher
    #
    # By default, it will launch the default game (named "default"). The
    # environment variable "GAME_ID" is used takes precedence over the default
    # game
    #
    compiler.link_executable(
        "launch",
        list(rglob("*.cpp", dir = "src/launch")),
        directory = 'release/bin',
        defines = [('GAME_ID', "default"), 'ETC_STATIC_LIBRARY'],
        static_libstd = not platform.IS_MACOSX and not platform.IS_WINDOWS,
        libraries =
            [libetc_static] +
            base_libraries +
            (
                not platform.IS_WINDOWS and
                [c.libraries.simple('pthread', compiler, system = True)] or
                []
            ) +
            curl.libraries
    )

    tests = [
        'simple_window', 'cube/gl/shader_generator',
    ]