Skip to content

rustc: android cross compilation #4343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
url = git://github.com/brson/llvm.git
[submodule "src/libuv"]
path = src/libuv
url = git://github.com/graydon/libuv.git
url = git://github.com/ILyoan/libuv.git
40 changes: 40 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## CMakeLists.txt
PROJECT(Rust)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

# The version number
SET(RustVersionMajor 0)
SET(RustVersionMinor 5)

INCLUDE(cmakeFiles/config.cmake)
INCLUDE(cmakeFiles/submodules.cmake)
INCLUDE(cmakeFiles/snapshot.cmake)
INCLUDE(cmakeFiles/libuv.cmake)
INCLUDE(cmakeFiles/llvm.cmake)
INCLUDE(cmakeFiles/rustllvm.cmake)
INCLUDE(cmakeFiles/rt.cmake)
INCLUDE(cmakeFiles/rustc.cmake)
INCLUDE(cmakeFiles/install.cmake)
IF(${IsCrossCompile})
INCLUDE(cmakeFiles/rustctarget.cmake)
ENDIF()


#SET(cmakeDir "${CMAKE_SOURCE_DIR}/cmakeFiles")
#SET(cmakeConfigure "${cmakeDir}/configuration.cmake")
#SET(cmakeSnapshot "${cmakeDir}/snapshot.cmake")
#SET(cmakeRustc "${cmakeDir}/rustc.cmake")
#SET(cmakellvm "${cmakeDir}/llvm.cmake")
#SET(cmakelibuv "${cmakeDir}/libuv.cmake")
#SET(cmakeInstall "${cmakeDir}/install.cmake")
#
#INCLUDE(${cmakeConfigure})
#INCLUDE(${cmakeSnapshot})
#INCLUDE(${cmakellvm})
#INCLUDE(${cmakelibuv})
#INCLUDE(${cmakeInstall})
#
#ADD_SUBDIRECTORY(src)
#
#INCLUDE(${cmakeRustc})

2 changes: 1 addition & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ DRIVER_CRATE := $(S)src/driver/driver.rs
######################################################################

# FIXME: x86-ism
LLVM_COMPONENTS=x86 ipo bitreader bitwriter linker asmparser jit mcjit \
LLVM_COMPONENTS=x86 ARM ipo bitreader bitwriter linker asmparser jit mcjit \
interpreter

define DEF_LLVM_VARS
Expand Down
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,62 @@ See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.
The [tutorial] is a good starting point.

[tutorial]: http://static.rust-lang.org/doc/tutorial.html


========================== Steps for Android Target addtion =======================

1. setup android ndk standalone tool chain with platform=14 option

Android NDK can be downloaded from http://developer.android.com/tools/sdk/ndk/index.html

example command to setup standalone tool chain:

~/work/toolchains/android-ndk-r8c/build/tools$ ./make-standalone-toolchain.sh --platform=android-14 --install-dir=/home/ubuntu/work/toolchains/ndk_standalone --ndk-dir=/home/ubuntu/work/toolchains/android-ndk-r8c

2. Download rustc from git repository

a. git clone http://github.com/webconv/rust.git

b. cd rust

c. mkdir build

d. cd build

3. Create Makefile using CMake

cmake ../ -DTargetOsType=android -DTargetCpuType=arm -DToolchain=path_of_standalone_toolchain_dir

4. Build libuv and llvm

make libuv

make llvm


5. Create Makefile again (the Makefile made in step 3 does not contain information of llvm)

cmake ../

6. Build Rustc ( make and make install have been separated)

a.make

b.make install [ it will copy ARM libraries into /usr/local/lib/rustc/arm-unknown-android/lib


7. How to cross compiler

rustc --target arm-unknown-android hello.rs


8. How to run on Android

use adb -e push command to push all arm libs as specified in 6 b

push your binary

set LD_LIBRARY_PATH

run using adb shell

231 changes: 231 additions & 0 deletions cmakeFiles/config.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)


# set host information

SET(HostCpuType ${CMAKE_SYSTEM_PROCESSOR})
IF(${HostCpuType} MATCHES "i386|i486|i686|i786|x86")
SET(HostCpuType "i686")
IF(APPLE)
EXECUTE_PROCESS(
COMMAND sysctl hw.optional.x86_64
OUTPUT_VARIABLE cpucheck
)
IF(cpucheck MATCHES ": 1")
SET(HostCpuType "x86_64")
ENDIF()
ENDIF()
ELSEIF(${HostCpuType} MATCHES "x86-64|x86_64|x64|amd64")
SET(HostCpuType "x86_64")
ELSE()
MESSAGE(FATAL_ERROR "Unkown CPU type")
ENDIF()

