1# This Source Code Form is subject to the terms of the Mozilla Public
2# License, v. 2.0. If a copy of the MPL was not distributed with this
3# file, You can obtain one at http://mozilla.org/MPL/2.0/.
4import cmakeparser as cp
5
6import copy
7import datetime
8import os
9import re
10import subprocess
11
12AOM_DIR = '../../third_party/aom'
13
14def write_aom_config(system, arch, variables, cache_variables):
15    # read template cmake file
16    variables['year'] = datetime.datetime.now().year
17    cp.parse(variables, [], os.path.join(AOM_DIR, 'build', 'cmake',
18          'generate_aom_config_templates.cmake'))
19
20    # filter variables
21    cache_variables = [x for x in sorted(cache_variables)
22                       if x and not x.startswith((' ', 'CMAKE', 'AOM'))]
23
24    # inherit this from the mozilla build config
25    cache_variables.remove('HAVE_PTHREAD_H')
26
27    outdir = os.path.join('config', system, arch, 'config')
28    try:
29        os.makedirs(outdir)
30    except OSError:
31        pass
32
33    with open(os.path.join(outdir, 'aom_config.h'), 'w') as f:
34        header = variables['h_file_header_block']
35        f.write(header)
36        f.write('\n')
37        for var in cache_variables:
38            f.write('#define %s %s\n' % (var, variables[var]))
39        f.write('#endif /* AOM_CONFIG_H_ */\n')
40
41    with open(os.path.join(outdir, 'aom_config.asm'), 'w') as f:
42        header = variables['asm_file_header_block']
43        f.write(header)
44        f.write('\n')
45        for var in cache_variables:
46            if var in ['INCLUDE_INSTALL_DIR', 'INLINE',
47                       'LIB_INSTALL_DIR', 'RESTRICT']:
48                continue
49            if arch == 'arm':
50                f.write('.equ %s, %s\n' % (var, variables[var]))
51            else:
52                f.write('%s equ %s\n' % (var, variables[var]))
53
54        if arch == 'arm':
55            f.write('.section	.note.GNU-stack,"",%progbits')
56
57
58if __name__ == '__main__':
59    import sys
60
61    shared_variables = {
62        'CMAKE_CURRENT_SOURCE_DIR': AOM_DIR,
63        'CONFIG_AV1_DECODER': 1,
64        'CONFIG_AV1_ENCODER': 0,
65        'CONFIG_COLLECT_INTER_MODE_RD_STATS': 0,
66        'CONFIG_INSPECTION': 0,
67        'CONFIG_INTERNAL_STATS': 0,
68        'CONFIG_LIBYUV': 0,
69        'CONFIG_LOWBITDEPTH': 1,
70        'CONFIG_MULTITHREAD': 1,
71        'CONFIG_PIC': 0,
72        'CONFIG_WEBM_IO': 0,
73        'CMAKE_CURRENT_BINARY_DIR': 'OBJDIR',
74        'CMAKE_INSTALL_PREFIX': 'INSTALLDIR',
75        'CMAKE_SYSTEM_NAME': 'Linux',
76        'CMAKE_SYSTEM_PROCESSOR': 'x86_64',
77        'ENABLE_EXAMPLES': 0,
78        'ENABLE_TESTS': 0,
79        'ENABLE_TOOLS': 0,
80        'ENABLE_DOCS': 0,
81        'ENABLE_NEON': 1,
82        'AOM_TEST_TEST_CMAKE_': 1, #prevent building tests
83    }
84
85    f = open('sources.mozbuild', 'w')
86    f.write('# This file is generated. Do not edit.\n\n')
87    f.write('files = {\n')
88
89    platforms = [
90        ('armv7', 'linux', 'arm', True),
91        ('generic', '', 'generic', True),
92        ('x86', 'linux', 'ia32', True),
93        ('x86', 'win', 'ia32', False),
94        ('x86_64', 'linux', 'x64', True),
95        ('x86_64', 'mac', 'x64', False),
96        ('x86_64', 'win', 'x64', False),
97    ]
98    for cpu, system, arch, generate_sources in platforms:
99        print('Running CMake for %s (%s)' % (cpu, system))
100        variables = shared_variables.copy()
101        variables['AOM_TARGET_CPU'] = cpu
102
103        # We skip compiling test programs that detect these
104        variables['HAVE_FEXCEPT'] = 1
105        variables['INLINE'] = 'inline'
106        if cpu == 'x86' and system == 'linux':
107            variables['CONFIG_PIC'] = 1
108        if cpu == 'armv7':
109            variables['CONFIG_PIC'] = 1
110        if system == 'win':
111            variables['MSVC'] = 1
112
113        cache_variables = []
114        sources = cp.parse(variables, cache_variables,
115                           os.path.join(AOM_DIR, 'CMakeLists.txt'))
116
117        # Disable HAVE_UNISTD_H.
118        cache_variables.remove('HAVE_UNISTD_H')
119        write_aom_config(system, arch, variables, cache_variables)
120        # Currently, the sources are the same for each supported cpu
121        # regardless of operating system / compiler. If that changes, we'll
122        # have to generate sources for each combination.
123        if generate_sources:
124            # Remove spurious sources and perl files
125            sources = filter(lambda x: x.startswith(AOM_DIR), sources)
126            sources = filter(lambda x: not x.endswith('.pl'), sources)
127
128            # Filter out exports
129            exports = filter(lambda x: re.match(os.path.join(AOM_DIR, '(aom|aom_mem|aom_ports|aom_scale)/.*h$'), x), sources)
130            exports = filter(lambda x: not re.search('(internal|src)', x), exports)
131            exports = filter(lambda x: not re.search('(emmintrin_compat.h|mem_.*|msvc.h|aom_once.h)$', x), exports)
132
133            sources = list(sources)
134
135            for export in exports:
136                sources.remove(export)
137
138            # Remove header files
139            sources = sorted(filter(lambda x: not x.endswith('.h'), sources))
140
141            # The build system is unhappy if two files have the same prefix
142            # In libaom, sometimes .asm and .c files share the same prefix
143            for i in range(len(sources) - 1):
144                if sources[i].endswith('.asm'):
145                    if os.path.splitext(sources[i])[0] == os.path.splitext(sources[i + 1])[0]:
146                        old = sources[i]
147                        sources[i] = sources[i].replace('.asm', '_asm.asm')
148                        if not os.path.exists(sources[i]):
149                            os.rename(old, sources[i])
150
151            f.write('  \'%s_EXPORTS\': [\n' % arch.upper())
152            for export in sorted(exports):
153                f.write('    \'%s\',\n' % export)
154            f.write("  ],\n")
155
156            f.write('  \'%s_SOURCES\': [\n' % arch.upper())
157            for source in sorted(sources):
158                f.write('    \'%s\',\n' % source)
159            f.write('  ],\n')
160
161        print('\n')
162
163    f.write('}\n')
164    f.close()
165