c++ - 使用 CUDA/自定义语言和 $(eval) 规则创建的 automake

标签 c++ cuda eval gnu-make automake

我需要构建一些混合纯 C 文件和 CUDA 文件的内部库。此外,可以使用不同的预处理器选项从相同的源构建不同的库。

我已经设法得到一些有用的东西,但发生的情况是我不喜欢这样的事实:当可以轻松地从 _SOURCES var 推断出 CUDA 对象时,我必须显式定义它们:

$cat Makefile.am

AUTOMAKE_OPTIONS = foreign

NVCC=cc
cuda_libs = libfoobar1.a libfoobar2.a

noinst_LIBRARIES = $(cuda_libs)

foobar_sources = foo.c bar.cu
libfoobar1_a_SOURCES  = $(foobar_sources)
libfoobar1_a_CPPFLAGS = -DLIB1
libfoobar1_a_LIBADD   = libfoobar1_a-bar.o # CUDA object explicit definition 
libfoobar2_a_SOURCES  = $(foobar_sources)
libfoobar2_a_CPPFLAGS = -DLIB2
libfoobar2_a_LIBADD   = libfoobar2_a-bar.o # CUDA object explicit definition 

$(eval include cuda.mk) # why eval? Check comment #1

clean-local:
    rm -rf libfoobar2_a-bar.o libfoobar1_a-bar.o

$猫cuda.mk

# $(get_conincal names)
get_canonical = $(subst .,_,$(1))

# $(call cuda_rule prefix) http://blog.jgc.org/2012/01/using-gnu-makes-define-and-eval-to.html
define cuda_rule
$(1)-%.o: %.cu
    $(NVCC) $(CUDA_CFLAGS) $($(1)_CPPFLAGS) --compiler-options="$($(1)_CFLAGS)" -c -o $$@ $$<
endef

$(foreach cuda_prefix,$(call get_canonical,$(cuda_libs)),$(eval $(call cuda_rule,$(cuda_prefix))))

如果我尝试概括 CUDA 对象定义,将它们移动到规则生成中,如下所示:

define cuda_rule
$(1)_LIBADD = $(addsuffix .o,$(addprefix $(1)-,$(basename $(filter %.cu,$($(1)_SOURCES)))))
[...]
endef

make 现在似乎没有掌握规则,并且不知道如何构建 CUDA 对象:

ar cru libfoobar1.a libfoobar1_a-foo.o libfoobar1_a-bar.o
ar: libfoobar1_a-bar.o: No such file or directory

有什么想法吗? 提前致谢。

阿尔伯特

附注All files如果你想玩这个,你需要它

最佳答案

这都是关于如何读取 Makefile 和如何扩展变量的。

检查 automake 生成的 Makefile 可以看到 $eval 调用最终出现在 Makefile 的末尾。最终 Makefile 中的顺序似乎是:AM 变量、用户变量、AM 规则,最后是用户规则。当我们修改 AM 规则的先决条件时,我们必须在解析规则本身之前完成此操作,因为规则先决条件会立即扩展。

A rule is always expanded the same way, regardless of the form:

immediate : immediate ; deferred

         deferred

https://www.gnu.org/software/make/manual/html_node/Reading-Makefiles.html

由于 eval 函数始终为空字符串,因此我们可以将其分配给一次性变量,强制立即扩展。然后,它将与用户变量一起放置在最终 Makefile 中的 AM 规则定义之前。

ignore:=$(eval include cuda.mk)

关于c++ - 使用 CUDA/自定义语言和 $(eval) 规则创建的 automake,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33895351/

相关文章:

javascript - 在 Firefox 中使用 eval 方法从字符串中获取类

actionscript-3 - AS3 中的评估公式?

ruby - 如何获取传递给 eval 方法的 block 的返回值?

c++ - 纹理在 opengl 中显示为白色

c++ - 客户端主题列表的数据结构

CMake v3.4.1 在 Ubuntu 16.04 上找到 CUDA 7.5 而不是 CUDA 8.0

cuda - 如何实现设备端CUDA虚拟功能?

c++ - 在 Clang 中使用 MSVC 预处理器 'charizing' 运算符

c++ - "Member is private"虽然我不从外部访问它,但在使用尾随返回类型时

c - 为什么我的程序没有错误地停止工作?