IF(APPLE)
SET(HostOsType darwin)
SET(HostTriple ${HostCpuType}-apple-darwin)
ELSEIF(UNIX)
SET(HostOsType linux)
SET(HostTriple ${HostCpuType}-unknown-linux-gnu)
ELSE()
MESSAGE(FATAL_ERROR "Unknown OS")
ENDIF()

SET(HostSharedLibPrefix ${CMAKE_SHARED_LIBRARY_PREFIX})
SET(HostSharedLibSuffix ${CMAKE_SHARED_LIBRARY_SUFFIX})
SET(HostStaticLibPrefix ${CMAKE_STATIC_LIBRARY_PREFIX})
SET(HostStaticLibSuffix ${CMAKE_STATIC_LIBRARY_SUFFIX})
SET(HostExecSuffix ${CMAKE_EXECUTABLE_SUFFIX})

# set target information

IF(TargetOsType AND TargetCpuType)
IF(NOT ${TargetOsType} STREQUAL "android")
MESSAGE(FATAL_ERROR "Unknown target OS")
ENDIF()
IF(NOT ${TargetCpuType} STREQUAL "arm")
MESSAGE(FATAL_ERROR "Unknown target CPU type")
ENDIF()

IF(${TargetOsType} STREQUAL "android")
SET(TargetTriple ${TargetCpuType}-unknown-android)

SET(TargetSharedLibPrefix lib)
SET(TargetSharedLibSuffix .so)
SET(TargetStaticLibPrefix lib)
SET(TargetStaticLibSuffix .a)
SET(TargetExecSuffix)
ENDIF()

SET(IsCrossCompile TRUE)
MESSAGE(STATUS "======================================================")
MESSAGE(STATUS " Cross Target: ${TargetTriple}")
MESSAGE(STATUS "======================================================")

ELSE()
SET(IsCrossCompile FALSE)
ENDIF()



# gcc setting

# host

SET(${HostTriple}cc ${CMAKE_C_COMPILER})
SET(${HostTriple}cxx ${CMAKE_CXX_COMPILER})
SET(${HostTriple}ar ${CMAKE_AR})

IF(${HostOsType} STREQUAL linux)
SET(HostCFlags
-DRUST_NDEBUG -MMD -MP -fPIC -O2 -Wall -Werror -g -fno-omit-frame-pointer)
SET(HostLinkFlags -shared -fPIC -ldl -lpthread -lrt -g)
IF(${HostCpuType} STREQUAL x86_64)
SET(HostCFlags ${HostCFlags} -m64)
SET(HostLinkFlags ${HostLinkFlags} -m64)
ELSE()
SET(HostCFlags ${HostCFlags} -m32)
SET(HostLinkFlags ${HostLinkFlags} -m32)
ENDIF()
SET(HostCxxFlags ${HostCFlags} -fno-rtti)
SET(HostDefFlags -Wl,--export-dynamic,--dynamic-list=)
SET(HostPreLibFlags -Wl,-whole-archive)
SET(HostPostLibFlags -Wl,-no-whole-archive -Wl,-znoexecstack)
SET(HostllvmBuildEnv CXXFLAGS=-fno-omit-frame-pointer)
SET(HostLinkPthread -lpthread)
ELSE() # darwin
SET(HostCFlags
-DRUST_NDEBUG -MMD -MP -fPIC -O2 -Wall -Werror -g)
SET(HostLinkFlags
-dynamiclib -lpthread -framework CoreServices -Wl,-no_compact_unwind)
IF(${HostCpuType} STREQUAL x86_64)
SET(HostCFlags ${HostCFlags} -m64 -arch x86_64)
SET(HostLinkFlags ${HostLinkFlags} -m64)
ELSE()
SET(HostCFlags ${HostCFlags} -m32 -arch i386)
SET(HostLinkFlags ${HostLinkFlags} -m32)
ENDIF()
SET(HostCxxFlags ${HostCFlags} -fno-rtti)
SET(HostDefFlags -Wl,-exported_symbols_list,)
SET(HostPreLibFlags)
SET(HostPostLibFlags)
SET(HostllvmBuildEnv)
SET(HostLinkPthread -lpthread)
ENDIF()

# target

IF(TargetOsType STREQUAL "android")
IF(NOT Toolchain)
MESSAGE(FATAL_ERROR "no toolchain information\n"
"use -DToolchain=<android tool chain directory>")
ENDIF()
IF(NOT EXISTS ${Toolchain})
MESSAGE(FATAL_ERROR "no directory - ${Toolchain}\n"
"use -DToolchain=<android tool chain directory>")
ENDIF()

