Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scons build both static and shared library

Tags:

scons

I am trying to build both a static and a shared library using the same sources with SCons.

Everything works fine if I just build one or the other, but as soon as I try to build both, only the static library is built.

My SConscript looks like:

cppflags = SP3_env['CPPFLAGS']
cppflags += ' -fPIC '
SP3_env['CPPFLAGS'] = cppflags

soLibFile = SP3_env.SharedLibrary(
   target = "sp3",
   source = sources)
installedSoFile = SP3_env.Install(SP3_env['SP3_lib_dir'], soLibFile)

libFile = SP3_env.Library(
    target = "sp3",
    source = sources)
installedLibFile = SP3_env.Install(SP3_env['SP3_lib_dir'], libFile)

I also tried SharedObject(sources) before the SharedLibrary (passing in the return from SharedObject, rather than sources), but it is no different. Same if I build the .a before the .so.

How do I work around this?

like image 552
Beth Jelich Avatar asked Feb 28 '13 16:02

Beth Jelich


1 Answers

When the installation directory is not in or below the current directory, SCons does not behave as expected, as commented in the SCons Install method docs:

Note, however, that installing a file is still considered a type of file "build." This is important when you remember that the default behavior of SCons is to build files in or below the current directory. If, as in the example above, you are installing files in a directory outside of the top-level SConstruct file's directory tree, you must specify that directory (or a higher directory, such as /) for it to install anything there:

That is, you must invoke SCons with the install directory as a target (SP3_env['SP3_lib_dir'] in your case) in order for the installation to be executed. To simplify this, use env.Alias() as I do below.

When you invoke SCons, you should at least see that both the static and shared libraries are built in the local project dir. I would imagine, however, that SCons does not install them. Here is an example I made on Ubuntu that works:

env = Environment()

sourceFiles = 'ExampleClass.cc'

sharedLib = env.SharedLibrary(target='example', source=sourceFiles)
staticLib = env.StaticLibrary(target='example', source=sourceFiles)

# Notice that installDir is outside of the local project dir
installDir = '/home/notroot/projects/sandbox'

sharedInstall = env.Install(installDir, sharedLib)
staticInstall = env.Install(installDir, staticLib)

env.Alias('install', installDir)

If I execute scons with no targets, I get the following:

# scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o ExampleClass.o -c ExampleClass.cc
g++ -o ExampleClass.os -c -fPIC ExampleClass.cc
ar rc libexample.a ExampleClass.o
ranlib libexample.a
g++ -o libexample.so -shared ExampleClass.os
scons: done building targets.

Then I can install, executing scons with the install target, as follows:

# scons install
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
Install file: "libexample.a" as "/home/notroot/projects/sandbox/libexample.a"
Install file: "libexample.so" as "/home/notroot/projects/sandbox/libexample.so"
scons: done building targets.

Or, you could just do it all with one command, first clean everything

# scons -c install

Then, do it all with just one command:

# scons install
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o ExampleClass.o -c ExampleClass.cc
g++ -o ExampleClass.os -c -fPIC ExampleClass.cc
ar rc libexample.a ExampleClass.o
ranlib libexample.a
g++ -o libexample.so -shared ExampleClass.os
Install file: "libexample.a" as "/home/notroot/projects/sandbox/libexample.a"
Install file: "libexample.so" as "/home/notroot/projects/sandbox/libexample.so"
scons: done building targets.
like image 132
Brady Avatar answered Nov 05 '22 14:11

Brady