Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Specify different compilers in waf

Tags:

python

waf

I want to have several build configurations (meaning different C compilers) configured in waf. I managed to do it that way, but it looks a bit smelly to me.

How do I do it currently: I make different envs, and reset the c_compiler list before loading the next compiler, and at the end I reset it to all compilers.

def configure(cnf):
   _os = Utils.unversioned_sys_platform()

   restore_c_compilers = c_compiler[_os]

   # load gcc
   c_compiler[_os] = ['gcc']
   conf.setenv('gcc')
   conf.load('compiler_c')

   # load clang
   conf.setenv('clang')
   c_compiler[_os] = ['clang']
   conf.load('compiler_c')

   c_compiler[_os] = restore_c_compilers  # reset compiler list

Is there a better way to do it?

There is this question on SO (How to use multiple compilers with waf (Python)) but with no suitable answer.

like image 659
user69453 Avatar asked Jan 23 '26 18:01

user69453


1 Answers

Well, the way to go with waf in this case is "variants" (Cf. the waf book §7.2.2). As gcc is usually the default compiler, I create a variant for each other compiler, and a corresponding set of commands and environments. In practise:

def options(opt):
    opt.load('compiler_c')

def configure(conf):

    # here we are in default variant/env
    # we load the default compiler, probably gcc

    conf.load('compiler_c')

    # config for clang variant

    conf.setenv('clang')
    conf.env.CC = ['clang']
    conf.load('compiler_c')

    # config for icc variant

    conf.setenv('icc')
    conf.env.CC = ['icc']
    conf.load('compiler_c')

    # back to default config

    conf.setenv('')

def build(bld):

    bld.program(source = 'main.c', target = 'myexe')

# this create variants commands and build directories

from waflib.Build import BuildContext, \
    CleanContext, InstallContext, UninstallContext

for variant in ['clang', 'icc']:
    for context in [BuildContext, CleanContext, InstallContext, UninstallContext]:
        name = context.__name__.replace('Context','').lower()
        class tmp(context):
            cmd = name + '_' + variant
            variant = variant

What you get: extra commands build_icc, build_clang, clean_icc, clean_clang, ... A directory for each variant, namely build/icc and build/clang and of course your exe build with the corresponding compiler.

To test:

waf build -v        # use gcc, or the default compiler
waf build_icc -v    # use icc
waf build_clang -v  # use clang

You will get:

build/
├── c4che
│   ├── build.config.py
│   ├── _cache.py
│   ├── clang_cache.py
│   └── icc_cache.py
├── clang
│   ├── main.c.1.o
│   └── myexe
├── icc
│   ├── main.c.1.o
│   └── myexe
├── config.log
├── main.c.1.o
└── myexe

Notice the default variant is in the root build directory. Its cache file is c4che/_cache.py. Each variant has a directory and a cache named ater its name.

like image 186
neuro Avatar answered Jan 25 '26 09:01

neuro



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!