【问题标题】:Include a generated header file using a relative path使用相对路径包含生成的头文件
【发布时间】:2021-06-17 16:20:49
【问题描述】:

目前,我尝试使用 Bazel (5.1.0) 构建一个最初使用 CMake 作为构建系统的库。

我在尝试使用相对路径包含生成的头文件时遇到问题(在 CMake 构建中它使用 configure_file):

(下面的例子也可以找到here

WORKSPACE.bazel

workspace(name = "TemplateRule")

main.cpp

#include "kernels/bvh/some_header.h"
#include <iostream>

int main() {
    std::cout << VERSION_STR << std::endl;
}

kernels/bvh/some_header.h

#pragma once

// include config.h using a relative path
// if changed to kernels/config.h everything works as expected
// unfortunately, this is legacy code that I cannot change
#include "../config.h"    

config.h.in

#pragma once

#define VERSION_STR "@VERSION_STR@"

BUILD.bazel

load("//bazel:expand_template.bzl", "expand_template")

expand_template(
    name = "config_h",
    template = "config.h.in",
    out = "kernels/config.h",
    substitutions = {
        "@VERSION_STR@": "1.0.3",
    },
)

cc_binary(
    name = "HelloWorld",
    srcs = [
        "main.cpp",
        "kernels/bvh/some_header.h",
        ":config_h",
    ],
)

bazel/BUILD.bazel

bazel/expand_template.bzl

# Copied from https://github.com/tensorflow/tensorflow/blob/master/third_party/common.bzl with minor modifications
# SPDX-License-Identifier: Apache-2.0

def expand_template_impl(ctx):
    ctx.actions.expand_template(
        template = ctx.file.template,
        output = ctx.outputs.out,
        substitutions = ctx.attr.substitutions,
    )

_expand_template = rule(
    implementation = expand_template_impl,
    attrs = {
        "template": attr.label(mandatory = True, allow_single_file = True),
        "substitutions": attr.string_dict(mandatory = True),
        "out": attr.output(mandatory = True),
    },
    output_to_genfiles = True,
)

def expand_template(name, template, substitutions, out):
    _expand_template(
        name = name,
        template = template,
        substitutions = substitutions,
        out = out,
    )

当我运行bazel build //...

我得到错误:

In file included from main.cpp:1:
kernel/some_header.h:3:10: fatal error: ../config.h: No such file or directory
    3 | #include "../config.h"
      |          ^~~~~~~~~~~~~

当我在 main.cpp 中包含 config.h 并将其从 kernel/bvh/some_header.h 中删除时,一切都按预期工作。

任何想法如何使相对路径.../config.h 工作?

创建文件config.h 并手动编译代码按预期工作:

g++  main.cpp kernel/bvh/some_header.h config.h

根据Best Practices 的相对路径,应避免使用..,但您可以在使用CMake 构建的遗留代码中找到此类内容。这是巴泽尔的限制吗?还是有解决方法?

【问题讨论】:

    标签: c++ include bazel bazel-rules


    【解决方案1】:

    虽然使用引号时搜索文件的行为和顺序在技术上是平台定义的,但最常见的原则是使用路径相对于发生包含的文件。对于kernel/bvh/some_header.h,路径../config.h 将导致仅在kernel 文件夹中搜索,不会检查工作文件夹或kernel/bvh/。一些编译器检查替代位置。搜索顺序是编译器文档的一部分。

    我曾经在这样的情况下看到在另一个标题 kernel.h 中使用 ../../config.h 并且它起作用了。这是维护责任。 kernel.h 被移动到不同的位置,它选择了错误的文件夹和错误的文件,这导致 ODR 在项目时间线的后期出现。采取行动的人将../../config.h 留在原地并制作了一份副本。一些单位使用旧的标头,而另一些则开始在新位置使用修改后的标头。

    因此,不建议在库基础架构之外使用反向相对路径。而是部分相对路径,例如kernel/config.h 是首选,假设核心文件夹将在包含路径列表中。在实践中,实际项目可以使用预处理器宏,例如#include KERNEL_CONFIG_FILE。在freetype、boost等中可以看到插图。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-21
      • 2011-12-08
      • 1970-01-01
      • 2021-07-11
      • 2013-04-09
      • 2014-11-15
      • 2013-05-25
      • 2011-04-29
      相关资源
      最近更新 更多