[Scons-users] Building cppunit with scons (configure and make)

Carl Cerecke carl.cerecke at compacsort.com
Mon Dec 9 20:39:42 EST 2013


Thanks Marc,

Your post pointed me in the right direction.
Ideallly, I would have liked the build artifacts to be in a separate
directory hierarchy rather than in the original (the version control
software sees a bunch of unversioned files), but I'm happy that it
works.

Here's my Sconscript file for building cppunit with configure/make,
with the tweaked AutoConfig file following:

import os
Import('shared')

env = shared.Clone()

env.Tool('AutoConf')
env.Tool('Make')

srcdir = Dir('3rdParty/cppunit-1.12.1').srcnode().abspath

env['AutoConfigTarget'] = [
'config.status',
'Makefile',
'cppunit.pc',
'cppunit.spec',
'cppunit-config',
'src/Makefile',
'src/DllPlugInTester/Makefile',
'src/cppunit/Makefile',
'include/Makefile',
'include/cppunit/Makefile',
'include/cppunit/config/Makefile',
'include/cppunit/extensions/Makefile',
'include/cppunit/plugin/Makefile',
'include/cppunit/portability/Makefile',
'include/cppunit/tools/Makefile',
'include/cppunit/ui/Makefile',
'include/cppunit/ui/mfc/Makefile',
'include/cppunit/ui/qt/Makefile',
'include/cppunit/ui/text/Makefile',
'doc/Makefile',
'doc/Doxyfile',
'examples/Makefile',
'examples/simple/Makefile',
'examples/hierarchy/Makefile',
'examples/cppunittest/Makefile',
'examples/ClockerPlugIn/Makefile',
'examples/DumperPlugIn/Makefile',
'examples/money/Makefile',
'config/config.h',
'include/cppunit/config-auto.h']

cppunit_config = env.AutoConfig(None,
Dir(srcdir), # fails without Dir()
call (i.e. with just 'srcdir').
AutoConfigScriptDir = srcdir,
AutoConfigParams =
['--prefix='+Dir('.').abspath])

lib_file = ['lib/libcppunit.la'] # plus a hundred other files made by
'make install'

cppunit_lib = env.Make(lib_file,
cppunit_config,
MakePath=srcdir,
MakeTargets='install')
Alias('cppunit',cppunit_lib)

------------------------------------------
And the tweaked AutoConf file:
------------------------------------------

# AutoConfig Builder: Runs ./configure inside a directory.
#
# Parameters:
# AutoConfigParams -- Sequence of parameter strings to include on the
# configure command line.
# Default: [ ]
# AutoConfigTarget -- File that configure will create.
# Default: config.h
# AutoConfigSource -- File that configure depends on.
# Default: Makefile.in
import os
import subprocess

from SCons.Script import *

def parms(target, source, env):
"""Assemble various AutoConfig parameters."""
workdir = os.path.dirname(str(source[0]))
params = None
if 'AutoConfigParams' in env.Dictionary().keys():
params = env['AutoConfigParams']
if not isinstance(params, list):
print 'AutoConfigParams must be a sequence'
Exit(1)
targetfile = 'Makefile'
if 'AutoConfigTarget' in env.Dictionary().keys():
targetfile = env['AutoConfigTarget']
sourcefile = 'Makefile.in'
if 'AutoConfigSource' in env.Dictionary().keys():
sourcefile = env['AutoConfigSource']
scriptdir = '.'
if 'AutoConfigScriptDir' in env.Dictionary().keys():
scriptdir = env['AutoConfigScriptDir']

#print 'parms',(workdir, params, targetfile, sourcefile, scriptdir)
return (workdir, params, targetfile, sourcefile, scriptdir)

def message(target, source, env):
"""Return a pretty AutoConfig message."""
(dirname,
params,
targetfile,
sourcefile,
scriptdir) = parms(target, source, env)
if 'AUTOCONFIGCOMSTR' in env.Dictionary().keys():
return env.subst(env['AUTOCONFIGCOMSTR'],
target = target, source = source, raw = 1)
msg = 'cd ' + dirname + ' && ./configure'
if params is not None:
msg += ' ' + ' '.join(params)
return msg

def emitter(target, source, env):
"""Remap the source & target to path/$AutoConfigSource and
path/$AutoConfigTarget."""
(dirname,
params,
targetfile,
sourcefile,
scriptdir) = parms(target, source, env)

