CUDA build tool for SCons

SCons is a really nice make replacement that allows you to describe your build process in a Python script.

I’ve attached a script that allows SCons to recognize CUDA files and automatically compile and link them correctly with nvcc and gcc. It’s also easy to do common things such as target different builds like emurelease, emudebug, etc.

Here’s an example SCons script that will build the simpleGL example in the SDK:

# create a SCons environment

env = Environment()

# direct SCons to the nvcc.py script

env.Tool('nvcc', toolpath = ['/home/jared/dev/src/cudascons/'])

# add the CUDA SDK include path to the CPPPATH

env.Append(CPPPATH = ['/home/jared/NVIDIA_CUDA_SDK/common/inc'])

# add the CUDA library paths to the LIBPATH

env.Append(LIBPATH Â = ['/home/jared/NVIDIA_CUDA_SDK/lib',

 Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  Â  '/usr/local/cuda/lib'])

# link to glut, glew, the cuda runtime, and the cuda utility libraries

env.Append(LIBS = ['glut', 'GLEW', 'cudart', 'cutil'])

# now create the simpleGL program

env.Program('simpleGL', 'simpleGL.cu')

To try out the example, assuming you have installed the NVIDIA CUDA SDK, download and unzip nvcc.py.zip, putting nvcc.py somewhere in your file system. Next, download SConstruct and put it in the NVIDIA_CUDA_SDK/projects/simpleGL directory. This file serves as a makefile. Edit line #5 of SConstruct to point to the directory containing nvcc.py, and lines #8 & #11 to point to the location of the SDK inc and lib directories.

Next, install SCons. If you are on a Debian-based system like Ubuntu, you can run

sudo apt-get install scons

from the command line to automatically install SCons.

To build simpleGL, run “scons” from the simpleGL directory and it should build in release mode. To build in a different mode, like emudebug, run “scons mode=emudebug”.

nvcc.py assumes CUDA is installed to ‘/usr/local/cuda’. If it is installed in a different location on your system, edit lines 81 & 84 of nvcc.py to point to the appropriate location.

Find out more about SCons here.

Edit: Fixed SharedLibrary bug.

Edit 2: Fixed SharedLibrary bug in SCons v 0.98.1 and higher.
nvcc.py.zip (1.34 KB)
SConstruct.zip (611 Bytes)

Awesome!

I was afraid Id either have to hack together my own makefiles or go after the beast that is autotools…

Thanks!

Great!!!

Seems like we CUDA developers have one more option to code beyond traditional makefiles…

I haven’t used SCons yet but heard that it’s a pretty advanced script-based build system. Anyway people can choose from CMake and SCons for new CUDA development. Thanks a lot!

Very nice. Building with scons in less than 5 minutes. Sure beats tinking with Makefiles.

Thanks

I seem to have trouble building a SharedLibrary() with this tool. scons builds .os intermediate targets and then complains that they’re not appropriate shared sources to build a .so.

I’m not sure whether my SConstruct is b0rken, or what. Can anyone confirm that they’ve done this using the given tool?

BTW, this is extremely useful, thanks. I probably never would have gotten around to writing this build tool.

You’re right, what I originally posted was broken. The fixed version is attached to this post.
nvcc.py.zip (1.24 KB)

