1#!/usr/bin/python
2#
3# Copyright 2020 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6"""Creates config files for building Weston."""
7
8from __future__ import print_function
9
10import os
11import re
12import shutil
13import subprocess
14import sys
15import tempfile
16
17
18BASE_DIR = os.path.abspath(os.path.dirname(__file__))
19
20CHROMIUM_ROOT_DIR = os.path.abspath(os.path.join(BASE_DIR, '..', '..'))
21
22sys.path.append(os.path.join(CHROMIUM_ROOT_DIR, 'build'))
23import gn_helpers
24
25MESON = ['meson']
26
27DEFAULT_BUILD_ARGS = [
28    '-Dbuild_tests=false',
29    '--buildtype', 'release',
30    '-Dbackend-drm-screencast-vaapi=false',
31    '-Dbackend-rdp=false',
32    '-Dxwayland=false',
33    '-Dcolor-management-lcms=false',
34    '-Dpipewire=false',
35    '-Dcolor-management-colord=false',
36    '-Dremoting=false',
37    '-Dsimple-dmabuf-drm=auto',
38    '-Dshell-ivi=false',
39    '-Ddemo-clients=false',
40    '-Dsimple-clients=egl',
41    '-Dlauncher-logind=false',
42    '-Dweston-launch=false',
43    '-Dscreenshare=false',
44    '-Dsystemd=false',
45    '-Dimage-jpeg=false',
46    '-Dimage-webp=false',
47    '-Dbackend-drm=false',
48    '-Dbackend-default=wayland'
49]
50
51
52def PrintAndCheckCall(argv, *args, **kwargs):
53    print('\n-------------------------------------------------\nRunning %s' %
54          ' '.join(argv))
55    c = subprocess.check_call(argv, *args, **kwargs)
56
57
58def RewriteFile(path, search_replace):
59    with open(path) as f:
60        contents = f.read()
61    with open(path, 'w') as f:
62        for search, replace in search_replace:
63            contents = re.sub(search, replace, contents)
64
65        # Cleanup trailing newlines.
66        f.write(contents.strip() + '\n')
67
68def AddAttributeInConfig(path):
69    with open(path) as f:
70        contents = f.read()
71    with open(path, 'w') as f:
72        f.write(contents.strip() + '\n')
73        f.write('\n' + '__attribute__((visibility("default"))) int main(int argc, char* argv[]);' + '\n')
74
75def CopyConfigsAndCleanup(config_dir, dest_dir):
76    if not os.path.exists(dest_dir):
77        os.makedirs(dest_dir)
78
79    shutil.copy(os.path.join(config_dir, 'config.h'), dest_dir)
80    shutil.rmtree(config_dir)
81
82
83def RewriteGitFile(path, data):
84    with open(path, 'w') as f:
85        contents = data
86
87        # Cleanup trailing newlines.
88        f.write(contents.strip() + '\n')
89
90
91def CopyGitConfigsAndCleanup(config_dir, dest_dir):
92    if not os.path.exists(dest_dir):
93        os.makedirs(dest_dir)
94
95    shutil.copy(os.path.join(config_dir, 'git-version.h'), dest_dir)
96    shutil.rmtree(config_dir)
97
98
99def GenerateGitConfig(config_dir, env, special_args=[]):
100    temp_dir = tempfile.mkdtemp()
101    PrintAndCheckCall(
102        MESON + DEFAULT_BUILD_ARGS + special_args + [temp_dir],
103        cwd='src',
104        env=env)
105
106    label = subprocess.check_output(["git", "describe", "--always"]).strip()
107    label = label.decode("utf-8")
108    RewriteGitFile(
109        os.path.join(temp_dir, 'git-version.h'),
110        "#define BUILD_ID \"{label}\"".format(label=label))
111    CopyGitConfigsAndCleanup(temp_dir, config_dir)
112
113
114def GenerateConfig(config_dir, env, special_args=[]):
115    temp_dir = tempfile.mkdtemp()
116    PrintAndCheckCall(
117        MESON + DEFAULT_BUILD_ARGS + special_args + [temp_dir],
118        cwd='src',
119        env=env)
120
121    CopyConfigsAndCleanup(temp_dir, config_dir)
122
123
124def ChangeConfigPath():
125    configfile = os.path.join(BASE_DIR, "config/config.h")
126    DIRS = ["BINDIR",
127            "DATADIR",
128            "LIBEXECDIR",
129            "LIBWESTON_MODULEDIR",
130            "MODULEDIR"]
131    for dir in DIRS:
132        pattern = "#define {dir} \"/[a-zA-Z0-9\\-_/]+\"".format(dir=dir)
133        RewriteFile(configfile, [(pattern, "")])
134
135    # Add attribute in config.h to suppress all undefined symbol(function) warnings
136    AddAttributeInConfig(configfile)
137
138
139def GenerateWestonVersion():
140    dirname = os.path.join(BASE_DIR, "version/libweston")
141    if not os.path.exists(dirname):
142        os.makedirs(dirname)
143    version_op_file = os.path.join(BASE_DIR, "version/libweston/version.h")
144    configfile = os.path.join(BASE_DIR, "config/config.h")
145    version_in_file = os.path.join(BASE_DIR, "src/include/libweston/version.h.in")
146    version_number = "0.0.0"
147    with open(configfile, 'r') as f:
148        for line in f:
149            if "PACKAGE_VERSION" in line:
150                package_version_list = (line.strip("\n")).split(" ")
151                version_number = package_version_list[-1]
152
153    version_number_list = (version_number.strip('"\n"')).split(".")
154    version_number_list.append(version_number.strip("\"\""))
155    VERSIONS = ["@WESTON_VERSION_MAJOR@", "@WESTON_VERSION_MINOR@",
156                "@WESTON_VERSION_MICRO@", "@WESTON_VERSION@"]
157    with open(version_in_file) as f:
158        contents = f.read()
159
160    for version, version_number in zip(VERSIONS, version_number_list):
161        pattern = version
162        repl_string = version_number
163        with open(version_op_file, 'w') as f:
164            contents = re.sub(pattern, repl_string, contents)
165
166            # Cleanup trailing newlines.
167            f.write(contents.strip() + '\n')
168    print("Created version.h file from version.h.in\n")
169
170
171def main():
172    env = os.environ
173    env['CC'] = 'clang'
174    GenerateGitConfig('version', env)
175    GenerateConfig('config', env)
176    ChangeConfigPath()
177    GenerateWestonVersion()
178
179if __name__ == '__main__':
180    main()
181