BrianD
BrianD

Reputation: 11

Setting Linux environment variable within the WAF build system

I have inherited an existing WAF build system. This existing system is using WAF 1.7.2. This system supports multiple cross-compilers using WAF variants. I need to add a new variant that supports a new toolchain. Unfortunately, in order to use this toolchain on our build system, I must set the Linux environment variable LD_LIBRARY_PATH before executing any of the tools.

The simple approach of setting the environment variable before running waf works fine for the configure step (I've removed some of the variants for simplicity of discussion):

export LD_LIBRARY_PATH=/opt/toolchains/crosstools-mipsel-linux-uclibc-4.6.3/usr/lib
./waf configure
Configuring variant docs       - Available  
Configuring variant linux_arm_musl - Available for ['arm-32bit']
Configuring variant linux_mips_uclibc - Available for ['mips-32bit']
'configure' finished successfully (0.288s)

But it fails during the build step:

export LD_LIBRARY_PATH=/opt/toolchains/crosstools-mipsel-linux-uclibc-4.6.3/usr/lib
./waf build --variant=linux_mips_uclibc_debug
Waf: Entering directory `/home/builder/dev/project/slag'
Waf: Entering directory `/home/builder/dev/project/slag/linux_mips_uclibc_debug'
[  1/305] | linux_mips_uclibc_debug | platform | c | ['list.c'] | ['list.c.1.o']
[  2/305] | linux_mips_uclibc_debug | platform | c | ['map.c'] | ['map.c.1.o']
[  3/305] | linux_mips_uclibc_debug | platform | c | ['tree.c'] | ['tree.c.1.o']
/opt/toolchains/crosstools-mipsel-linux-uclibc-4.6.3/usr/bin/../libexec/gcc/mipsel-buildroot-linux-uclibc/4.6.3/cc1: error while loading shared libraries: libmpc.so.3: cannot open shared object file: No such file or directory
/opt/toolchains/crosstools-mipsel-linux-uclibc-4.6.3/usr/bin/../libexec/gcc/mipsel-buildroot-linux-uclibc/4.6.3/cc1: error while loading shared libraries: libmpc.so.3: cannot open shared object file: No such file or directory
/opt/toolchains/crosstools-mipsel-linux-uclibc-4.6.3/usr/bin/../libexec/gcc/mipsel-buildroot-linux-uclibc/4.6.3/cc1: error while loading shared libraries: libmpc.so.3: cannot open shared object file: No such file or directory
Waf: Leaving directory `/home/builder/dev/project/slag/linux_mips_uclibc_debug'
Build failed

As I dug into the problem, I discovered that WAF preserves the environment when executing the compiler during the configure step, but it wipes out the environment before executing the compiler during the build step. I tried many different ways to have WAF set a Linux environment variable during the build step, but all of my attempts get wiped clean before the compiler executes.

How can I setup WAF so that I can have a Linux environment variable set when executing the compiler during the build?

Upvotes: 1

Views: 1106

Answers (1)

neuro
neuro

Reputation: 15180

You can have a look at the waf book § 10.5.2.

I think your problem is that LD_LIBRARY_PATH defines libs path for execution. For linking you have to use your linker with the -L flag with the correct path.

For that, the simplest way is to use conf.env.LINKFLAGS = "-L/opt/toolchains/crosstools-mipsel-linux-uclibc-4.6.3/usr/lib" in the relevant variant configuration.

By the way is useful to define a specific command associated with your variant :

def configure(cnf):

    cnf.setenv("linux_mips_uclibc_debug")
    cnf.env.CC = /opt/toolchains/crosstools-mipsel-linux-uclibc-4.6.3/usr/bin/cc
    cnf.env.LINKFLAGS = "-L/opt/toolchains/crosstools-mipsel-linux-uclibc-4.6.3/usr/lib"
    cnf.env.foo = "whatever"

    cnf.setenv("linux_xxx")
    cnf.env.CC = /opt/toolchains/crosstools-xxx/usr/bin/cc
    cnf.env.LINKFLAGS = "-L/opt/toolchains/crosstools-xxx/usr/lib"
    cnf.env.foo = "whatever_xxx"

def build(bld):

    bld.program(target = "myexe", source = "mymain.c")

class dummy_name_doesnt_matter(BuildContext):
    cmd = 'build_linux_mips_uclibc_debug'
    variant = 'linux_mips_uclibc_debug' # must match setenv name in conf

class dummy_name_doesnt_matter(BuildContext):
    cmd = 'build_xxx'
    variant = 'linux_xxx'

Use like:

waf # build default variant, with system toolchain
waf build_linux_mips_uclibc_debug # use linux mips variant
waf build_xxx # use variant linux_xxx

Note: untested, I have no waf 1.7.2

If you really need to set LD_LIBRARY_PATH for the compiler, you can monkeypatch waf compile/link command. Something like that:

from waflib.Tools.c import c, cprogram
from waflib.Task import classes

llp = "LD_LIBRARY_PATH={} ".format("/your/path/here")

class MyC(c):
    run_str = lld + c.run_str
class MyCProgram(cprogram):
    run_str = lld + cprogram.run_str

classes['c'] = MyC
classes['cprogram'] = MyCProgram

I have made something like that to replace -I with -isystem. Works like a charm :)

Of course, You can do that in a waf tool for ease of use.

Upvotes: 1

Related Questions