简体   繁体   中英

Cross-Compiling Swiften library for ARM-embedded with SCons makery

Swiften is a XMPP client library and my objective was to build it for a ARM-embedded target running Linux.

I hacked my way to a successful cross-compile with little knowledge of SCons. I'll lay out my hack here with the hope that someone can point me to a maintainable solution using the two makery files, SConscript.boot and SConstruct .

I had two tasks (neither accomplished satisfactorily):

  1. Successfully switching the tool-chain from native-compile to cross-compile
  2. Ensuring that OpenSSL libraries were successfully linked (not supplied by the swiftim project; they has to be installed and built in the 3rdParty folder).

Switching the tool-chain from native-compile to cross-compile for ARM

My ARM cross tool-chain components, gcc, g++, ld, etc are located here.

/opt/toolchain/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux/arm-linux-gnueabihf/bin/

I couldn't find a way to tell scons to use the cross tool-chain (from the above location) instead of the native tool (in the usual place, /usr/bin ). Prefacing the invocation ( ./scons Swiften ) with the fully-qualified values for the environment variables, CC and CXX didn't work (while not recommended, its alluded to in one place ).

Scons would only pick up the native tool-chain even after many ad hoc changes to the makery.

So, as a hack , I had to change the native tool-chain to point to the cross tool-chain.

/usr/bin/gcc -> /opt/toolchain/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux/bin/arm-linux-gnueabihf-gcc-4.7.3*
/usr/bin/g++ -> /opt/toolchain/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux/bin/arm-linux-gnueabihf-g++*

The first compile-break for ARM was fixed by adding the line below to the default portion of the build script, SConscript.boot .

env.Append(CPPDEFINES = ["_LITTLE_ENDIAN"])

The next compile-break has to do with the OpenSSL header files not being found. To fix the location issue, I had to introduce the line below into SConscript.boot

vars.Add(PackageVariable("openssl", "OpenSSL location", "/home/auro-tripathy/swiftim/swift/3rdParty/OpenSSL/openssl-1.0.1c/"))

Linking with OpenSSL

For the sample Switften programs to link with the OpenSSL libraries, I had to move libssl.a and libcrypto.a (built separately) from the location they were built to the toolchain library-location like so.

mv ~/swiftim/swift/3rdParty/OpenSSL/openssl-1.0.1c/libcrypto.a /opt/toolchain/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux/lib/gcc/arm-linux-gnueabihf/4.7.3/.

Help

Not understanding of the working of scons, I've made some hacks to get it to work.

I'd like some help to:

  1. Introduce a new target called ARM-embedded, just like other targets; iPhone, android, etc
  2. Clean way to integrate OpenSSL into the build .

Update Per dirkbaechle, retried the script below and it works

export CC=/opt/toolchain/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux/arm-linux-gnueabihf/bin/gcc
export CXX=/opt/toolchain/gcc-linaro-arm-linux-gnueabihf-4.7-2013.01-20130125_linux/arm-linux-gnueabihf/bin/g++
./scons Swiften

Brady's answer is correct, regarding how you'd do it in plain SCons. I'd just like to mention that the top-level SConstruct of Swiften already provides arguments like " cc= " and " cxx= " for using local toolchains. You might want to inspect the ouput of scons -h for a complete list of available options.

In addition, the SConscript for the OpenSSL build expects the sources to be located in the relative folder named " openssl ", not " openssl-1.0.1c " as in your case. Maybe that's where your build problems are mainly coming from.

I left a comment above regarding the cross-compilation. Its already been answered in the link provided, but basically you just need to set the appropriate construction variables: CC, CXX, LINK, etc.

As for a "Clean way to integrate OpenSSL into the build" this can be performed simply by adding library and include paths appropriately as follows replacing the quoted values appropriately: (without having to copy/move the original files)

# This sets the location of the OpenSSL Include paths
env.Append(CPPPATH="path/to/openssl/includes")

# This sets the location of the OpenSSL Libraries
env.Append(LIBPATH="path/to/openssl/libraries")

# These are the OpenSSL libraries to be linked into the binary
env.Append(LIBS=["OpenSSL_lib", "OpenSSL_lib2"])

The choice of compiler, and additional flags, can all be set in Swift's config.py file. A snippet from config.py using a custom compiler and flags is below (the one I use on one of my dev boxes):

cc = link = "/usr/local/llvm-git/bin/clang"
cxx = "/usr/local/llvm-git/bin/clang++"

bothflags = " -std=c++11 -stdlib=libc++ -nostdinc++"
cxxflags = bothflags + " -I/usr/local/libcxx/include -Wno-deprecated"
linkflags = bothflags + " -L/usr/local/libcxx/lib"

This should work for cross-compiling in the same manner.

To use a bundled openssl, you should just be able to extract into 3rdParty/OpenSSL, and add openssl_force_bundled = True to your config.py. You should not need to fiddle with setting include paths to this yourself. It's conceivable that this is tied to a particular openssl release as I've not compiled a bundled openssl since 1.0.0a, but if it doesn't work with the current version it's probably a bug that ought to be fixed. You could also cross-compile openssl yourself and use openssl='/path/to/openssl' , but that's a little more of a nuisance for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM