1

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
Community
  • 1
  • 1
auro
  • 1,079
  • 1
  • 10
  • 22
  • The cross-compilation aspect of your question is already answered elsewhere: http://stackoverflow.com/a/15206709/1158895 – Brady Jun 09 '14 at 08:37

3 Answers3

3

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.

dirkbaechle
  • 3,984
  • 14
  • 17
  • Thanks, @dirkbaechle. Taking a hint from you, I tried prefacing the CC and CXX with the tool-chain values and SCons picked up the right compiler. I'll try them as args a bit later. – auro Jun 09 '14 at 23:35
1

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"])
Brady
  • 10,207
  • 2
  • 20
  • 59
1

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.

Kev
  • 2,234
  • 1
  • 12
  • 6