3

我们有一个使用自定义对象关系映射系统的 C++ 项目,其中表由 .tbl 文件定义。然后通过代码生成器运行这些代码生成器,该代码生成器为每个生成一个 .h 和一个 .cpp 文件。

我正在尝试在 Visual Studio 2008 和 2010 中使用自定义构建规则。

到目前为止,这就是我所拥有的:

<?xml version="1.0" encoding="utf-8"?>
<VisualStudioToolFile
    Name="z_dbbld"
    Version="8.00"
    >
    <Rules>
        <CustomBuildRule
            Name="z_dbbld"
            DisplayName="z_dbbld"
            CommandLine="$(SolutionDir)\tools\z_dbbld $(InputName)"
            Outputs="$(InputName).cpp"
            FileExtensions="*.tbl"
            ExecutionDescription="z_dbbld  $(InputName)"
            >
            <Properties>
            </Properties>
        </CustomBuildRule>
    </Rules>
</VisualStudioToolFile>

问题是依赖关系。当我在不存在任何文件的干净签出上运行构建时,对于由此规则生成的 .h 文件,我收到“无法打开包含文件”错误。

我尝试将输出更改为“$(InputName).h”,但仍然出现错误。

现在的问题是,这些文件是在代码生成器运行时创建的。如果我再次编译,我没有错误,因为所有文件都是在第一遍中创建的。但这使得从新结帐中进行干净,自动化的构建不起作用。

有任何想法吗?

4

2 回答 2

0

sblom 给出的答案是正确的,但是并没有说明原因。

对于每个构建规则(自定义或本地),VS 构建系统需要知道输入和输出的完整列表,以便它可以决定需要构建项目的哪个部分。

您的构建规则将生成的 .cpp 文件声明为输出,因此 VS 知道它并会自动为您构建此文件。由于您省略了头文件,VS 不知道它,因此任何包含此头文件的源文件都不知道从哪里获取它并且无法构建。在这种情况下使构建工作的解决方法是将这个 .h 文件所在的目录添加到您的包含路径中,然后该文件的#includes 将起作用。您基本上是在让 VS 以不同的方式了解此文件。

相反,如果您更改构建规则以将头文件声明为输出,则包含它的源文件将知道从何处获取此文件,但现在 VS 不知道您的 .cpp 文件,因此它不会构建它。这种情况的解决方法是将生成的 .cpp 文件作为源文件显式添加到您的项目中。与上述情况一样,您正在使用一种技巧来让构建系统识别生成的文件。

但是,虽然上面的解决方法会让你继续前进,但它们并不是最好的解决方案,因为它们只是弥补了 VS 不知道文件的情况。解决此问题的最佳方法是在规则中将 .cpp 和 .h 文件声明为输出,并用分号分隔它们。这将使 VS 能够对这两个文件应用正确的行为。

于 2011-10-23T18:08:16.940 回答
0

我认为您需要在构建的主要部分中指定输出文件(查看http://msdn.microsoft.com/en-us/library/hefydhhy.aspx的最后一句话)。可能最简单的方法是在文件存在时添加对文件的引用,然后删除它们并查看 codegen 步骤是否按应有的方式运行。

于 2011-10-21T07:25:39.513 回答