Hmm…That didn’t do it. In fact, it looks worse now. :(

Here’s a simple example which might illustrate the problem. If I get a chance, I’ll start tinkering with nvcc.py to see if it’s something obvious.
nvcc_scons.zip (1.13 KB)

I tried your example on my system, and it builds ok. Can you post the error messages you’re seeing?

Here’s my output:

jared@filthy:~/Desktop/nvcc_scons$ scons

scons: Reading SConscript files ...

scons: done reading SConscript files.

scons: Building targets ...

nvcc -o minimal.os -c -shared -Xcompiler -O3 -Xcompiler -fPIC -I/usr/local/cuda_sdk/common/inc minimal.cu

"minimal.cu", line 12: warning: variable "i" was declared but never referenced

      int i = 12;

          ^

gcc -o libminimal.so -shared minimal.os -L/home/jared/NVIDIA_CUDA_SDK/lib -L/usr/local/cuda/lib -lcudart -lcutil

scons: done building targets.

Ok. I was getting these errors, with your most recent nvcc.py:

$ scons -c && scons

scons: Reading SConscript files ...

scons: done reading SConscript files.

scons: Cleaning targets ...

Removed minimal.os

Removed libminimal.so

scons: done cleaning targets.

scons: Reading SConscript files ...

scons: done reading SConscript files.

scons: Building targets ...

nvcc -o minimal.os -c -shared -Xcompiler -O3 -Xcompiler -fPIC -Xcompiler [] -Xcompiler -fPIC -I/usr/local/cuda_sdk/common/inc minimal.cu

gcc: []: No such file or directory

scons: *** [minimal.os] Error 255

scons: building terminated because of errors.

I’m kinda surprised that you didn’t encounter this problem. You had to change the SConstruct to point to your include and/or lib directories. Did you make any other changes?

Anyways, I thought this problem might be because I didn’t define any SHCXXFLAGS in my environment in SConstruct, or it was defaulting to an empty list, or something. So I just shoved in a kludge to nvcc.py (commenting out the usage of SHCXXFLAGS):

#   env['_NVCCWRAPSHCXXFLAGS'] = '${_concat("-Xcompiler ", SHCXXFLAGS, "", __env__)}'

So after that change, it works:

$ scons

scons: Reading SConscript files ...

scons: done reading SConscript files.

scons: Building targets ...

nvcc -o minimal.os -c -shared -Xcompiler -O3 -Xcompiler -fPIC -I/usr/local/cuda_sdk/common/inc minimal.cu

"minimal.cu", line 12: warning: variable "i" was declared but never referenced

      int i = 12;

          ^

gcc -o libminimal.so -shared minimal.os -L/usr/local/cuda_sdk/lib -L/usr/local/cuda/lib -lcudart -lcutil

scons: done building targets.

I suppose it’s not the appropriate change, but I can live with it for now. I was considering changing it to not assign to env[‘_NVCCWRAPSHCXXFLAGS’] if SHCXXFLAGS is an empty list. Or to assign an empty string. Neither of these options seem quite right. Whatever change needs to be made, it should probably apply to each of these properties.

I haven’t gotten a chance to look at TFM to see what a more appropriate solution might be.

On the off chance that this is a bug outside of nvcc.py and SConstruct, here are some details about my system:

$ rpm -qa | egrep 'python-2.5|scons'

scons-0.98.0-1.fc8

python-2.5.1-15.fc8

$ cat /etc/redhat-release

Fedora release 8 (Werewolf)

$ cat /proc/version

Linux version 2.6.23.1-42.fc8 (kojibuilder@xenbuilder2.fedora.redhat.com) (gcc version 4.1.2 20070925 (Red Hat 4.1.2-33)) #1 SMP Tue Oct 30 13:18:33 EDT 2007

Looks like you have a newer version of scons than I do:

jared@filthy:~/Desktop/nvcc_scons$ scons -version

SCons by Steven Knight et al.:

        script: v0.97.D001, 2007/05/17 11:35:19, by knight on roxbury

        engine: v0.97.D001, 2007/05/17 11:35:19, by knight on roxbury

Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation

You’re right that the bug is occuring because that scons macro is trying to wrap an empty list and is producing something weird.

This behavior is probably present in the newer version of scons you have. I’ll upgrade and post a fix if I find one; please do the same if you get to it :ph34r:

Any updates?

I can repro the SharedLibrary bug with scons 0.98.0-1:

jared@filthy:~/Desktop/nvcc_scons$ scons --version

SCons by Steven Knight et al.:

        engine: v0.98.0.r2725, 2008/03/31 12:52:02, by knight on bangkok

Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation

jared@filthy:~/Desktop/nvcc_scons$ scons

scons: Reading SConscript files ...

scons: done reading SConscript files.

scons: Building targets ...

nvcc -o minimal.os -c -shared -Xcompiler -O3 -Xcompiler [] -Xcompiler -fPIC -I/usr/local/cuda_sdk/common/inc minimal.cu

gcc: []: No such file or directory

scons: *** [minimal.os] Error 255

scons: building terminated because of errors.

jared@filthy:~/Desktop/nvcc_scons$

The behavior is correct in the current version of scons (0.98.2)

The fixed script I’ve attached to the OP gives the correct behavior for shared objects in scons 0.98.1 and higher:

jared@filthy:~/Desktop/nvcc_scons$ scons --version && scons

SCons by Steven Knight et al.:

        script: v0.98.1.r2881, 2008/04/18 19:20:28, by knight on bangkok

        engine: v0.98.1.r2881, 2008/04/18 19:20:28, by knight on bangkok

Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation

scons: Reading SConscript files ...

scons: done reading SConscript files.

scons: Building targets ...

nvcc -o minimal.os -c -shared -Xcompiler -O3 -Xcompiler -fPIC -I/usr/local/cuda_sdk/common/inc minimal.cu

"minimal.cu", line 12: warning: variable "i" was declared but never referenced

      int i = 12;

          ^

gcc -o libminimal.so -shared minimal.os -L/home/jared/NVIDIA_CUDA_SDK/lib -L/usr/local/cuda/lib -lcudart -lcutil

scons: done building targets.

thanks for the bug reports

It doesnt work for me with template, transpose example:

Paths are correct i have checke many times.

[codebox]

scons: Reading SConscript files …

scons: done reading SConscript files.

scons: Building targets …

nvcc -o template.o -c -I/usr/people/nickel/NVIDIA_CUDA/cudasdk/common/inc template.cu

nvcc -o template_kernel.o -c -I/usr/people/nickel/NVIDIA_CUDA/cudasdk/common/inc template_kernel.cu

template_kernel.cu(68): error: identifier “cutilBankChecker” is undefined

1 error detected in the compilation of “/tmp/tmpxft_00001932_00000000-4_template_kernel.cpp1.ii”.

scons: *** [template_kernel.o] Error 255

scons: building terminated because of errors.

[/codebox]

if I add

[codebox]

#include <cutil_inline.h>

[/codebox]

to template_kernel.o

i get following error:

[codebox]scons: Reading SConscript files …

scons: done reading SConscript files.

scons: Building targets …

g++ -o template template.o template_kernel.o template_gold.o -L/usr/people/nickel/NVIDIA_CUDA/cudasdk/lib -L/usr/local/cuda/lib -lcudart -lcutil

template_kernel.o: In function `_device_stub__Z10testKernelPfS’:

tmpxft_00001992_00000000-11_template_kernel.ii:(.text+0x6c88): multiple definition of `_device_stub__Z10testKernelPfS

template.o:tmpxft_00001956_00000000-11_template.ii:(.text+0x6c88): first defined here

collect2: ld returned 1 exit status

scons: *** [template] Error 1

scons: building terminated because of errors.[/codebox]

its the same error when i do a manual complie

[codebox] g++ -c template_gold.cpp -I/usr/people/nickel/NVIDIA_CUDA/cudasdk/common/inc -I/usr/local/cuda/include -lcudart -lcutil -L/usr/people/nickel/NVIDIA_CUDA/cudasdk/common/lib -L/usr/people/nickel/NVIDIA_CUDA/cudasdk/lib -L/usr/local/cuda/lib -lcudart

/usr/local/cuda/bin/nvcc -c template.cu -I/usr/people/nickel/NVIDIA_CUDA/cudasdk/common/inc -I/usr/local/cuda/include -lcutil -lcuda -lcudart -lcutil -L/usr/people/nickel/NVIDIA_CUDA/cudasdk/common/lib -L/usr/people/nickel/NVIDIA_CUDA/cudasdk/lib -L/usr/local/cuda/lib

/usr/local/cuda/bin/nvcc -c template_kernel.cu -I/usr/people/nickel/NVIDIA_CUDA/cudasdk/common/inc -I/usr/local/cuda/include -lcutil -lcuda -L/usr/people/nickel/NVIDIA_CUDA/cudasdk/lib/ -L/usr/people/nickel/NVIDIA_CUDA/cudasdk/common/lib/ -L/usr/local/cuda/lib -lcudart

g++ -fPIC -o template template.o template_kernel.o template_gold.o -lcudart -lcutil -L/usr/people/nickel/NVIDIA_CUDA/cudasdk/common/lib -L/usr/people/nickel/NVIDIA_CUDA/cudasdk/lib -L/usr/local/cuda/lib

template_kernel.o: In function `_device_stub__Z10testKernelPfS’:

tmpxft_00001850_00000000-11_template_kernel.ii:(.text+0x6c88): multiple definition of `_device_stub__Z10testKernelPfS

template.o:tmpxft_00001810_00000000-11_template.ii:(.text+0x6c88): first defined here

collect2: ld returned 1 exit status

[/codebox]

Why do I get this?

Why doesnt work manual compile?