使用 CUDA/custom 语言和 $(eval) 规则创建的 automake
automake with CUDA/custom language and $(eval) rule creation
我需要构建一些混合纯 C 文件和 CUDA 文件的内部库。此外,可以使用不同的预处理器选项从相同的源构建不同的库。
我已经设法得到一些有用的东西,但发生的事情是我不喜欢 我必须显式定义 CUDA 对象,因为它们可以很容易地从 _SOURCES 中推断出来变量:
$猫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
有什么想法吗?
提前致谢。
阿尔伯特
P.S。 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 文件的内部库。此外,可以使用不同的预处理器选项从相同的源构建不同的库。
我已经设法得到一些有用的东西,但发生的事情是我不喜欢 我必须显式定义 CUDA 对象,因为它们可以很容易地从 _SOURCES 中推断出来变量:
$猫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
有什么想法吗? 提前致谢。
阿尔伯特
P.S。 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)