prepare.py 10.3 KB
Newer Older
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
1 2 3 4
#!/usr/bin/env python

############################################################################
# prepare.py
5
# Copyright (C) 2015-2018  Belledonne Communications, Grenoble France
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#
############################################################################
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
21
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
22 23 24 25
#
############################################################################

import os
Ghislain MARY's avatar
Ghislain MARY committed
26
import platform
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
27
import sys
28
from logging import error, warning, info
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
29 30
from subprocess import Popen
sys.dont_write_bytecode = True
31
sys.path.insert(0, 'submodules/cmake-builder')
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
32 33
try:
    import prepare
34 35
except Exception as e:
    error(
36 37
        "Could not find prepare module: {}, probably missing submodules/cmake-builder? Try running:\n"
        "git submodule sync && git submodule update --init --recursive".format(e))
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
38 39 40
    exit(1)


41

Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
42 43
class DesktopTarget(prepare.Target):

44
    def __init__(self, group_builders=False):
45
        prepare.Target.__init__(self, 'desktop')
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
46 47
        current_path = os.path.dirname(os.path.realpath(__file__))
        self.config_file = 'configs/config-desktop.cmake'
48 49
        self.output = 'OUTPUT/' + self.name
        self.external_source_path = os.path.join(current_path, 'submodules')
50 51 52
        self.packaging_args = [
            "-DENABLE_RELATIVE_PREFIX=YES"
        ]
53 54 55 56 57
        external_builders_path = os.path.join(current_path, 'cmake_builder')
        self.additional_args = [
            "-DLINPHONE_BUILDER_EXTERNAL_BUILDERS_PATH=" + external_builders_path,
            "-DLINPHONE_BUILDER_TARGET=linphoneqt"
        ]
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
58

59

60 61 62 63 64 65 66 67 68 69
class DesktopRaspberryTarget(prepare.Target):

    def __init__(self, group_builders=False):
        prepare.Target.__init__(self, 'desktop-raspberry')
        current_path = os.path.dirname(os.path.realpath(__file__))
        self.required_build_platforms = ['Linux']
        self.config_file = 'configs/config-desktop-raspberry.cmake'
        self.toolchain_file = 'toolchains/toolchain-raspberry.cmake'
        self.output = 'OUTPUT/' + self.name
        self.external_source_path = os.path.join(current_path, 'submodules')
70 71 72 73
        self.packaging_args = [
            "-DCMAKE_INSTALL_RPATH=$ORIGIN/../lib",
            "-DENABLE_RELATIVE_PREFIX=YES"
        ]
74 75


76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
class DesktopRpmTarget(prepare.Target):

    def __init__(self, group_builders=False):
        prepare.Target.__init__(self, 'desktop-rpm')
        current_path = os.path.dirname(os.path.realpath(__file__))
        self.config_file = 'configs/config-desktop-rpm.cmake'
        self.output = 'OUTPUT/' + self.name
        self.external_source_path = os.path.join(current_path, 'submodules')
        external_builders_path = os.path.join(current_path, 'cmake_builder')
        self.additional_args = [
            "-DLINPHONE_BUILDER_EXTERNAL_BUILDERS_PATH=" + external_builders_path,
            "-DLINPHONE_BUILDER_TARGET=linphoneqt"
        ]


91 92 93 94 95 96
class NoUITarget(prepare.Target):

    def __init__(self, group_builders=False):
        prepare.Target.__init__(self, 'no-ui')
        current_path = os.path.dirname(os.path.realpath(__file__))
        self.config_file = 'configs/config-desktop.cmake'
Erwan Croze's avatar
Erwan Croze committed
97
        self.output = 'OUTPUT/' + self.name
98 99 100
        self.external_source_path = os.path.join(current_path, 'submodules')
        self.packaging_args = [
            "-DCMAKE_INSTALL_RPATH=$ORIGIN/../lib",
101 102
            "-DENABLE_RELATIVE_PREFIX=YES",
            "-DENABLE_CXX_WRAPPER=OFF"
103 104 105 106 107
        ]




