开发者

Custom Build Rules in Visual Studio, with multiple outputs

We have a C++ project that uses a custom object-relational-mapping system, in which tables are defined by .tbl files. These are then run through a code-generator that creates, for each, a .h and a .cpp file.

I'm trying to get a custom build rule working for this, in Visual Studio 2008 and 2010.

This is what I have, so far:

<?xml version="1.0" encoding="utf-8"?>
<VisualStudioToolFile
    Name="z_dbbld"
    Ver开发者_如何学JAVAsion="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>

The problem is the dependencies. When I run a build on a clean checkout, where none of the files exist, I get "Cannot open include file" errors, for .h files that are generated by this rule.

I've tried changing Outputs to "$(InputName).h", and I still get the errors.

Now the thing is that these files are created, when the code generator runs. If I compile again, I don't have the errors, because all of the files were created in the first pass. But it makes doing a clean, automated, build from fresh checkout not work.

Any ideas?


I think you need to specify the Output files in the main part of the build (looking at the very last sentence of http://msdn.microsoft.com/en-us/library/hefydhhy.aspx). Probably the easiest way to do that is to add a reference to the files when they exist and then delete them and see if the codegen step runs like it should.


The answer given by sblom is correct, but it does not explain the reason.

For each build rule (custom or native) the VS build system needs to know the complete list of inputs and outputs so that it can decide what part of the project needs to be built.

Your build rule declares the generated .cpp file as an output, so VS knows about it and will automatically build this file for you. Since you omitted the header file, VS does not know about it, so any source files that include this header will not know where to get it from and fail to build. A work around to get the build to work in this situation is to add the directory where this .h file is located to your include path, and then #includes of this file will work. You are basically enabling VS to know about this file in a different way.

Conversely, if you change your build rule to declare the header file as output, then source files that include it will know where to get this file from, but now VS does not know about your .cpp file so it won't build it. A work around for this case is to explicitly add the generated .cpp file to your project as a source file. Like in the above case, you are using a trick to get the build system to recognize the generated file.

But while the workarounds above will get you going they are not the best solution, since they just compensate for VS not knowing about a file. The best way to address this problem is to declare both the .cpp and the .h files as outputs in your rule, separating them with a semi-colon. This will enable VS to apply the correct behavior to both files.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