我正在尝试为GSL编写一个bazel构建
问题是它在子文件夹中有各种gsl_*.h头文件,但它们总是作为#include <gsl/gsl_somename.h>
包含在其中,例如,位于gsl/err/gsl_errno.h中的头gsl_errno.h包含在#include <gsl/gsl_errno.h>
中,而位于gsl/gsl_math.h中的gsl_math.h
也包含在#include <gsl/gsl_math.h>
中。
我尝试为每个文件夹创建一个单独的cc_library,并使用strip_include_prefix
和include_prefix
,如下所示:
cc_library(
name = "gsl_sys",
visibility = ["//visibility:public"],
srcs = [
"sys/minmax.c",
"sys/prec.c",
"sys/hypot.c",
"sys/log1p.c",
"sys/expm1.c",
"sys/coerce.c",
"sys/invhyp.c",
"sys/pow_int.c",
"sys/infnan.c",
"sys/fdiv.c",
"sys/fcmp.c",
"sys/ldfrexp.c",
],
hdrs = glob(
include = ["sys/*.h"],
),
strip_include_prefix = "sys/",
include_prefix = "gsl/",
)
但问题是,如果我使用文件夹,则存在循环依赖(例如,gsl/gsl_math.h包含gsl/sys/gsl_sys.h,但gsl/sys中的一些文件包含位于gsl/根文件夹中的gsl_*.h文件。
我认为最好我应该有一个包含所有gsl_*.h文件的cc_library,但这样它们都可以作为#include <gsl/gsl_*.h>
访问,而不管它们在哪个子文件夹中。
我怎样才能做到这一点呢?
发布于 2020-08-13 05:35:23
我会将它们全部复制到一个新文件夹中,然后将这些新复制的版本用于您的cc_library
。genrule是完成此操作的最简单方法。在顶层的构建文件中类似这样(不要将构建文件放在任何子文件夹中;您希望所有文件都放在同一个包中,这样一条规则就可以处理所有文件):
# You could list all the headers instead of the glob, or something
# similar, if you only want a subset of them.
all_headers = glob(["gsl/*/*.h"])
# This is the logic for actually remapping the paths. Consider a macro
# instead of writing it inline like this if it gets more complicated.
unified_header_paths = ["unified_gsl/" + p.split("/")[-1] for p in all_headers]
genrule(
name = "unified_gsl"
srcs = all_headers,
outs = unified_header_paths,
cmd = "\n".join(["cp $(location %s) $(location %s)" %
(src, dest) for src, dest in zip(all_headers, unified_header_paths)]),
)
文件在复制后会像这样结束:
unified_gsl/gsl/gsl_math.h
unified_gsl/gsl/gsl_sys.h
然后你可以像这样写一个cc_library:
cc_library(
name = "gsl_headers",
hdrs = [":unified_gsl"],
strip_include_prefix = "unified_gsl/",
)
cc_library.hdrs
正在查找文件,因此它将从genrule
获取所有输出。
如果您想对文件执行比移动文件更复杂的操作,可以考虑使用完整的custom rule。如果您在DefaultInfo.files
中包含了所有复制的标头,那么只需将目标的标签传递给cc_library.hdrs
就可以像使用genrule一样工作。
https://stackoverflow.com/questions/63347234
复制相似问题