Cross Compiling: Difference between revisions
No edit summary  | 
				No edit summary  | 
				||
| Line 5: | Line 5: | ||
** for cmake, you typically need a toolchain file to specify details  | ** for cmake, you typically need a toolchain file to specify details  | ||
* need to cross compile any dependencies (static link what you can)  | * need to cross compile any dependencies (static link what you can)  | ||
* need to match the libraries on target machine for any dynamic linking requirements  | |||
* need to match the build to the target kernel (or you might get "kernel too old")  | |||
{| class="mw-collapsible mw-collapsed wikitable"  | {| class="mw-collapsible mw-collapsed wikitable"  | ||
! libz example  | ! libz example  | ||
| Line 53: | Line 56: | ||
     fi  |      fi  | ||
|}  | |}  | ||
**   | {| class="mw-collapsible mw-collapsed wikitable"  | ||
*   | ! multi-lib complete example  | ||
*   | |-  | ||
|   | |||
    # Cross compile env for armv4 chipset   | |||
    # Conel cellular modem (Verizon/Pogens)  | |||
    # ARM 926EJ-S processor  | |||
    # Using toolchain on vpn.causam.com that was built a while ago by Bryan G. with Crosstool-NG 1.20.0  | |||
    # We will cross compile these libraries:  | |||
    # zlib for compression  | |||
    # openssl for encryption - NOTE that it is considered unsafe to bake zlib directly into openssl  | |||
    # libwebsockets for wss  | |||
    # LIB VERSIONS: No reason I know of not to use the latest  | |||
    # It's just that the versions are needed in the script  | |||
    zlib_version=1.2.8     # see http://www.zlib.net/  | |||
    openssl_version=1.1.0c # see https://www.openssl.org/source/  | |||
    lws_branch=v2.0-stable  | |||
    # Turn this on at least at the first run, again as needed.  | |||
    rebuild_libs=true  | |||
    # ==========================================  | |||
    # cross compile toolchain magic happens here  | |||
    # ==========================================  | |||
    nickname=armv4  | |||
    # We will use a cross-compile toolchain that was built a while ago by Bryan G. with Crosstool-NG 1.20.0  | |||
    # We will build on an older machine (vpn.causam.com) since this did not seem to help limit the kernel: --enable-kernel=${max_kernel}  | |||
    if [ ! -d /opt/crosstool-source-v4 ]; then  | |||
        echo "Cross-compile toolchain not found..."  | |||
        kill -SIGINT $$;  | |||
    fi  | |||
    export cross=arm-926ejs-linux-gnueabi-  | |||
    CC=${cross}gcc  | |||
    CMAKE_TOOLCHAIN_FILE=/home/m/development/causam/git/np/nop-bigress-client-c/${nickname}/toolchain.cmake  | |||
    export PATH=/opt/crosstool-source-v4/arm-926ejs-linux-gnueabi/bin:${PATH}  | |||
    export install_root=/home/m/development/${nickname}  | |||
    # ==========================================  | |||
    echo Getting source code for libraries...  | |||
    cd ${install_root}/source  | |||
    if [ ! -d zlib ]; then  | |||
        wget http://zlib.net/zlib-${zlib_version}.tar.gz  | |||
        tar -xzvf zlib-${zlib_version}.tar.gz  | |||
        ln -s zlib-${zlib_version} zlib  | |||
    fi  | |||
    if [ ! -d openssl ]; then  | |||
        wget https://www.openssl.org/source/openssl-${openssl_version}.tar.gz  | |||
        tar -xzvf openssl-${openssl_version}.tar.gz  | |||
        ln -s openssl-${openssl_version} openssl  | |||
    fi  | |||
    if [ ! -d libwebsockets ]; then  | |||
        git clone https://github.com/warmcat/libwebsockets.git  | |||
        cd libwebsockets  | |||
        git checkout ${lws_branch}  | |||
        cd ..  | |||
    fi  | |||
    echo Building libraries...  | |||
    if [ "$rebuild_libs" = true ]; then  | |||
        # Good help: http://stackoverflow.com/questions/11841919/cross-compile-openssh-for-arm  | |||
        # BUT full of landmines...      | |||
        # Use [file ##.so.##] or [file executable] to find out the architecture of an asset.  | |||
        # ZLIB  | |||
        # THIS IS EXTREMELY BRITTLE, do not adjust  | |||
        # THIS DOES NOT USE 'ar r', IT USES 'ar', BUT OPENSSL WILL USE 'ar r'  | |||
        # Make sure we build static  | |||
        # NOTE the global CC define WILL NOT WORK HERE, use this CC define specifically or it WILL BREAK  | |||
        cd zlib  | |||
        CC="${cross}gcc" AR="${cross}ar" RANLIB="${cross}ranlib" ./configure --static --prefix=${install_root}  | |||
        make clean  | |||
        make  | |||
        make install  | |||
        cd ..  | |||
        # OPENSSL  | |||
        # THIS IS EXTREMELY BRITTLE, do not adjust  | |||
        cd openssl  | |||
        ./Configure dist --prefix=${install_root} --openssldir=${install_root}  | |||
        make clean  | |||
        make CC="${cross}gcc" AR="${cross}ar r" RANLIB="${cross}ranlib"  | |||
        make install  | |||
        cd ..  | |||
        # LIBWEBSOCKETS  | |||
        # NOTE: we basically need most lws features, with the exception of PLUGINS support.  | |||
        cd libwebsockets  | |||
        git pull  | |||
        mkdir -p cmake-${nickname}-release  | |||
        cd cmake-${nickname}-release  | |||
        rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake *.cpb Makefile  | |||
        cmake -static \  | |||
            -DCMAKE_INSTALL_PREFIX:PATH=${install_root}         \  | |||
            -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}      \  | |||
            -DZLIB_LIBRARY=${install_root}/lib                  \  | |||
            -DZLIB_INCLUDE_DIR=${install_root}/include          \  | |||
            -DLWS_OPENSSL_LIBRARIES=${install_root}/lib         \  | |||
            -DLWS_OPENSSL_INCLUDE_DIRS=${install_root}/include  \  | |||
            -DLWS_WITH_SHARED=OFF           \  | |||
            -DLWS_WITHOUT_TESTAPPS=1        \  | |||
            -DLWS_WITH_SSL=1                \  | |||
            -DLWS_WITH_ZLIB=1               \  | |||
            -DLWS_WITHOUT_EXTENSIONS=0      \  | |||
            -DLWS_HAVE_SSL_CTX_set1_param=1 \  | |||
            -DLWS_WITHOUT_DAEMONIZE=0       \  | |||
            -DLWS_WITHOUT_SERVER=1          \  | |||
            -DLWS_MAX_SMP=4                 \  | |||
            ..  | |||
        make  | |||
        make install  | |||
        cd ../..  | |||
    fi  | |||
    echo =========================================================  | |||
    echo Cross-compiled libraries have been built here [${install_root}/lib]:  | |||
    echo =========================================================  | |||
    ls -la ${install_root}/lib  | |||
    echo =========================================================  | |||
    echo Copy nop-client source and toolchain CMakeLists.txt...  | |||
    mkdir -p nop-client  | |||
    cp -rp /home/m/development/causam/git/np/nop-bigress-client-c/* nop-client/  | |||
    cp -rp /home/m/development/causam/git/np/nop-bigress-client-c/${nickname}/CMakeLists.txt nop-client/  | |||
    cd nop-client  | |||
    mkdir -p cmake-${nickname}-release  | |||
    cd cmake-${nickname}-release  | |||
    echo Building nop-client...  | |||
    rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake *.cpb Makefile  | |||
    cmake -static \  | |||
        -DCMAKE_INSTALL_PREFIX:PATH=${install_root}         \  | |||
        -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}      \  | |||
        ..  | |||
    make  | |||
    echo =========================================================  | |||
    echo Binary details of build...  | |||
    echo =========================================================  | |||
    file nop-client  | |||
    echo =========================================================  | |||
    echo Copying to remote device...  | |||
    ssh -p 2222 [email protected] "cat > nop-client-${nickname}" < nop-client  | |||
    ssh -p 2222 [email protected] "chmod a+x nop-client-${nickname}"  | |||
    # Here are some other remote commands  | |||
    #  | |||
    # rm the bin (had to do this when cp failed due to lack of space on device)  | |||
    # ssh -p 2222 [email protected] "rm nop-client-${nickname}"  | |||
    #  | |||
    # cp FROM the device back to host (again, to clean space on device)  | |||
    # ssh -p 2222 [email protected] "cat nop-client.0" > nop-client.0  | |||
|}  | |||
{| class="mw-collapsible mw-collapsed wikitable"  | |||
! cmake toolchain file example  | |||
|-  | |||
|   | |||
    # https://github.com/zyga/cmake-toolchains/blob/master/Toolchain-Ubuntu-gnueabi.cmake  | |||
    # Sample toolchain file for building for ARM from an Ubuntu Linux system.  | |||
    #  | |||
    # Typical usage:  | |||
    #    *) install cross compiler: `sudo apt-get install gcc-arm-linux-gnueabi`  | |||
    #    *) cd build  | |||
    #    *) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-gnueabi.cmake ..  | |||
    set(CMAKE_SYSTEM_NAME Linux)  | |||
    set(TOOLCHAIN_PREFIX arm-926ejs-linux-gnueabi)  | |||
    # cross compilers to use for C and C++  | |||
    set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)  | |||
    set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)  | |||
    # target environment on the build host system  | |||
    #   set 1st to dir with the cross compiler's C/C++ headers/libs  | |||
    set(CMAKE_FIND_ROOT_PATH /opt/crosstool-source-v4/arm-926ejs-linux-gnueabi)  | |||
    # modify default behavior of FIND_XXX() commands to  | |||
    # search for headers/libs in the target environment and  | |||
    # search for programs in the build host environment  | |||
    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)  | |||
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)  | |||
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)  | |||
|}  | |||
Revision as of 20:00, 29 November 2016
Issues:
- need cross compile toolchain
- you need to find or build an entire toolchain environment; ubuntu has some, others have some, Crosstool-NG will build one from scratch
 - for autotools, you typically need to define tools like ar, gcc, g++ in the build script
 - for cmake, you typically need a toolchain file to specify details
 
 - need to cross compile any dependencies (static link what you can)
 - need to match the libraries on target machine for any dynamic linking requirements
 - need to match the build to the target kernel (or you might get "kernel too old")
 
| libz example | 
|---|
   echo Getting source code for libraries...
   if [ ! -d zlib ]; then
       wget http://zlib.net/zlib-${zlib_version}.tar.gz
       untar zlib-${zlib_version}.tar.gz
       ln -s zlib-${zlib_version} zlib
   fi
   echo Building libraries...
   if [ "$rebuild_libs" = true ]; then
   
       export cross=arm-linux-gnueabi-
   
       # ZLIB
       cd zlib
       ./configure --prefix=${install_root}
       make CC="${cross}gcc" AR="${cross}ar r" RANLIB="${cross}ranlib"
       make install
       cd ..
   fi
 | 
| openssl example | 
|---|
   echo Getting source code for libraries...
   if [ ! -d openssl ]; then
       wget https://www.openssl.org/source/openssl-${openssl_version}.tar.gz
       untar openssl-${openssl_version}.tar.gz
       ln -s openssl-${openssl_version} openssl
   fi
   
   echo Building libraries...
   
   if [ "$rebuild_libs" = true ]; then
   
       export cross=arm-linux-gnueabi-
   
       # OPENSSL
       cd openssl
       ./Configure dist --prefix=${install_root} --openssldir=${install_root}
       make CC="${cross}gcc" AR="${cross}ar r" RANLIB="${cross}ranlib"
       make install
       cd ..
   fi
 | 
| multi-lib complete example | 
|---|
# Cross compile env for armv4 chipset # Conel cellular modem (Verizon/Pogens) # ARM 926EJ-S processor # Using toolchain on vpn.causam.com that was built a while ago by Bryan G. with Crosstool-NG 1.20.0 # We will cross compile these libraries: # zlib for compression # openssl for encryption - NOTE that it is considered unsafe to bake zlib directly into openssl # libwebsockets for wss # LIB VERSIONS: No reason I know of not to use the latest # It's just that the versions are needed in the script zlib_version=1.2.8 # see http://www.zlib.net/ openssl_version=1.1.0c # see https://www.openssl.org/source/ lws_branch=v2.0-stable # Turn this on at least at the first run, again as needed. rebuild_libs=true # ========================================== # cross compile toolchain magic happens here # ========================================== nickname=armv4 # We will use a cross-compile toolchain that was built a while ago by Bryan G. with Crosstool-NG 1.20.0 # We will build on an older machine (vpn.causam.com) since this did not seem to help limit the kernel: --enable-kernel=${max_kernel} if [ ! -d /opt/crosstool-source-v4 ]; then echo "Cross-compile toolchain not found..." kill -SIGINT $$; fi export cross=arm-926ejs-linux-gnueabi- CC=${cross}gcc CMAKE_TOOLCHAIN_FILE=/home/m/development/causam/git/np/nop-bigress-client-c/${nickname}/toolchain.cmake export PATH=/opt/crosstool-source-v4/arm-926ejs-linux-gnueabi/bin:${PATH} export install_root=/home/m/development/${nickname} # ========================================== echo Getting source code for libraries... cd ${install_root}/source if [ ! -d zlib ]; then wget http://zlib.net/zlib-${zlib_version}.tar.gz tar -xzvf zlib-${zlib_version}.tar.gz ln -s zlib-${zlib_version} zlib fi if [ ! -d openssl ]; then wget https://www.openssl.org/source/openssl-${openssl_version}.tar.gz tar -xzvf openssl-${openssl_version}.tar.gz ln -s openssl-${openssl_version} openssl fi if [ ! -d libwebsockets ]; then git clone https://github.com/warmcat/libwebsockets.git cd libwebsockets git checkout ${lws_branch} cd .. fi echo Building libraries... if [ "$rebuild_libs" = true ]; then # Good help: http://stackoverflow.com/questions/11841919/cross-compile-openssh-for-arm # BUT full of landmines... # Use [file ##.so.##] or [file executable] to find out the architecture of an asset. # ZLIB # THIS IS EXTREMELY BRITTLE, do not adjust # THIS DOES NOT USE 'ar r', IT USES 'ar', BUT OPENSSL WILL USE 'ar r' # Make sure we build static # NOTE the global CC define WILL NOT WORK HERE, use this CC define specifically or it WILL BREAK cd zlib CC="${cross}gcc" AR="${cross}ar" RANLIB="${cross}ranlib" ./configure --static --prefix=${install_root} make clean make make install cd .. # OPENSSL # THIS IS EXTREMELY BRITTLE, do not adjust cd openssl ./Configure dist --prefix=${install_root} --openssldir=${install_root} make clean make CC="${cross}gcc" AR="${cross}ar r" RANLIB="${cross}ranlib" make install cd .. # LIBWEBSOCKETS # NOTE: we basically need most lws features, with the exception of PLUGINS support. cd libwebsockets git pull mkdir -p cmake-${nickname}-release cd cmake-${nickname}-release rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake *.cpb Makefile cmake -static \ -DCMAKE_INSTALL_PREFIX:PATH=${install_root} \ -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} \ -DZLIB_LIBRARY=${install_root}/lib \ -DZLIB_INCLUDE_DIR=${install_root}/include \ -DLWS_OPENSSL_LIBRARIES=${install_root}/lib \ -DLWS_OPENSSL_INCLUDE_DIRS=${install_root}/include \ -DLWS_WITH_SHARED=OFF \ -DLWS_WITHOUT_TESTAPPS=1 \ -DLWS_WITH_SSL=1 \ -DLWS_WITH_ZLIB=1 \ -DLWS_WITHOUT_EXTENSIONS=0 \ -DLWS_HAVE_SSL_CTX_set1_param=1 \ -DLWS_WITHOUT_DAEMONIZE=0 \ -DLWS_WITHOUT_SERVER=1 \ -DLWS_MAX_SMP=4 \ .. make make install cd ../.. fi echo ========================================================= echo Cross-compiled libraries have been built here [${install_root}/lib]: echo ========================================================= ls -la ${install_root}/lib echo ========================================================= echo Copy nop-client source and toolchain CMakeLists.txt... mkdir -p nop-client cp -rp /home/m/development/causam/git/np/nop-bigress-client-c/* nop-client/ cp -rp /home/m/development/causam/git/np/nop-bigress-client-c/${nickname}/CMakeLists.txt nop-client/ cd nop-client mkdir -p cmake-${nickname}-release cd cmake-${nickname}-release echo Building nop-client... rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake *.cpb Makefile cmake -static \ -DCMAKE_INSTALL_PREFIX:PATH=${install_root} \ -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} \ .. make echo ========================================================= echo Binary details of build... echo ========================================================= file nop-client echo ========================================================= echo Copying to remote device... ssh -p 2222 [email protected] "cat > nop-client-${nickname}" < nop-client ssh -p 2222 [email protected] "chmod a+x nop-client-${nickname}" # Here are some other remote commands # # rm the bin (had to do this when cp failed due to lack of space on device) # ssh -p 2222 [email protected] "rm nop-client-${nickname}" # # cp FROM the device back to host (again, to clean space on device) # ssh -p 2222 [email protected] "cat nop-client.0" > nop-client.0  | 
| cmake toolchain file example | 
|---|
# https://github.com/zyga/cmake-toolchains/blob/master/Toolchain-Ubuntu-gnueabi.cmake # Sample toolchain file for building for ARM from an Ubuntu Linux system. # # Typical usage: # *) install cross compiler: `sudo apt-get install gcc-arm-linux-gnueabi` # *) cd build # *) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-gnueabi.cmake .. set(CMAKE_SYSTEM_NAME Linux) set(TOOLCHAIN_PREFIX arm-926ejs-linux-gnueabi) # cross compilers to use for C and C++ set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) # target environment on the build host system # set 1st to dir with the cross compiler's C/C++ headers/libs set(CMAKE_FIND_ROOT_PATH /opt/crosstool-source-v4/arm-926ejs-linux-gnueabi) # modify default behavior of FIND_XXX() commands to # search for headers/libs in the target environment and # search for programs in the build host environment set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)  |