예제 #1
0
    def do_build(self):
        """ Runs the actual build process """
        # Downloading qgis is a big process. We escape to another directory and see if it is
        # downloaded already
        output = self.do_download_cache()

        # Resuming normal operations
        self.unpack(output)
        self.push_current_source_path(
            os.path.join(self.get_source_path(), self.library_name()))

        recon = self.get_recon()

        # QGis uses (as only library in this whole project) cmake. We need to set up a number
        # of things for this.

        our_env = dict(os.environ).copy()
        our_env['QT_ROOT'] = recon.qt_path
        our_env['ANDROID_LEVEL'] = str(recon.android_level)
        our_env['ANDROID_NDK_PLATFORM'] = 'android-' + str(recon.android_level)
        our_env['ANDROID_NDK_TOOLCHAIN_ROOT'] = recon.get_toolchain_path()
        our_env['ANDROID_NDK_HOST'] = 'linux-x86'
        our_env['ANDROID_NDK_TOOLCHAIN_PREFIX'] = 'arm-linux-androideabi'
        our_env['ANDROID_NDK_TOOLCHAIN_VERSION'] = '4.4.3'
        our_env['QT_INCLUDE_DIR'] = os.path.join(our_env['QT_ROOT'], 'include')
        our_env['QT_LIBRARY_DIR'] = os.path.join(our_env['QT_ROOT'], 'lib')
        our_env['QMAKE'] = os.path.join(recon.qt_tools_path, 'qmake')
        our_env['PATH'] = self.get_path()
        our_env['INSTALL_DIR'] = self.get_build_path()

        # We need to add some definitions
        self.add_definitions()

        self.sed_i(
            's/SPATIALITE_INCLUDE_DIR/\\SPATIALITE_INCLUDE_DIR\\} \\$\\{SQLITE3_INCLUDE_DIR/',
            'src/providers/spatialite/CMakeLists.txt')

        # Do the argument dance
        toolchain_src = os.path.join(self.get_core_patch_path(), 'cmake',
                                     'android.toolchain.cmake')
        toolchain_file = os.path.join(self.get_current_source_path(),
                                      'android.toolchain.cmake')
        shutil.copyfile(toolchain_src, toolchain_file)

        python_builder = PythonBuilder(self.get_recon())
        host_python_vars = python_builder.get_host_python_vars()
        cmake_path = os.path.join(self.get_current_source_path(), 'cmake')
        python_syspath = os.path.join(python_builder.get_host_python_prefix(),
                                      'site-packages')
        our_env["PYTHONPATH"] = python_syspath
        our_env['PATH'] = os.pathsep.join(
            [host_python_vars.bin, our_env['PATH']])

        arguments = {
            'ANDROID':
            'true',
            'ARM_TARGET':
            'armeabi',
            'CMAKE_INSTALL_PREFIX':
            self.get_build_path(),
            'CMAKE_TOOLCHAIN_FILE':
            toolchain_file,
            'QT_MKSPECS_DIR':
            os.path.join(recon.qt_path, 'mkspecs'),
            'QT_QMAKE_EXECUTABLE':
            os.path.join(recon.qt_tools_path, 'qmake'),
            'GDAL_CONFIG':
            os.path.join(
                GDALBuilder(recon).get_build_path(), 'bin', 'gdal-config'),
            'GDAL_INCLUDE_DIR':
            GDALBuilder(recon).get_include_path(),
            'GDAL_LIBRARY':
            os.path.join(
                GDALBuilder(recon).get_build_path(), 'lib', 'libgdal.so'),
            'GEOS_CONFIG':
            os.path.join(
                GeosBuilder(recon).get_build_path(), 'bin', 'geos-config'),
            'GEOS_INCLUDE_DIR':
            GeosBuilder(recon).get_include_path(),
            'GEOS_LIBRARY':
            os.path.join(
                GeosBuilder(recon).get_build_path(), 'lib', 'libgeos_c.so'),
            'EXPAT_INCLUDE_DIR':
            ExpatBuilder(recon).get_include_path(),
            'EXPAT_LIBRARY':
            os.path.join(
                ExpatBuilder(recon).get_build_path(), 'lib', 'libexpat.so'),
            'PROJ_INCLUDE_DIR':
            Proj4Builder(recon).get_include_path(),
            'PROJ_LIBRARY':
            os.path.join(
                Proj4Builder(recon).get_build_path(), 'lib', 'libproj.so'),
            'CHARSET_LIBRARY':
            os.path.join(
                LibiconvBuilder(recon).get_build_path(), 'lib',
                'libcharset.so'),
            'QWT_INCLUDE_DIR':
            QWTBuilder(recon).get_include_path(),
            'QWT_LIBRARY':
            os.path.join(
                QWTBuilder(recon).get_build_path(), 'libs', 'armeabi',
                'libqwt.a'),
            'QT_MOBILITY_INCLUDE_DIR':
            os.path.join(recon.qt_path, 'include', 'QtMobility'),
            'SQLITE3_LIBRARY':
            os.path.join(
                SQLiteBuilder(recon).get_build_path(), 'lib', 'libsqlite3.so'),
            'SQLITE3_INCLUDE_DIR':
            SQLiteBuilder(recon).get_include_path(),
            'SPATIALITE_LIBRARY':
            os.path.join(
                SpatialiteBuilder(recon).get_build_path(), 'lib',
                'libspatialite.so'),
            'SPATIALITE_INCLUDE_DIR':
            os.path.join(SpatialiteBuilder(recon).get_include_path()),
            'FLEX_EXECUTABLE':
            '/usr/bin/flex',
            'BISON_EXECUTABLE':
            '/usr/bin/bison',
            'SPATIALINDEX_INCLUDE_DIR':
            SpatialindexBuilder(recon).get_include_path(),
            'SPATIALINDEX_LIBRARY':
            os.path.join(
                SpatialindexBuilder(recon).get_build_path(), 'lib',
                'libspatialindex.so'),
            'NO_SWIG':
            'true',
            'PEDANTIC':
            'OFF',
            'WITH_APIDOC':
            'OFF',
            'WITH_DESKTOP':
            'OFF',
            'WITH_BINDINGS':
            'ON',
            'WITH_GLOBE':
            'OFF',
            'WITH_GRASS':
            'OFF',
            'WITH_INTERNAL_QWTPOLAR':
            'ON',
            'WITH_MAPSERVER':
            'OFF',
            'WITH_POSTGRESQL':
            'OFF',
            'WITH_SPATIALITE':
            'ON',
            'WITH_TXT2TAGS_PDF':
            'OFF',
            'WITH_QTMOBILITY':
            'ON',
            'WITH_PYSPATIALITE':
            'ON',
            'ENABLE_TESTS':
            'OFF',
            'BINDINGS_GLOBAL_INSTALL':
            'OFF',
            'PYTHON_EXECUTABLE':
            host_python_vars.python,
            '_find_sip_py':
            os.path.join(self.get_patch_path(), 'FindSIP.py'),
            '_find_lib_python_py':
            os.path.join(cmake_path, 'FindLibPython.py'),
            '_find_pyqt_py':
            os.path.join(self.get_patch_path(), 'FindPyQt.py'),
            '_python_compile_py':
            os.path.join(cmake_path, 'PythonCompile.py'),
            'PYTHON_LIBRARY':
            os.path.join(python_builder.get_output_library_path(),
                         'libpython2.7.so'),
            'PYUIC4_PROGRAM':
            os.path.join(host_python_vars.bin, 'pyuic4'),
            'PYRCC4_PROGRAM':
            os.path.join(host_python_vars.bin, 'pyrcc4')
        }

        # Need to prepend CMAKE_C(XX)_FLAGS to the already set flags
        self.sed_ie(
            '1iinclude_directories("%s")' % python_builder.get_include_path(),
            'CMakeLists.txt')
        self.sed_ie(
            '1iinclude_directories("%s")' %
            SQLiteBuilder(self.get_recon()).get_include_path(),
            'CMakeLists.txt')
        self.sed_ie(
            '1iinclude_directories("%s")' %
            SpatialiteBuilder(self.get_recon()).get_include_path(),
            'CMakeLists.txt')
        #self.sed_ie('s/ADD_SUBDIRECTORY(gui)//',
        #            os.path.join(self.get_current_source_path(),
        #                         'src', 'CMakeLists.txt'))
        #self.sed_ie('s|../gui||',
        #            os.path.join(self.get_current_source_path(),
        #                         'src', 'python', 'CMakeLists.txt'))
        #self.sed_ie('s/ADD_SIP_PYTHON_MODULE(qgis.gui.*$//',
        #            os.path.join(self.get_current_source_path(),
        #                         'python', 'CMakeLists.txt'))
        #self.sed_ie('s/ADD_SIP_PYTHON_MODULE(qgis.analysis.*$//',
        #            os.path.join(self.get_current_source_path(),
        #                         'python', 'CMakeLists.txt'))
        #self.sed_ie('s/ADD_SIP_PYTHON_MODULE(qgis.networkanalysis.*$//',
        #            os.path.join(self.get_current_source_path(),
        #                         'python', 'CMakeLists.txt'))

        # There appears not to be a good (sane) argument to have qgsapplication
        # exported as something instantiatable, as most likely, the
        # provider/plugin will not be at the wanted location.

        # The runtime catches this through specific configuration elements and
        # uses QApplication (which can be retrieved) as it's normal
        # instantiation routine.

        self.sed_ie(
            's/%Include qgsapplication.sip//',
            os.path.join(self.get_current_source_path(), 'python', 'core',
                         'core.sip'))

        # In order to fix a number of compilation problems due to unsupported
        # types, most likely "doubles".
        #
        # In ARM-Qt, these need to be "floats" and should be encoded as qreal

        self.sed_ie(
            's/void adjustBoxSize.*$//',
            os.path.join(self.get_current_source_path(), 'python', 'core',
                         'qgscomposerscalebar.sip'))
        self.sed_ie(
            's/void segmentPositions.*$//',
            os.path.join(self.get_current_source_path(), 'python', 'core',
                         'qgscomposerscalebar.sip'))
        self.sed_ie(
            's/^.*encodeRealVector.*$//',
            os.path.join(self.get_current_source_path(), 'python', 'core',
                         'symbology-ng-core.sip'))
        self.sed_ie(
            's/^.*decodeRealVector.*$//',
            os.path.join(self.get_current_source_path(), 'python', 'core',
                         'symbology-ng-core.sip'))

        self.sed_ie(
            's/^.*simpleMeasure.*$//',
            os.path.join(self.get_current_source_path(), 'python', 'analysis',
                         'qgsgeometryanalyzer.sip'))
        self.sed_ie(
            's/^.*perimeterMeasure.*$//',
            os.path.join(self.get_current_source_path(), 'python', 'analysis',
                         'qgsgeometryanalyzer.sip'))

        self.sed_i(
            '1i typedef qint64 Q_PID;',
            os.path.join(self.get_current_source_path(), 'python', 'core',
                         'core.sip'))

        # self.sed_ie('14,100d',
        #             os.path.join(self.get_current_source_path(),
        #                          'python', 'core', 'core.sip'))

        # self.sed_ie('8,2d',
        #             os.path.join(self.get_current_source_path(),
        #                          'python', 'core', 'core.sip'))

        # self.sed_ie('$a %Include qgsrect.sip',
        #             os.path.join(self.get_current_source_path(),
        #                          'python', 'core', 'core.sip'))
        # self.sed_ie('$a %Include qgspoint.sip',
        #             os.path.join(self.get_current_source_path(),
        #                          'python', 'core', 'core.sip'))

        #self.sed_ie('s/.*//',
        #            os.path.join(self.get_current_source_path(),
        #                         'python', 'analysis', 'analysis.sip'))

        #self.sed_ie('s/.*//',
        #            os.path.join(self.get_current_source_path(),
        #                         'python', 'analysis', 'network', 'networkanalysis.sip'))

        os.remove(
            os.path.join(self.get_current_source_path(), 'python', 'core',
                         'qgsapplication.sip'))

        #self.sed_ie('s/LINK_DIRECTORIES\(${CMAKE_BINARY_DIR}/src/core "\n', 'CMakeLists.txt')

        #os.rename(os.path.join(self.get_current_source_path(), 'src', 'gui'),
        #          os.path.join(self.get_current_source_path(), 'src', 'nogui'))
        args = ['cmake']
        for arg in arguments:
            args.extend(['-D' + arg + '=' + arguments[arg]])
        args.extend(['.'])
        process = subprocess.Popen(args,
                                   cwd=self.get_current_source_path(),
                                   env=our_env)
        process.communicate(None)
        if process.returncode != 0:
            raise ValueError("Failed Process:", args[0])
        cpuflag = '-j' + str(multiprocessing.cpu_count())
        process = subprocess.Popen(['make', 'VERBOSE=1', cpuflag, 'install'],
                                   cwd=self.get_current_source_path(),
                                   env=our_env)
        process.communicate(None)
        if process.returncode != 0:
            raise ValueError("Failed Process:", args[0])
        print 'Done building QGis Base'

        distutils.dir_util.copy_tree(
            os.path.join(self.get_build_path(), 'include'),
            os.path.join(self.get_include_path()))

        self.sed_i(
            's/typedef qint64 Q_PID;//',
            os.path.join(self.get_current_source_path(), 'python', 'core',
                         'core.sip'))

        self.mark_finished()
    def do_build(self):
        """ Runs the actual build process """
        # Downloading qgis is a big process. We escape to another directory
        # and see if it is downloaded already
        output = self.do_download_cache()
        
        # Unpack again for the target build
        self.unpack(output)

        # We need qgis both on the base system as well as the target systen
        self.push_current_source_path(os.path.join(self.get_source_path(), 
                                                   self.library_name()))

        self.do_target_patches()
        recon = self.get_recon()

        # QGis uses (as only library in this whole project) cmake. We need to set up a number
        # of things for this.
        
        our_env = dict(os.environ).copy()
        our_env['QT_ROOT'] = recon.qt_path
        our_env['ANDROID_LEVEL'] = str(recon.android_level)
        our_env['ANDROID_NDK_PLATFORM'] = 'android-' + str(recon.android_level)
        our_env['ANDROID_NDK_TOOLCHAIN_ROOT'] = recon.get_toolchain_path()
        our_env['ANDROID_NDK_HOST'] = 'linux-x86'
        our_env['ANDROID_NDK_TOOLCHAIN_PREFIX'] = 'arm-linux-androideabi'
        our_env['ANDROID_NDK_TOOLCHAIN_VERSION'] = '4.4.3'
        our_env['QT_INCLUDE_DIR'] = os.path.join(our_env['QT_ROOT'], 'include')
        our_env['QT_LIBRARY_DIR'] = os.path.join(our_env['QT_ROOT'], 'lib')
        our_env['QMAKE'] = os.path.join(recon.qt_tools_path, 'qmake')
        our_env['PATH'] = self.get_path()
        our_env['INSTALL_DIR'] = self.get_build_path()
        
        # We need to add some definitions
        self.add_definitions()

        self.sed_i('s/SPATIALITE_INCLUDE_DIR/\\SPATIALITE_INCLUDE_DIR\\} \\$\\{SQLITE3_INCLUDE_DIR/',
                   'src/providers/spatialite/CMakeLists.txt')
        
        # Do the argument dance
        toolchain_src = os.path.join(self.get_core_patch_path(), 
                                     'cmake', 'android.toolchain.cmake')
        toolchain_file = os.path.join(self.get_current_source_path(), 
                                      'android.toolchain.cmake')
        shutil.copyfile(toolchain_src, toolchain_file)
        
        python_builder = PythonBuilder(self.get_recon())
        host_python_vars = python_builder.get_host_python_vars()
        cmake_path = os.path.join(self.get_current_source_path(), 'cmake')
        python_syspath = os.path.join(python_builder.get_host_python_prefix(),
                                      'site-packages')
        our_env["PYTHONPATH"] = python_syspath
        our_env['PATH'] = os.pathsep.join([host_python_vars.bin, our_env['PATH']])
        

        arguments = { 'ANDROID'              : 'true',
                      'ARM_TARGET'           : 'armeabi',
                      'CMAKE_INSTALL_PREFIX' : self.get_build_path(),
                      'CMAKE_TOOLCHAIN_FILE' : toolchain_file,
                      'QT_MKSPECS_DIR'       : os.path.join(recon.qt_path, 'mkspecs'),
                      'QT_QMAKE_EXECUTABLE'  : os.path.join(recon.qt_tools_path, 'qmake'),
                      'GDAL_CONFIG'          : os.path.join(GDALBuilder(recon).get_build_path(),
                                                            'bin', 'gdal-config'),
                      'GDAL_INCLUDE_DIR'     : GDALBuilder(recon).get_include_path(),
                      'GDAL_LIBRARY'         : os.path.join(GDALBuilder(recon).get_build_path(),
                                                            'lib', 'libgdal.so'),
                      'GEOS_CONFIG'          : os.path.join(GeosBuilder(recon).get_build_path(),
                                                            'bin', 'geos-config'),
                      'GEOS_INCLUDE_DIR'     : GeosBuilder(recon).get_include_path(),
                      'GEOS_LIBRARY'         : os.path.join(GeosBuilder(recon).get_build_path(),
                                                            'lib', 'libgeos_c.so'),
                      'EXPAT_INCLUDE_DIR'    : ExpatBuilder(recon).get_include_path(),
                      'EXPAT_LIBRARY'        : os.path.join(ExpatBuilder(recon).get_build_path(),
                                                            'lib', 'libexpat.so'),
                      'PROJ_INCLUDE_DIR'     : Proj4Builder(recon).get_include_path(),
                      'PROJ_LIBRARY'         : os.path.join(Proj4Builder(recon).get_build_path(),
                                                            'lib', 'libproj.so'),
                      'QWT_INCLUDE_DIR'      : QWTBuilder(recon).get_include_path(),
                      'QWT_LIBRARY'          : os.path.join(QWTBuilder(recon).get_build_path(),
                                                            'libs', 'armeabi', 'libqwt.a'),
                      'QT_MOBILITY_INCLUDE_DIR' : os.path.join(recon.qt_path, 'include',
                                                               'QtMobility'),
                      'SQLITE3_LIBRARY'      : os.path.join(SQLiteBuilder(recon).get_build_path(),
                                                            'lib', 'libsqlite3.so'),
                      'SQLITE3_INCLUDE_DIR'  : SQLiteBuilder(recon).get_include_path(),
                      'SPATIALITE_LIBRARY'   : os.path.join(SpatialiteBuilder(recon).get_build_path(),
                                                            'lib', 'libspatialite.so'),
                      'SPATIALITE_INCLUDE_DIR'   : os.path.join(SpatialiteBuilder(
                          recon).get_include_path()),
                      'FLEX_EXECUTABLE'      : '/usr/bin/flex',
                      'BISON_EXECUTABLE'     : '/usr/bin/bison',
                      'SPATIALINDEX_INCLUDE_DIR' : SpatialindexBuilder(recon).get_include_path(),
                      'SPATIALINDEX_LIBRARY' :  os.path.join(SpatialindexBuilder(recon).get_build_path(),
                                                             'lib', 'libspatialindex.so'),
                      'NO_SWIG' : 'true', 
                      'PEDANTIC' : 'OFF',
                      'WITH_APIDOC' : 'OFF',
                      'WITH_DESKTOP' : 'OFF',
                      'WITH_BINDINGS' : 'ON',
                      'WITH_GLOBE' : 'OFF',
                      'WITH_GRASS' : 'OFF',
                      'WITH_INTERNAL_QWTPOLAR' : 'ON',
                      'WITH_MAPSERVER' : 'OFF',
                      'WITH_POSTGRESQL' : 'OFF',
                      'WITH_SPATIALITE' : 'ON',
                      'WITH_TXT2TAGS_PDF' : 'OFF',
                      'WITH_QTMOBILITY' : 'ON',
                      'WITH_PYSPATIALITE' : 'ON',
                      'ENABLE_TESTS' : 'OFF',
                      'BINDINGS_GLOBAL_INSTALL' : 'OFF',
                      'PYTHON_EXECUTABLE' : host_python_vars.python,
                      '_find_sip_py' : os.path.join(self.get_patch_path(), 'FindSIP.py'),
                      '_find_lib_python_py' : os.path.join(cmake_path, 'FindLibPython.py'),
                      '_find_pyqt_py' : os.path.join(self.get_patch_path(), 'FindPyQt.py'),
                      '_python_compile_py' : os.path.join(cmake_path, 'PythonCompile.py'),
                      'PYTHON_LIBRARY' : os.path.join(python_builder.get_output_library_path(),
                                                      'libpython2.7.so'),
                      'PYUIC4_PROGRAM' : os.path.join(host_python_vars.bin, 'pyuic4'),
                      'PYRCC4_PROGRAM' : os.path.join(host_python_vars.bin, 'pyrcc4')}

        # Need to prepend CMAKE_C(XX)_FLAGS to the already set flags
        self.sed_ie('1iinclude_directories("%s")' % 
                   python_builder.get_include_path(), 'CMakeLists.txt')
        self.sed_ie('1iinclude_directories("%s")' % 
                   SQLiteBuilder(self.get_recon()).get_include_path(), 'CMakeLists.txt')
        self.sed_ie('1iinclude_directories("%s")' % 
                   SpatialiteBuilder(self.get_recon()).get_include_path(), 'CMakeLists.txt')

        # There appears not to be a good (sane) argument to have qgsapplication
        # exported as something instantiatable, as most likely, the 
        # provider/plugin will not be at the wanted location.

        # The runtime catches this through specific configuration elements and
        # uses QApplication (which can be retrieved) as it's normal 
        # instantiation routine.

        self.sed_ie('s/%Include qgsapplication.sip//',
                    os.path.join(self.get_current_source_path(), 
                                 'python', 'core', 'core.sip'))

        # In order to fix a number of compilation problems due to unsupported 
        # types, most likely "doubles".
        #
        # In ARM-Qt, these need to be "floats" and should be encoded as qreal

        self.sed_ie('s/void adjustBoxSize.*$//',
                    os.path.join(self.get_current_source_path(), 
                                 'python', 'core', 'qgscomposerscalebar.sip'))
        self.sed_ie('s/void segmentPositions.*$//',
                    os.path.join(self.get_current_source_path(), 
                                 'python', 'core', 'qgscomposerscalebar.sip'))
        self.sed_ie('s/^.*encodeRealVector.*$//',
                    os.path.join(self.get_current_source_path(), 
                                 'python', 'core', 'symbology-ng-core.sip'))
        self.sed_ie('s/^.*decodeRealVector.*$//',
                    os.path.join(self.get_current_source_path(), 
                                 'python', 'core', 'symbology-ng-core.sip'))


        self.sed_ie('s/^.*simpleMeasure.*$//',
                    os.path.join(self.get_current_source_path(), 
                                 'python', 'analysis', 'qgsgeometryanalyzer.sip'))
        self.sed_ie('s/^.*perimeterMeasure.*$//',
                    os.path.join(self.get_current_source_path(), 
                                 'python', 'analysis', 'qgsgeometryanalyzer.sip'))

        self.sed_i('1i typedef qint64 Q_PID;',
                   os.path.join(self.get_current_source_path(), 
                                'python', 'core', 'core.sip'))
        

        os.remove(os.path.join(self.get_current_source_path(), 
                                 'python', 'core', 'qgsapplication.sip'))



        # Need to remove Q_PID declaration in the source files temporarily
        qprocess_sip_path = os.path.join(
            PyQtBuilder(self.get_recon()).get_build_path(),
            'share', 'sip', 'QtCore', 'qprocess.sip')            

        try:
            self.sed_ir('s|typedef qint64 Q_PID;|//typedef qint64 Q_PID;|',
                        qprocess_sip_path)
            args = ['cmake']        
            for arg in arguments:
                args.extend(['-D' + arg + '=' + arguments[arg]])
            args.extend(['.'])
            process = subprocess.Popen(args, cwd=self.get_current_source_path(), env=our_env)
            process.communicate(None)
            if process.returncode != 0:
                raise ValueError("Failed Process:", args[0])
            cpuflag = '-j' + str(multiprocessing.cpu_count())
            process = subprocess.Popen(['make',
                                        'VERBOSE=1', cpuflag, 'install'],
                                       cwd=self.get_current_source_path(), env=our_env)
            process.communicate(None)
            if process.returncode != 0:
                raise ValueError("Failed Process:", args[0])
            print 'Done building QGis Base'
        
            distutils.dir_util.copy_tree(os.path.join(self.get_build_path(), 'include'),
                                         os.path.join(self.get_include_path()))
        
            self.sed_i('s/typedef qint64 Q_PID;//',
                       os.path.join(self.get_current_source_path(), 
                                    'python', 'core', 'core.sip'))
        finally:
            self.sed_ir('s|//typedef qint64 Q_PID;|typedef qint64 Q_PID;|',
                        qprocess_sip_path)
        
        self.mark_finished()