SET(${TargetTriple}cc ${Toolchain}/bin/arm-linux-androideabi-gcc)
SET(${TargetTriple}cxx ${Toolchain}/bin/arm-linux-androideabi-g++)
SET(${TargetTriple}ar ${Toolchain}/bin/arm-linux-androideabi-ar)
SET(${TargetTriple}include ${Toolchain}/sysroot/usr/include)
SET(${TargetTriple}lib ${Toolchain}/sysroot/usr/lib)
SET(${TargetTriple}sysroot ${Toolchain}/sysroot)

IF(NOT EXISTS ${${TargetTriple}cc})
MESSAGE(FATAL_ERROR "There is no gcc compiler in ${Toolchain}/bin")
ENDIF()
IF(NOT EXISTS ${${TargetTriple}cxx})
MESSAGE(FATAL_ERROR "There is no g++ compiler in ${Toolchain}/bin")
ENDIF()
IF(NOT EXISTS ${${TargetTriple}ar})
MESSAGE(FATAL_ERROR "There is no ar in ${Toolchain}/bin")
ENDIF()

MESSAGE(STATUS "Target gcc - ${${TargetTriple}cc}")
MESSAGE(STATUS "Target g++ - ${${TargetTriple}cxx}")
MESSAGE(STATUS "Target ar - ${${TargetTriple}ar}")

SET(TargetCFlags
-DRUST_NDEBUG -MMD -MP -fPIC -O2 -Wall -g -fno-omit-frame-pointer
-D__arm__ -DANDROID -D__ANDROID__
-I${Toolchain}/arm-linux-androideabi/include/c++/4.6
-I${Toolchain}/arm-linux-androideabi/include/c++/4.6/arm-linux-androideabi
)
SET(TargetLinkFlags -shared -fPIC -ldl -g -lm -lsupc++ -lgnustl_shared)
SET(TargetCxxFlags ${TargetCFlags} -fno-rtti)
SET(TargetDefFlags -Wl,--export-dynamic,--dynamic-list=)
SET(TargetPreLibFlags -Wl,-whole-archive)
SET(TargetPostLibFlags -Wl,-no-whole-archive -Wl,-znoexecstack)
SET(TargetLinkPthread)
ENDIF()

##SET(CMAKE_C_COMPILER "gcc")
##SET(CMAKE_CXX_COMILER "g++")
#SET(CMAKE_C_FLAGS "${GCC_CFLAGS}")
#SET(CMAKE_CXX_FLAGS "${GCC_CXXFLAGS}")
#SET(CMAKE_C_LINK_FLAGS "${GCC_LINK_FLAGS}")
#SET(CMAKE_CXX_LINK_FLAGS "${GCC_LINK_FLAGS}")


MACRO(doMakeDef osType defName defIn defOut)
IF(${osType} MATCHES "linux|android")
ADD_CUSTOM_COMMAND(
OUTPUT ${defOut}
COMMAND ${CMAKE_COMMAND} -E copy ${defIn} ${defOut}
COMMAND echo '{' > ${defOut}
&& sed 's/.$$/&\;/' ${defIn} >> ${defOut}
&& echo '}\;' >> ${defOut}
DEPENDS ${defIn}
)
ADD_CUSTOM_TARGET(
${defName}
DEPENDS ${defOut}
)
ELSEIF(${osType} STREQUAL darwin)
ADD_CUSTOM_COMMAND(
OUTPUT ${defOut}
COMMAND ${CMAKE_COMMAND} -E copy ${defIn} ${defOut}
COMMAND sed 's/^./_&/' ${defIn} > ${defOut}
DEPENDS ${defIn}
)
ADD_CUSTOM_TARGET(
${defName}
DEPENDS ${defOut}
)
ENDIF()
ENDMACRO(doMakeDef)


SET(BuildParallel -j4)



#directories

SET(RustRoot "${CMAKE_SOURCE_DIR}")
MESSAGE(STATUS "Rust root: ${RustRoot}")

SET(BuildRoot ${CMAKE_BINARY_DIR})
SET(BuildDlDir ${BuildRoot}/dl)
SET(BuildStageDir ${BuildRoot}/stage)
SET(BuildRtDir ${BuildRoot}/rt)
SET(BuildRustllvmDir ${BuildRoot}/rustllvm)


SET(EnvVar
export CFG_BUILD_DIR=${BuildRoot}
export CFG_VERSION=${RustVersionMajor}.${RustVersionMinor}
export CFG_HOST_TRIPLE=${HostTriple}
export CFG_LLVM_ROOT=
export CFG_ENABLE_MINGW_CROSS=
export CFG_PREFIX=/usr/home
export CFG_LIBDIR=lib
export CFG_SRC_DIR=${RustRoot}
)

IF(EXISTS ${Toolchain})
SET(EnvVar ${EnvVar} export PATH=$$PATH:${Toolchain}/bin
)
ENDIF()

Loading