108 109 110
class PythonTarget(prepare.Target):

    def __init__(self):
111
        prepare.Target.__init__(self, 'python')
112 113
        current_path = os.path.dirname(os.path.realpath(__file__))
        self.config_file = 'configs/config-python.cmake'
114 115
        self.output = 'OUTPUT/' + self.name
        self.external_source_path = os.path.join(current_path, 'submodules')
Ghislain MARY's avatar
Ghislain MARY committed
116 117 118 119 120
        external_builders_path = os.path.join(current_path, 'cmake_builder')
        self.additional_args += [
            "-DLINPHONE_BUILDER_EXTERNAL_BUILDERS_PATH=" + external_builders_path,
            "-DLINPHONE_BUILDER_PYTHON_VERSION={}.{}".format(sys.version_info.major, sys.version_info.minor)
        ]
121

122

123 124 125
class PythonRaspberryTarget(prepare.Target):

    def __init__(self):
126
        prepare.Target.__init__(self, 'python-raspberry')
Ghislain MARY's avatar
Ghislain MARY committed
127
        current_path = os.path.dirname(os.path.realpath(__file__))
128 129 130
        self.required_build_platforms = ['Linux']
        self.config_file = 'configs/config-python-raspberry.cmake'
        self.toolchain_file = 'toolchains/toolchain-raspberry.cmake'
131 132 133 134 135 136 137
        self.output = 'OUTPUT/' + self.name
        self.external_source_path = os.path.join(current_path, 'submodules')



desktop_targets = {
    'desktop': DesktopTarget(),
138
    'desktop-raspberry': DesktopRaspberryTarget(),
139 140 141 142
    'desktop-rpm': DesktopRpmTarget(),
    'no-ui' : NoUITarget(),
    'python': PythonTarget(),
    'python-raspberry': PythonRaspberryTarget()
143 144 145 146 147
}

class DesktopPreparator(prepare.Preparator):

    def __init__(self, targets=desktop_targets, default_targets=['desktop']):
148
        prepare.Preparator.__init__(self, targets, default_targets)
149 150 151 152
        self.veryclean = True
        self.argparser.add_argument('-ac', '--all-codecs', help="Enable all codecs, including the non-free ones", action='store_true')
        self.argparser.add_argument('-sys', '--use-system-dependencies', help="Find dependencies on the system.", action='store_true')
        self.argparser.add_argument('-p', '--package', help="Build an installation package (only on Mac OSX and Windows).", action='store_true')
153
        self.argparser.add_argument('-ps', '--package-source', help="Build source packages for the dependencies.", action='store_true')
154 155

    def parse_args(self):
156
        prepare.Preparator.parse_args(self)
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179

        if self.args.use_system_dependencies:
            self.additional_args += ["-DLINPHONE_BUILDER_USE_SYSTEM_DEPENDENCIES=YES"]

        if self.args.all_codecs:
            self.additional_args += ["-DENABLE_GPL_THIRD_PARTIES=YES"]
            self.additional_args += ["-DENABLE_NON_FREE_CODECS=YES"]
            self.additional_args += ["-DENABLE_AMRNB=YES"]
            self.additional_args += ["-DENABLE_AMRWB=YES"]
            self.additional_args += ["-DENABLE_G729=YES"]
            self.additional_args += ["-DENABLE_GSM=YES"]
            self.additional_args += ["-DENABLE_ILBC=YES"]
            self.additional_args += ["-DENABLE_ISAC=YES"]
            self.additional_args += ["-DENABLE_OPUS=YES"]
            self.additional_args += ["-DENABLE_SILK=YES"]
            self.additional_args += ["-DENABLE_SPEEX=YES"]
            self.additional_args += ["-DENABLE_FFMPEG=YES"]
            self.additional_args += ["-DENABLE_H263=YES"]
            self.additional_args += ["-DENABLE_H263P=YES"]
            self.additional_args += ["-DENABLE_MPEG4=YES"]
            self.additional_args += ["-DENABLE_OPENH264=YES"]
            self.additional_args += ["-DENABLE_VPX=YES"]

