LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

CVI2013: _TARGET_PRODUCT_VERSION_ and _TARGET_FILE_VERSION_ troubles

I've just noticed another strange behaviour of CVI 2013, and it's related with precompiled headers (am I the only user of this feature?).

 

It's very simple to trigger:

  •  Set up any project for using precompiled headers
  • Set in Target Settings -> Version Info a version number with auto increment (e.g. 1.0.0.0+) for both file version and product version fields, for the release configuration.
  • Rebuild the "release" configuration, so to have all files recompiled.
  • Modify any source that does not trigger precompiled header recompilation
  • Build the project.

 

Then the build will terminate with this error messages:

...
 main.c - 2 errors, 2 warnings
  1, 1   error: definition of the macro '_TARGET_FILE_VERSION_' conflicts with the definition used to build the precompiled header
      1, 1   <built-in>:162:1: note: definition of macro '_TARGET_FILE_VERSION_' in the precompiled header
  1, 1   error: definition of the macro '_TARGET_PRODUCT_VERSION_' conflicts with the definition used to build the precompiled header
      1, 1   <built-in>:163:1: note: definition of macro '_TARGET_PRODUCT_VERSION_' in the precompiled header
Build failed.

As additional  information please note that there is no reference to _TARGET_PRODUCT_VERSION_  and _TARGET_FILE_VERSION_ macros.

 

The reason is obvious: the precompiled header retains the old values of these variables.

I don't have found any workaround but to stop using the auto-increment feature.

 

Carlo A.
Megaris




0 Kudos
Message 1 of 12
(5,371 Views)

Hello carlox,

 

I have opened report #429548 to track this issue. We will investigate and fix it in a future version. 

I think I can suggest a possible workaround other than to stop using the auto-increment feature: doing a rebuild of the project instead of a build after you modify a source file that does not trigger precompiled header recompilation.

 

Best regards,

Nelu F. || National Instruments.

0 Kudos
Message 2 of 12
(5,356 Views)

Thanks NeluF.

As a further detail, it's possible to create a scenario that gives the same problem in debug mode, going back from release configuration. I observed it yesterday just after writing my post.

I'm not going on this issue because I'm short on my project schedule.

 

A full rebuild can be a workaround, sure, but when you have a project with 80+ source files recompiling all files is not exactly instaneous, you know.

 

 

 

 

Carlo A.
Megaris




0 Kudos
Message 3 of 12
(5,352 Views)

Hi Carlo,

 

We have investigated the issue. The cause of the build error is that the precompiled header is not rebuilt, but the source file is, so only the source file is compiled with the new values of the version macros. Note that even the compilation of the source file is triggered not by the version change, but only by any edits made to it.

 

Even though the _TARGET_PRODUCT_VERSION_ or _TARGET_FILE_VERSION_ macros are not actually used in your code, the build process cannot know that, so it has to pass them as compiler defines to all files, including the precompiled header. The root cause of the build error is that the build process is not correctly detecting that these macros have changed.

 

Please note that when we correct our build process to detect this change, CVI will have to actually rebuild the entire project behind the scenes with each build that increments the version, because any of the files, including the precompiled headers themselves, could be using the version macros. Otherwise, you could end up with inconsistencies among any source files that happen to use these macros. Also note that regenerating just the precompiled header (which you could do even now by deleting the .pch file from the build folder of the configuration) would still trigger a full rebuild because the date of the .pch file becomes newer and because it is automatically included by all source files.

 

It turns out that even earlier versions of CVI had similar problems with the version changes, although it did not result in build errors. The resulting output binary would not use the up-to-date values of the version macros in the code.
For example, the code snippet:

printf("FileVer: %s\n", _TARGET_FILE_VERSION_);
printf("ProdVer: %s\n", _TARGET_PRODUCT_VERSION_);

would not be returning the correct/latest versions after consecutive builds, since the files themselves were not automatically recompiled

 

I realize that, as you mentioned, the build error is reproducible in debug configuration as well, but the need to rebuild the entire project does not apply to debug configurations. For it to apply, you would have to manually change the version numbers, since auto-increment has effect only in release configurations.
Note that CVI already does a rebuild when one of the Compiler Defines changes. Effectively, these version macros aren't any different than the Compiler Defines macros.
Furthermore, with CVI 2013 you can take advantage of the new multi-core compilation feature to help reduce your build times for larger projects (Options > Build Options > Build Process Options tab > Number of concurrent compiles) so that might mitigate somewhat the downside of a full rebuild.

 

Given all these, the performance hit from a behind-the-scenes rebuild should affect only your release builds, and only if you have version auto-increment enabled. Since development is typically done using the Debug configuration and Release builds are normally not all that frequent, does this solution look acceptable to you?


Best regards,
Alpar

