From 8da40ce09b485db40f469912438705bf53fb398a Mon Sep 17 00:00:00 2001 From: SaeHie Park Date: Mon, 30 Apr 2018 14:20:23 +0900 Subject: [PATCH] Enable arm cross building (#56) This will enable cross building for ARM - Tested with Raspberry Pi 3 with rpi SDL backend --- CMakeLists.txt | 19 +++++++++++++++---- README.md | 20 ++++++++++++++++++++ build.py | 25 +++++++++++++++++++++---- cmake/armv7l_settings.cmake | 36 ++++++++++++++++++++++++++++++++++++ cmake/toolchain-armv7l.cmake | 24 ++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 cmake/armv7l_settings.cmake create mode 100644 cmake/toolchain-armv7l.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index b0fecae..bcd21cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,11 +22,22 @@ elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC") endif() endif() +set(BUILD_NATIVE True) +if(DEFINED ROOTFS_ARM) + set(BUILD_NATIVE False) +endif() + # Look up required packages and add the include directory to our include path -find_package(Boost 1.55.0 COMPONENTS filesystem system REQUIRED) -find_package(SDL2 REQUIRED) -find_package(SDL2_ttf REQUIRED) -find_package(Lua REQUIRED) +if(BUILD_NATIVE) + find_package(Boost 1.55.0 COMPONENTS filesystem system REQUIRED) + find_package(SDL2 REQUIRED) + find_package(SDL2_ttf REQUIRED) + find_package(Lua REQUIRED) +else() + if (DEFINED ROOTFS_ARM) + include("cmake/armv7l_settings.cmake") + endif() +endif() include_directories(${Boost_INCLUDE_DIR}) include_directories(${SDL2_INCLUDE_DIR}) include_directories(${SDL2_TTF_INCLUDE_DIR}) diff --git a/README.md b/README.md index cb091cf..6b277af 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,26 @@ $ docker build -t {image_tag_name} docker $ docker run --rm -v `pwd`:{mount_path_on_container} -w={mount_path_on_container} {image_tag_name} ./build.py ``` +##### Cross build for ARM(Raspberry Pi 2/3) + +You need to install required packages +``` +sudo apt-get install qemu qemu-user-static binfmt-support debootstrap +sudo apt-get install binutils-arm-linux-gnueabihf +sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf +``` + +You then need to prepare a root filesystem. Only ARMv7l is supported for now. +``` +$ sudo ./cross/build-rootfs.sh +``` +Root file system will be prepared in `./cross/rootfs/armv7l` + +After it's prepared, you can build with `--cross` option. +``` +$ ./build.py --cross armv7l +``` + #### Windows TBD diff --git a/build.py b/build.py index f2502f8..54af1aa 100755 --- a/build.py +++ b/build.py @@ -69,6 +69,7 @@ def parse_args(): parser.add_argument("--buildpath", default="build", help="specify build path") parser.add_argument("--clean", default=False, help="clean before build", dest="clean", action="store_true") parser.add_argument("--single", default=False, help="disalbe parallel build", dest="single", action="store_true") + parser.add_argument("--cross", default="", help="cross build target", choices=["", "armv7l"]) return parser.parse_args() @@ -79,17 +80,33 @@ def main(): system, node, release, version, machine, processor = platform.uname() cpu_count = multiprocessing.cpu_count() + if options.cross == "armv7l": + machine = "armv7l" + # Set the install folder install_folder = "mengde" + home_folder = os.getcwd() + print_header("Start CMake configuration") build_dir = "build/%s.%s.%s" % (system, machine, options.buildtype) check_run_cmd("mkdir", ["-p", build_dir]) os.chdir(build_dir) - check_run_cmd("cmake", ["-DCMAKE_BUILD_TYPE=" + options.buildtype, - ("../" * (build_dir.count("/") + 1)), - "-DCMAKE_INSTALL_PREFIX=./", - "-DINSTALL_FOLDER=" + install_folder]) + + if options.cross == "armv7l": + if os.environ.get("ROOTFS_ARM") is None: + os.environ["ROOTFS_ARM"] = os.path.join(home_folder, "cross/rootfs/armv7l") + toolchain = os.path.join(home_folder, "cmake/toolchain-armv7l.cmake") + check_run_cmd("cmake", ["-DCMAKE_BUILD_TYPE=" + options.buildtype, + ("../" * (build_dir.count("/") + 1)), + "-DCMAKE_INSTALL_PREFIX=./", + "-DINSTALL_FOLDER=" + install_folder, + "-DCMAKE_TOOLCHAIN_FILE=" + toolchain]) + else: + check_run_cmd("cmake", ["-DCMAKE_BUILD_TYPE=" + options.buildtype, + ("../" * (build_dir.count("/") + 1)), + "-DCMAKE_INSTALL_PREFIX=./", + "-DINSTALL_FOLDER=" + install_folder]) # From here, support `Makefile` project only make_args = [] diff --git a/cmake/armv7l_settings.cmake b/cmake/armv7l_settings.cmake new file mode 100644 index 0000000..df2825b --- /dev/null +++ b/cmake/armv7l_settings.cmake @@ -0,0 +1,36 @@ +# Notice: this file is used in cross building for ARMv7l +# find_package() will be looking for host machine +# and it will not be correct for cross building for ARM target. +# As RootFS will be prepared with required packages, +# we assume they are installed as described in below folders. + +if(NOT DEFINED ROOTFS_ARM) + message(FATAL_ERROR "ROOTFS_ARM is required for cross building") +endif() +if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + message(FATAL_ERROR "ARM cross build is currently supported only in Linux") +endif() +if(NOT EXISTS "${ROOTFS_ARM}/lib/arm-linux-gnueabihf") + message(FATAL_ERROR "ROOTFS_ARM path doesn't seem to be a correct ARM rootfs") +endif() + +set(Boost_VERSION 105500) +set(Boost_FOUND True) +set(BOOST_INCLUDEDIR ${ROOTFS_ARM}/usr/include/boost) +set(BOOST_LIBRARYDIR ${ROOTFS_ARM}/usr/lib/arm-linux-gnueabihf) +set(Boost_INCLUDE_DIRS ${ROOTFS_ARM}/usr/include/boost) +set(SDL2_INCLUDE_DIR ${ROOTFS_ARM}/usr/include/SDL2) +set(SDL2_TTF_INCLUDE_DIR ${ROOTFS_ARM}/usr/include/SDL2) +set(LUA_INCLUDE_DIR ${ROOTFS_ARM}/usr/include/lua5.2) + +set(SDL2_LIBRARY SDL2main SDL2 pthread) +set(SDL2_TTF_LIBRARIES SDL2_ttf) +set(Boost_LIBRARIES boost_filesystem boost_system) +set(LUA_LIBRARIES lua5.2 m) + +# include path for system +include_directories(${ROOTFS_ARM}/usr/include/arm-linux-gnueabihf) + +# library path for system +link_directories(${ROOTFS_ARM}/usr/lib/arm-linux-gnueabihf + ${BOOST_LIBRARYDIR}) diff --git a/cmake/toolchain-armv7l.cmake b/cmake/toolchain-armv7l.cmake new file mode 100644 index 0000000..74a75ca --- /dev/null +++ b/cmake/toolchain-armv7l.cmake @@ -0,0 +1,24 @@ +include(CMakeForceCompiler) + +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR armv7l) + +SET(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) +SET(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++) + +# where is the target environment +set(ROOTFS_ARM $ENV{ROOTFS_ARM}) +set(CMAKE_SHARED_LINKER_FLAGS + "${CMAKE_SHARED_LINKER_FLAGS} --sysroot=${ROOTFS_ARM}" + CACHE INTERNAL "" FORCE) +set(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} --sysroot=${ROOTFS_ARM}" + CACHE INTERNAL "" FORCE) + +set(CMAKE_FIND_ROOT_PATH ${ROOTFS_ARM}) +# search for programs in the build host directories +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +# for libraries and headers in the target directories +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)