Ghislain MARY's avatar
Ghislain MARY committed
180 181
    def check_environment(self):
        ret = prepare.Preparator.check_environment(self)
182

183
        if "no-ui" in self.targets:
184
            return ret
185 186
        if platform.system() == 'Windows':
            ret |= not self.check_is_installed('mingw-get', 'MinGW (https://sourceforge.net/projects/mingw/files/Installer/)')
187 188
        if platform.system() == 'Windows':
            doxygen_prog = 'doxygen (http://www.stack.nl/~dimitri/doxygen/download.html)'
erwan's avatar
erwan committed
189
            graphviz_prog = 'graphviz (http://www.graphviz.org/download/)'
190 191 192 193 194 195
        else:
            doxygen_prog = 'doxygen'
            graphviz_prog = 'graphviz'
        ret |= not self.check_is_installed('doxygen', doxygen_prog)
        ret |= not self.check_is_installed('dot', graphviz_prog)
        ret |= not self.check_python_module_is_present('pystache')
196
        ret |= not self.check_python_module_is_present('six')
197
        if "python" in self.args.target or "python-raspberry" in self.args.target:
198
            ret |= not self.check_python_module_is_present('wheel')
199

200 201 202 203 204 205 206 207
        return ret

    def show_missing_dependencies(self):
        if self.missing_dependencies:
            error("The following binaries are missing: {}. Please install these packages:\n\t{}".format(
                " ".join(self.missing_dependencies.keys()),
                " ".join(self.missing_dependencies.values())))

208
    def clean(self):
209
        prepare.Preparator.clean(self)
210 211 212 213 214 215
        if os.path.isfile('Makefile'):
            os.remove('Makefile')
        if os.path.isdir('WORK') and not os.listdir('WORK'):
            os.rmdir('WORK')
        if os.path.isdir('OUTPUT') and not os.listdir('OUTPUT'):
            os.rmdir('OUTPUT')
216

217
    def generate_makefile(self, generator, project_file=''):
218 219 220 221 222 223 224
        targets = self.args.target
        targets_str = ""
        for target in targets:
            targets_str += """
{target}: {target}-build

{target}-build:
225
\t{generator} WORK/{target}/cmake/{project_file}
226
\t@echo "Done"
227
""".format(target=target, generator=generator, project_file=project_file)
228 229
        makefile = """
targets={targets}
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
230

231
.PHONY: all
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
232

233
all: build
234

235
build: $(addsuffix -build, $(targets))
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
236

237
{targets_str}
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
238 239 240 241 242 243 244 245 246

pull-transifex:
\t$(MAKE) -C linphone pull-transifex

push-transifex:
\t$(MAKE) -C linphone push-transifex

help-prepare-options:
\t@echo "prepare.py was previously executed with the following options:"
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
247
\t@echo "   ./prepare.py {options}"
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
248 249 250 251 252

help: help-prepare-options
\t@echo ""
\t@echo "(please read the README.md file first)"
\t@echo ""
253
\t@echo "Available targets: {targets}"
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
254
\t@echo ""
255
""".format(targets=' '.join(targets), targets_str=targets_str, options=' '.join(self.argv), generator=generator)
256 257 258
        f = open('Makefile', 'w')
        f.write(makefile)
        f.close()
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
259

260

Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
261

262 263 264
def main():
    preparator = DesktopPreparator()
    preparator.parse_args()
Ghislain MARY's avatar
Ghislain MARY committed
265 266
    if preparator.check_environment() != 0:
        preparator.show_environment_errors()
267 268
        return 1
    return preparator.run()
Gautier Pelloux-Prayer's avatar
Gautier Pelloux-Prayer committed
269 270 271

if __name__ == "__main__":
    sys.exit(main())