# NOTE: Using source[0] instead of target[0] for the target's path!
# If there's only one . in the source[0] value, then Scons strips off the
# extension when it determines the target[0] value. For example,
# AutoConfig('foo.blah')
# sets
# source[0] = 'foo.blah'
# target[0] = 'foo'
# (SCons does NOT do this if source[0] has more than one . )
# Since this emitter expects the incoming source[0] value to be a directory
# name, we can use it here for the rewritten target[0].

#print 'emitter[0]',[ os.path.join(str(source[0]), targetfile) ]
#print 'emitter[1]',[ os.path.join(str(source[0]), sourcefile) ]

return ([ os.path.join(str(source[0]), filename) for filename in
targetfile ],
[ os.path.join(str(source[0]), sourcefile) ])

def builder(target, source, env):
"""Run ./configure in a directory."""
( dirname,
params,
targetfile,
sourcefile,
scriptdir) = parms(target, source, env)

real_stdout = subprocess.PIPE
if 'AUTOCONFIGCOMSTR' not in env.Dictionary().keys():
real_stdout = None
cmd = os.path.join(scriptdir,'configure')
if params is not None:
cmd = [ cmd ] + params

return subprocess.call( cmd,
cwd = dirname,
stdout = real_stdout,
stderr = real_stdout)


def generate(env, **kwargs):
env['BUILDERS']['AutoConfig'] = env.Builder(
action = env.Action(builder, message),
emitter = emitter,
single_source = True)

def exists(env):
return True

On 10 December 2013 05:19, Marc Branchaud <marcnarc at xiplink.com> wrote:

>

> On 13-12-08 08:51 PM, Carl Cerecke wrote:

> > Hi,

> >

> > We have cppunit (cppunit-1.12.1) that we would like to build with scons. It

> > uses autoconf currently.

> >

> > I'm hoping to be able to use a variant_dir build....

> >

> > I tried to just use scons, but the ./configure step creates a number of files

> > which the build requires.

> >

> > I tried to use the AutoConfigBuilder and MakeBuilder

> > from http://www.scons.org/wiki/CustomBuilders, but have had a lot of trouble.

> > The ./configure step wants to create files it doesn't need to, and the

> > MakeBuilder is giving me weird errors (which I don't have handy right

> > now...). I'm thinking that it might have something to do with the symlinks in

> > the build directory confusing configure and make.

> >

> > After a bit of fiddling around, I've managed to get AutoConfigBuilder to run

> > configure. I had to add a bunch of lines like so ()to get the symlinks created):

> > Depends(configure_targets, Glob('3rdParty/cppunit-1.12.1/*/*'))

>

> Could you post your SCons code? It's hard to diagnose a problem without the

> code.

>

> In my experience building autoconfigure things with SCons, you can generally

> (but not always) chdir into your variant and run the configure script from

> there, e.g.

> cd /path/to/variant/dir

> /path/to/source/dir/configure

>

> This is the approach I use with cppunit. Unfortunately the AutoConfigBuilder

> posted in the wiki doesn't allow for this. I've attached an *untested*

> version that supports an AutoConfigScriptDir parameter. Set that to the

> absolute path to your cppunit sources, like this:

>

> cppunit_config = AutoConfig(AutoConfigScriptDir = Dir('.').srcnode().abspath)

>

> If you're happy re-writing cppunit's makefiles in SCons, then more power to

> you. Me, I just invoke "make install":

>

> cppunit = Make(source = cppunit_config,

> target = [ ... ],

> MakePath = Dir('.').abspath, # Not the srcnode()

> MakeTargets = 'install')

>

> Set the target of the Make call to the installed cppunit library. As you

> saw, SCons needs to know about the installed headers too. You must list all

> of these explicitly, and use SideEffect() not Precious().

>

> You can control where cppunit installs itself by passing --prefix to the

> configure script (with the AutoConfigParams option). Note that the variant

> directory where you *build* cppunit isn't where you want cppunit to *install*

> itself. You should designate a place in your variant tree for installed

> libraries & headers, and use --prefix to point cppunit there.

>

> M.

>

>

> _______________________________________________

> Scons-users mailing list

> Scons-users at scons.org

> http://four.pairlist.net/mailman/listinfo/scons-users

>




--
Carl Cerecke
SENIOR SOFTWARE DEVELOPER



M: +64 21 205 0239
F: +64 9 634 4491
Skype: carl-compac


More information about the Scons-users mailing list