cmake.py 2.93 KB
Newer Older
1
import os
2 3 4 5
import subprocess

from build.project import Project

6
def __write_cmake_compiler(f, language, compiler):
7 8
    s = compiler.split(' ', 1)
    if len(s) == 2:
9
        print(f'set(CMAKE_{language}_COMPILER_LAUNCHER {s[0]})', file=f)
10
        compiler = s[1]
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
    print(f'set(CMAKE_{language}_COMPILER {compiler})', file=f)

def __write_cmake_toolchain_file(f, toolchain):
    if '-darwin' in toolchain.actual_arch:
        cmake_system_name = 'Darwin'
    elif toolchain.is_windows:
        cmake_system_name = 'Windows'
    else:
        cmake_system_name = 'Linux'

    f.write(f"""
set(CMAKE_SYSTEM_NAME {cmake_system_name})
set(CMAKE_SYSTEM_PROCESSOR {toolchain.actual_arch.split('-', 1)[0]})

set(CMAKE_C_COMPILER_TARGET {toolchain.actual_arch})
set(CMAKE_CXX_COMPILER_TARGET {toolchain.actual_arch})

set(CMAKE_C_FLAGS "{toolchain.cflags} {toolchain.cppflags}")
set(CMAKE_CXX_FLAGS "{toolchain.cxxflags} {toolchain.cppflags}")
""")
    __write_cmake_compiler(f, 'C', toolchain.cc)
    __write_cmake_compiler(f, 'CXX', toolchain.cxx)
33

34 35 36 37 38 39
def configure(toolchain, src, build, args=()):
    cross_args = []

    if toolchain.is_windows:
        cross_args.append('-DCMAKE_RC_COMPILER=' + toolchain.windres)

40 41 42 43 44 45 46 47 48 49 50 51
    # Several targets need a sysroot to prevent pkg-config from
    # looking for libraries on the build host (TODO: fix this
    # properly); but we must not do that on Android because the NDK
    # has a sysroot already
    if '-android' not in toolchain.actual_arch and '-darwin' not in toolchain.actual_arch:
        cross_args.append('-DCMAKE_SYSROOT=' + toolchain.install_prefix)

    os.makedirs(build, exist_ok=True)
    cmake_toolchain_file = os.path.join(build, 'cmake_toolchain_file')
    with open(cmake_toolchain_file, 'w') as f:
        __write_cmake_toolchain_file(f, toolchain)

52 53 54 55
    configure = [
        'cmake',
        src,

56 57
        '-DCMAKE_TOOLCHAIN_FILE=' + cmake_toolchain_file,

58 59 60 61 62 63 64 65 66 67
        '-DCMAKE_INSTALL_PREFIX=' + toolchain.install_prefix,
        '-DCMAKE_BUILD_TYPE=release',

        '-GNinja',
    ] + cross_args + args

    subprocess.check_call(configure, env=toolchain.env, cwd=build)

class CmakeProject(Project):
    def __init__(self, url, md5, installed, configure_args=[],
68
                 windows_configure_args=[],
69 70 71
                 **kwargs):
        Project.__init__(self, url, md5, installed, **kwargs)
        self.configure_args = configure_args
72
        self.windows_configure_args = windows_configure_args
73 74 75 76

    def configure(self, toolchain):
        src = self.unpack(toolchain)
        build = self.make_build_path(toolchain)
77 78 79 80
        configure_args = self.configure_args
        if toolchain.is_windows:
            configure_args = configure_args + self.windows_configure_args
        configure(toolchain, src, build, configure_args)
81 82
        return build

83
    def _build(self, toolchain):
84 85 86
        build = self.configure(toolchain)
        subprocess.check_call(['ninja', 'install'],
                              cwd=build, env=toolchain.env)