1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
##############################################################################
#
# Copyright (c) 2003-2016 by The University of Queensland
# http://www.uq.edu.au
#
# Primary Business: Queensland, Australia
# Licensed under the Apache License, version 2.0
# http://www.apache.org/licenses/LICENSE-2.0
#
# Development until 2012 by Earth Systems Science Computational Center (ESSCC)
# Development 2012-2013 by School of Earth Sciences
# Development from 2014 by Centre for Geoscience Computing (GeoComp)
#
##############################################################################
"""SCons.Tool.nvcc
Tool-specific initialization for NVIDIA CUDA Compiler.
There normally shouldn't be any need to import this module directly.
It will usually be imported through the generic SCons.Tool.Tool()
selection method.
"""
from __future__ import print_function, division
import SCons.Tool
import SCons.Scanner.C
import SCons.Defaults
import os
import platform
def get_cuda_paths():
"""Determines CUDA {bin,lib,include} paths
returns (bin_path,lib_path,inc_path)
"""
# determine defaults
if os.name == 'nt':
bin_path = 'C:/CUDA/bin'
lib_path = 'C:/CUDA/lib'
inc_path = 'C:/CUDA/include'
elif os.name == 'posix':
bin_path = '/usr/local/cuda/bin'
lib_path = '/usr/local/cuda/lib'
inc_path = '/usr/local/cuda/include'
else:
raise ValueError, 'Error: unknown OS. Where is nvcc installed?'
if platform.machine()[-2:] == '64':
lib_path += '64'
# override with environement variables
if 'CUDA_BIN_PATH' in os.environ:
bin_path = os.path.abspath(os.environ['CUDA_BIN_PATH'])
if 'CUDA_LIB_PATH' in os.environ:
lib_path = os.path.abspath(os.environ['CUDA_LIB_PATH'])
if 'CUDA_INC_PATH' in os.environ:
inc_path = os.path.abspath(os.environ['CUDA_INC_PATH'])
return (bin_path,lib_path,inc_path)
CUDASuffixes = ['.cu']
# make a CUDAScanner for finding #includes
# cuda uses the c preprocessor, so we can use the CScanner
CUDAScanner = SCons.Scanner.C.CScanner()
def add_common_nvcc_variables(env):
"""
Add underlying common "NVIDIA CUDA compiler" variables that
are used by multiple builders.
"""
# "NVCC common command line"
if not env.has_key('_NVCCCOMCOM'):
# nvcc needs '-I' prepended before each include path, regardless of platform
env['_NVCCWRAPCPPPATH'] = '${_concat("-I ", CPPPATH, "", __env__)}'
# prepend -Xcompiler before each flag
env['_NVCCWRAPCFLAGS'] = '${_concat("-Xcompiler ", CFLAGS, "", __env__)}'
env['_NVCCWRAPSHCFLAGS'] = '${_concat("-Xcompiler ", SHCFLAGS, "", __env__)}'
env['_NVCCWRAPCCFLAGS'] = '${_concat("-Xcompiler ", CCFLAGS, "", __env__)}'
env['_NVCCWRAPSHCCFLAGS'] = '${_concat("-Xcompiler ", SHCCFLAGS, "", __env__)}'
# assemble the common command line
env['_NVCCCOMCOM'] = '${_concat("-Xcompiler ", CPPFLAGS, "", __env__)} $_CPPDEFFLAGS $_NVCCWRAPCPPPATH'
def generate(env):
"""
Add Builders and construction variables for CUDA compilers to an Environment.
"""
# create a builder that makes PTX files from .cu files
ptx_builder = SCons.Builder.Builder(action = '$NVCC -ptx $NVCCFLAGS $_NVCCWRAPCFLAGS $NVCCWRAPCCFLAGS $_NVCCCOMCOM $SOURCES -o $TARGET',
emitter = {},
suffix = '.ptx',
src_suffix = CUDASuffixes)
env['BUILDERS']['PTXFile'] = ptx_builder
# create builders that make static & shared objects from .cu files
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
for suffix in CUDASuffixes:
# Add this suffix to the list of things buildable by Object
static_obj.add_action('$CUDAFILESUFFIX', '$NVCCCOM')
shared_obj.add_action('$CUDAFILESUFFIX', '$SHNVCCCOM')
static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)
# Add this suffix to the list of things scannable
SCons.Tool.SourceFileScanner.add_scanner(suffix, CUDAScanner)
add_common_nvcc_variables(env)
# set the "CUDA Compiler Command" environment variable
# windows is picky about getting the full filename of the executable
if os.name == 'nt':
env['NVCC'] = 'nvcc.exe'
env['SHNVCC'] = 'nvcc.exe'
else:
env['NVCC'] = 'nvcc'
env['SHNVCC'] = 'nvcc'
# set the include path, and pass both c compiler flags and c++ compiler flags
env['NVCCFLAGS'] = SCons.Util.CLVar('')
env['SHNVCCFLAGS'] = SCons.Util.CLVar('') + ' -shared'
# 'NVCC Command'
env['NVCCCOM'] = '$NVCC -ccbin=g++-4.8 -o $TARGET -c $NVCCFLAGS $_NVCCWRAPCFLAGS $NVCCWRAPCCFLAGS $_NVCCCOMCOM $SOURCES'
env['SHNVCCCOM'] = '$SHNVCC -ccbin=g++-4.8 -o $TARGET -c $SHNVCCFLAGS $_NVCCWRAPSHCFLAGS $_NVCCWRAPSHCCFLAGS $_NVCCCOMCOM $SOURCES'
# the suffix of CUDA source files is '.cu'
env['CUDAFILESUFFIX'] = '.cu'
# XXX add code to generate builders for other miscellaneous
# CUDA files here, such as .gpu, etc.
# XXX intelligently detect location of nvcc and cuda libraries here
(bin_path,lib_path,inc_path) = get_cuda_paths()
env.PrependENVPath('PATH', bin_path)
def exists(env):
return env.Detect('nvcc')
|