How to build a package in ubuntu of the same version, but for a different architecture using the cross-compiler arm-linux-gnueabihf-gcc? How to modify the Makefile to call the cross compiler instead of the usual one?

    1 answer 1

    To build packages in Debian, there is a stack of utilities (each of which calls the following lower level):

    • pdebuild
    • pbuilder
    • apt-get, debuild
    • dpkg-buildpackage
    • dpkg-architecture, fakeroot, debian / rules
    • dh, dh _...
    • make, strip, dpkg-deb

    The top four levels allow you to specify the target architecture in the launch arguments. Lower levels take this information from environment variables. The first two collect packets in an isolated environment to verify that all build dependencies are specified. They require a lot of disk memory and time to prepare the environment, they should be used before releasing your package for general use. For internal use, dpkg-buildpackage probably best suited. Run from the source directory of the package (the one in which the debian subdirectory is located):

     dpkg-buildpackage -a armhf 

    You can also use debuild:

     debuild -a armhf 

    For a successful build this may not be enough. You must specify the correct compiler. For this, you can use the CC variable. As I spied in the /usr/share/perl5/Debian/Debhelper/Dh_Lib.pm module and the dh_strip program, the environment variable DEB_HOST_GNU_TYPE is used to determine the prefix of the compilation utilities, if not, it is not used. So we need to put either a debian/rules or a line in the first level Makefile :

     export CC=$(DEB_HOST_GNU_TYPE)-gcc 

    Similarly for C ++:

     export CXX=$(DEB_HOST_GNU_TYPE)-g++ 

    If the build process requires a native compiler to compile a preprocessor, etc., you need to return the variable to the old state (gcc / g ++) for specific files or directories. If the package uses qmake, cmake or autoconf, all this should be done automatically, but it does not always work.

    Separate consideration costs cross-compilation of libraries and dependent packages.

    Assembly dependencies

    dpkg-buildpackage and higher-level build utilities check the dependencies specified in the Build-Depends: line of the debian / control file, which can be disabled with the -d option.

    For a package to satisfy a dependency, it must either be architecture independent ( Architecture: all ), or a matching architecture (which is suitable for libraries and not suitable if its binary file is to be executed during the build process), or have the Multi-Arch: foreign property, which must be in his control file. A more complicated variant is also possible, which is used for interpreters with plug-ins in the form of dynamically loaded libraries as perl or python: in the dependent package in Build-Depends after the package name is added :any , and in the satisfying dependency the string Multi-Arch: allowed is written.

    The latter method allows you to present two variants of package requirements: without :any - you need your own architecture (we are going to link our program with the file from this package, for example, we use our own plugin) - it’s most likely not suitable for cross-assembling, since such packages are not can be installed simultaneously two architectures, this option is usually used in dependencies during installation; c :any - any (just going to run the interpreter).

    Except :any in dependencies :native suffix is ​​also possible :native , meaning that the package of the architecture on which the build is made (builder) is required. This suffix for some reason does not satisfy packages with Multi-Arch: foreign or Architecture: all , a package without Multi-Arch , or with Multi-Arch: same or Multi-Arch: allowed .

    Libraries

    If your build package uses the library, the best option is if its package has the Multi-Arch: same property. This means that it will be possible to install the same packages simultaneously under several different architectures. Library files in such packages are located in different directories depending on the architecture. Those. instead of the old path /lib/ use /lib/arm-linux-gnueabihf/ or /lib/i386-linux-gnu/ . The names of these subdirectories when building library packages should be taken from the variable DEB_HOST_MULTIARCH (which may differ from DEB_HOST_GNU_TYPE ). The remaining files may be the same, but must then be identical. The versions of the packages to be installed must also be the same . The dependent package in Build-Depends simply indicates the name of the library package.

    Otherwise, the required library of a foreign architecture during the installation replaces the native library, which leads to the removal of all dependent packages of the native architecture.

    If you use dpkg-buildpackage (or a higher level utility) to build, the DEB _... variables are determined automatically. If you call fakeroot debian/rules binary directly, these variables are not defined. You can find out their standard values ​​for your system using the commands:

     dpkg-architecture -qDEB_HOST_MULTIARCH dpkg-architecture -qDEB_HOST_GNU_TYPE 

    For another architecture, add the -a option, for example -a armhf .

    Installing libraries of foreign architecture

    When installing, two problems appear: the library is not adapted to multi-architecture, or the latest versions of libraries are different in different architecture repositories. In the second case, apt-get gives an error like "broken packages" or, as in the first case, it offers to remove a lot of necessary packages from the system. In the first case, you need to redo the package, as described above, in the second case, downgrading can help, i.e. explicitly indicate the version of the package that is for both architectures, for example:

     # apt-get install linux-libc-dev:armhf=3.19.0-68.76 linux-libc-dev:i386=3.19.0-68.76