0 Kudos
Message 4 of 12
(5,317 Views)

Alpar, it's clear that current implementation of _TARGET_PRODUCT_VERSION_ and _TARGET_FILE_VERSION_ is incompatible with the auto-increment feature.

 

The full rebuild "behind the scenes" would work, but it's an ugly patch, in my opinion: it would bring to a perfect equivalence between "build" and "rebuild" commands when the auto-increment is used.

 

I think that the only elegant way to solve this problem is to trigger the auto increment only when a rebuild command is issued. The normal build will use the current values.

 

It must only clearly documented, of course.

 

 

 

 

 

 

 

 

Carlo A.
Megaris




0 Kudos
Message 5 of 12
(5,294 Views)

Hello Carlo,

 

I don't agree that the "behind the scenes" rebuild is an ugly patch. This is no different than what happens if you change some setting in the Build Options dialog, as Alpar mentioned earlier. Because most of those build options are inputs to the build, on the next build CVI will have to recompile every file in your project whenever one of those inputs changes. All ADEs do the same thing during their dependency checks.

 

We cannot establish a different versioning policy for builds and rebuilds. The only difference between a build and a rebuild is that a build checks first what really needs to be built and builds only what it needs, whereas a rebuild always builds everything. It's not okay to end up with a different version in your exe or dll if you happen to do a build instead a rebuild.

 

You say that this policy sets up a perfect equivalence between builds and rebuilds when auto-increment is used. That is true, but only for release configurations. In my opinion this isn't that bad unless you're doing most of your code development using release configurations. Is that what you're doing?

 

Luis

0 Kudos
Message 6 of 12
(5,282 Views)

Luis, I hope that my words didn't sound offensive: it wasn't my intention.Smiley Embarassed

 

No, I don't do the bulk of my development in release configuration. 

In my applications, I usually have some "release only" and "debug only" code, selected by conditional compilation by using the NDEBUG / _CVI_DEBUG_ predefined constants.

Sometimes, by chance, it happens I had to do a quick fix in the "release only" code. It isn't a frequent event, anyway.

 

When this happened on CVI 2013, the compilation ended in a fatal error, on perfectly valid code.

The whole scenario is not exactly common, but it could be misleading to other users, too.

I think I can survive  Smiley LOL doing only full rebuilds in release configuration: its impact can be made negligible by using a more conventional development pattern.

 

IMHO all the problems come from the definition itself of the two constants. 

Both of them refer to the version of something that should not exist at compilation time, something that in a logical sequence should come to life only when the executable file is generated, or - more precisely - when resource compiler appends to the executable the version information.

Preprocessor constant must obviously be known in the first phase of compilation, so the compiler is somewhat betting on the build result, hoping that all steps involved in executable generation will be successful.

Given this, these constant should not exist at all.

 

If someone needs to know at run time the actual executable version number, it's not hard get it by using GetFileVersionInfo() API from version.dll. I don't know if there is some equivalent on Linux.

And if someone claims he/she needs to know at compilation time the version number, then he/she is simply doing it wrong... Smiley Tongue 

 

A sort of compromise could be to exclude from the constants any... variable part, e.g. the autoincrementing numbers. After all, a proper costant must be constant, isn't it ?

 

I'm very interested to hear your opinion.

 

 

 

 

Carlo A.
Megaris




0 Kudos
Message 7 of 12
(5,263 Views)

@carlox wrote:
 

A sort of compromise could be to exclude from the constants any... variable part, e.g. the autoincrementing numbers. After all, a proper costant must be constant, isn't it ?



This is already the case:

 

_TARGET_FILE_VERSION_ Windows Linux Defined as the value in the File Version option of the Version Info dialog box. This macro does not include increment symbols; for example, if the version string in the Version Info dialog box is 1.0.0.0+, this macro is defined to 1.0.0.0.
  Note  LabWindows/CVI updates the value of the file version only when the file that includes this macro is recompiled.
_TARGET_PRODUCT_VERSION_ Windows Linux Defined as the value in the Product Version option of the Version Info dialog box. This macro does not include increment symbols; for example, if the version string in the Version Info dialog box is 1.0.0.0+, this macro is defined to 1.0.0.0.
  Note  LabWindows/CVI updates the value of the product version only when the file that includes this macro is recompiled.
0 Kudos
Message 8 of 12
(5,252 Views)

No, Wolfgang, you have misinterpreted the doc.

What is not included in the predefined constant is only the "increment symbol", that is the "+" character.

The value of constant includes all four numeric fields, including the incrementing ones.

 

Carlo A.
Megaris




0 Kudos
Message 9 of 12
(5,250 Views)

Touché! You're right, the doc refers to the symbol Smiley Embarassed But at least the debug version is not autoincremented...

0 Kudos
Message 10 of 12
(5,246 Views)