Skip to content

Commit

Permalink
Enable arm cross building (wateret#56)
Browse files Browse the repository at this point in the history
This will enable cross building for ARM
- Tested with Raspberry Pi 3 with rpi SDL backend
  • Loading branch information
seanshpark authored and wateret committed Apr 30, 2018
1 parent 08c209e commit 8da40ce
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 8 deletions.
19 changes: 15 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
25 changes: 21 additions & 4 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand All @@ -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 = []
Expand Down
36 changes: 36 additions & 0 deletions cmake/armv7l_settings.cmake
Original file line number Diff line number Diff line change
@@ -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})
24 changes: 24 additions & 0 deletions cmake/toolchain-armv7l.cmake
Original file line number Diff line number Diff line change
@@ -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)

0 comments on commit 8da40ce

Please sign in to comment.