prepare.py 8.38 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#!/usr/bin/env python

############################################################################
# prepare.py
# Copyright (C) 2015  Belledonne Communications, Grenoble France
#
############################################################################
#
# 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.
22 23 24 25
#
############################################################################

import os
Ghislain MARY's avatar
Ghislain MARY committed
26
import platform
27
import sys
28
from logging import error, warning, info
29 30
from subprocess import Popen
sys.dont_write_bytecode = True
31
sys.path.insert(0, 'submodules/cmake-builder')
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))
38 39 40
    exit(1)


41

42 43
class DesktopTarget(prepare.Target):

44
    def __init__(self, group_builders=False):
45
        prepare.Target.__init__(self, 'desktop')
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 53
        self.packaging_args = [
            "-DCMAKE_SKIP_INSTALL_RPATH=YES",
            "-DENABLE_RELATIVE_PREFIX=YES"
        ]
54

55

56 57 58 59 60 61 62 63 64 65
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')
66 67 68 69
        self.packaging_args = [
            "-DCMAKE_INSTALL_RPATH=$ORIGIN/../lib",
            "-DENABLE_RELATIVE_PREFIX=YES"
        ]
70 71


72 73 74
class PythonTarget(prepare.Target):

    def __init__(self):
75
        prepare.Target.__init__(self, 'python')
76 77
        current_path = os.path.dirname(os.path.realpath(__file__))
        self.config_file = 'configs/config-python.cmake'
78 79
        self.output = 'OUTPUT/' + self.name
        self.external_source_path = os.path.join(current_path, 'submodules')
80

81

82 83 84
class PythonRaspberryTarget(prepare.Target):

    def __init__(self):
85
        prepare.Target.__init__(self, 'python-raspberry')
Ghislain MARY's avatar
Ghislain MARY committed
86
        current_path = os.path.dirname(os.path.realpath(__file__))
87 88 89
        self.required_build_platforms = ['Linux']
        self.config_file = 'configs/config-python-raspberry.cmake'
        self.toolchain_file = 'toolchains/toolchain-raspberry.cmake'
90 91 92 93 94 95 96 97
        self.output = 'OUTPUT/' + self.name
        self.external_source_path = os.path.join(current_path, 'submodules')



desktop_targets = {
    'desktop': DesktopTarget(),
    'python': PythonTarget(),
98
    'desktop-raspberry': DesktopRaspberryTarget(),
99
    'python-raspberry': PythonRaspberryTarget()
100 101 102 103 104
}

class DesktopPreparator(prepare.Preparator):

    def __init__(self, targets=desktop_targets, default_targets=['desktop']):
105
        prepare.Preparator.__init__(self, targets, default_targets)
106 107 108 109 110 111
        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')

    def parse_args(self):
112
        prepare.Preparator.parse_args(self)
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

        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"]
            self.additional_args += ["-DENABLE_X264=NO"]

Ghislain MARY's avatar
Ghislain MARY committed
137 138
    def check_environment(self):
        ret = prepare.Preparator.check_environment(self)
139 140 141 142 143 144 145 146 147 148 149
        if platform.system() == 'Windows':
            ret |= not self.check_is_installed('mingw-get', 'MinGW (https://sourceforge.net/projects/mingw/files/Installer/)')
        if "python" in self.args.target or "python-raspberry" in self.args.target:
            if platform.system() == 'Windows':
                doxygen_prog = 'doxygen (http://www.stack.nl/~dimitri/doxygen/download.html)'
                graphviz_prog = 'graphviz (http://graphviz.org/Download.php)'
            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)
150 151
            ret |= not self.check_python_module_is_present('pystache')
            ret |= not self.check_python_module_is_present('wheel')
152 153 154 155 156 157 158 159
        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())))

160
    def clean(self):
161
        prepare.Preparator.clean(self)
162 163 164 165 166 167
        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')
168

169
    def generate_makefile(self, generator, project_file=''):
170 171 172 173 174 175 176
        targets = self.args.target
        targets_str = ""
        for target in targets:
            targets_str += """
{target}: {target}-build

{target}-build:
177
\t{generator} WORK/{target}/cmake/{project_file}
178
\t@echo "Done"
179
""".format(target=target, generator=generator, project_file=project_file)
180 181
        makefile = """
targets={targets}
182

183
.PHONY: all
184

185
all: build
186

187
build: $(addsuffix -build, $(targets))
188

189
{targets_str}
190 191 192 193 194 195 196 197 198

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:"
199
\t@echo "   ./prepare.py {options}"
200 201 202 203 204

help: help-prepare-options
\t@echo ""
\t@echo "(please read the README.md file first)"
\t@echo ""
205
\t@echo "Available targets: {targets}"
206
\t@echo ""
207
""".format(targets=' '.join(targets), targets_str=targets_str, options=' '.join(self.argv), generator=generator)
208 209 210
        f = open('Makefile', 'w')
        f.write(makefile)
        f.close()
211

212

213

214 215 216
def main():
    preparator = DesktopPreparator()
    preparator.parse_args()
Ghislain MARY's avatar
Ghislain MARY committed
217 218
    if preparator.check_environment() != 0:
        preparator.show_environment_errors()
219 220
        return 1
    return preparator.run()
221 222 223

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