I'm working on a few multi platform projects that all depend on common framework. I want to add support for Google Native-Client (NaCl). The way I aproached the problem is first to compile the framework as static library (this is how I've been doing it on all other platforms).
I have to say that I have never used SCons before. I think I start grasping it. Starting from a build.scons from a tutorial I can get some code compiling and linking. Now I would want to skip the linking process but seems like the nacl_env was never intended to compile static libraries.
Reading the SCons help didn't help me much since the Library node is missing from the nacl_env.
I don't think I understand SCons enough to write the whole build process from scratch so I was hopping to not have to do so.
1. Am I approaching the problem correctly?
2. Any tips or sample nacl static libs, build using SCons?
Ok, what I did is way more trickery than what you probably need.
I wanted my static library to handle the initialization steps of the NaCl module, and then call some project-specific function.
I ended up turning my whole framework and the contents of the built-in libppapi_cpp.a into a single .o file, and then that into a single .a file, a static library.
I needed a single .o file, because otherwise I would run into dependency problems releated to initialization, I could not solve.
build_lib.sh (framework):
#!/bin/bash -e
SDK="/home/kalmi/ik/nacl_sdk/pepper_15"
function create_allIn_a {
TMPDIR="`mktemp -d`"
echo $TMPDIR
cp $O_FILES $TMPDIR
pushd $TMPDIR &> /dev/null
$AR x $LIBPPAPI_CPP_A
$LD -Ur * -o ALL.o
$AR rvs $OUTPUT_NAME ALL.o
$RANLIB $OUTPUT_NAME
popd &> /dev/null
}
./scons
BIN_BASE="$SDK/toolchain/linux_x86/bin"
LD="$BIN_BASE/i686-nacl-ld"
AR="$BIN_BASE/i686-nacl-ar"
RANLIB="$BIN_BASE/i686-nacl-ranlib"
LIBPPAPI_CPP_A="$SDK/toolchain/linux_x86_newlib/x86_64-nacl/lib32/libppapi_cpp.a"
O_FILES="`find $(pwd)/opt_x86_32 | grep .o$ | grep --invert-match my_main.o | tr "\n" " "`"
LIBDIR="../../../bin/lib/lib32"
mkdir -p $LIBDIR
if [ -f $LIBDIR/libweb2grid_framework.a ]; then
rm $LIBDIR/libweb2grid_framework.a
fi
OUTPUT_NAME="`readlink -m $LIBDIR/libweb2grid_framework.a`"
create_allIn_a
BIN_BASE="$SDK/toolchain/linux_x86/bin"
LD="$BIN_BASE/x86_64-nacl-ld"
AR="$BIN_BASE/x86_64-nacl-ar"
RANLIB="$BIN_BASE/x86_64-nacl-ranlib"
LIBPPAPI_CPP_A="$SDK/toolchain/linux_x86_newlib/x86_64-nacl/lib64/libppapi_cpp.a"
O_FILES="`find $(pwd)/opt_x86_64 | grep .o$ | grep --invert-match my_main.o | tr "\n" " "`"
LIBDIR="../../../bin/lib/lib64"
mkdir -p $LIBDIR
if [ -f $LIBDIR/libweb2grid_framework.a ]; then
rm $LIBDIR/libweb2grid_framework.a
fi
OUTPUT_NAME="`readlink -m $LIBDIR/libweb2grid_framework.a`"
create_allIn_a
./scons -c
The my_main.o file is excluded from the static library, because that file contains the function that is to be provided by the project that uses this framework.
The build.scons file for the framework is truly ordinary.
build.scons (for some project that uses this framework):
#! -*- python -*-
#What to compile:
sources = [ 'src/something.cpp', 'src/something_helper.cpp' ]
###############################################################x
import make_nacl_env
import nacl_utils
import os
nacl_env = make_nacl_env.NaClEnvironment(
use_c_plus_plus_libs=False,
nacl_platform=os.getenv('NACL_TARGET_PLATFORM'))
nacl_env.Append(
# Add a CPPPATH that enables the full-path #include directives, such as
# #include "examples/sine_synth/sine_synth.h"
CPPPATH=[os.path.dirname(os.path.dirname(os.path.dirname(os.getcwd())))],
LIBS=['web2grid_framework','srpc'],
LIBPATH=['../../../bin/lib/lib32','../../../bin/lib/lib64'],
LINKFLAGS=['-pthread']
)
nacl_env.AllNaClModules(sources, 'client')
Some lines worth highlighting:
I am not saying that this is a clean method, but it gets the job done.