Folks,
I'm using VS2010 and trying to sync the build version of my project with my Subversion repository using SubWCRev. This is all working correctly, but I can't quite get my head around one thing. My template file consists of this :
#define MAJOR_VERSION 2
#define MINOR_VERSION 2
#define MICRO_VERSION 0
#define BUILD_VERSION $WCMODS?$WCREV$+1:$WCREV$$
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
#define BUILD_VERSION_STRING QUOTE(MAJOR_VERSION.MINOR_VERSION.MICRO_VERSION.BUILD_VERSION)
Then in my application .RC file I have :
FILEVERSION MAJOR_VERSION,MINOR_VERSION,MICRO_VERSION,BUILD_VERSION
PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,MICRO_VERSION,BUILD_VERSION
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "080004e4"
BEGIN
VALUE "FileVersion", BUILD_VERSION_STRING
VALUE "ProductVersion", BUILD_VERSION_STRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x800, 1252
END
END
As you can probably work out, I'm trying to up the build version by 1 if there's modified code so that the build version in the EXE will match the Subversion revision number when I do a release and check the code in. The problem is that BUILD_VERSION gets expanded to x+1 or x+0 which then appears in the BUILD_VERSION_STRING as "2.2.0.227+1" which is not quite what I intended.
Does anyone with a little more experience with this know a way to achieve my aim?
Thanks in advance
#define BUILD_VERSION $WCMODS?$WCREV+1$:$WCREV$$
Im my group we only automate the update of the least significant value with the svn revision number for the projects working directory. To do this we have added a pre-build step to each project that creates and then calls a batch script that does the following:
Copy $(ProjectDir)Properties\AssemblyInfo.cs to $(ProjectDir)Properties\AssemblyInfo.cs.template.
Find AssemblyVersion("X.Y.Z.ddd") in $(ProjectDir)Properties\AssemblyInfo.cs.template and replace with AssemblyVersion("X.Y.Z.$WCREV$").
Find AssemblyFileVersion("X.Y.Z.ddd") in $(ProjectDir)Properties\AssemblyInfo.cs.template and replace with AssemblyFileVersion("X.Y.Z.$WCREV$").
Run 'SubWCRev $(ProjectDir) $(ProjectDir)Properties\AssemblyInfo.cs.template $(ProjectDir)Properties\AssemblyInfo.cs'
If you use subwcrev to generate an unversioned header from your versioned template, then #include the unversioned header in your versioned .RC file, you can build for release from an unmodified work area.
Then you can just use
#define BUILD_VERSION $WCREV$
This also removes the risk of any changes creeping in between building your release EXE and checking in the code.
Could you do something like:
#define MOD_VERSION $WCMODS?1:0$
#define REVISION $WCREV$
#define BUILD_VERSION ( REVISION + MOD_VERSION )
Edit: This won't work either as pointed out in the comments!
What is the purpose of your version number? If it's to get back to the source code used to produce the binary then you might be shooting yourself in the foot a bit here. What happens if someone checks some more code into the repository at the same time as you're creating your version number? You're going to end up with your binary referencing different code.
What might be better would be to check to see if the working copy has any modifications or mixed revisions and use a specific revision number (e.g. 0xFFFFFFFF or 0) to represent this. And only use the true revision number if you used a clean tree to build the binary.
#define MAJOR_VERSION 2
#define MINOR_VERSION 2
#define MICRO_VERSION 0
#if $WCMODS?1:0$
#define BUILD_VERSION 0
#else
#define BUILD_VERSION $WCREV$
#endif
Related
I think everybody knows this excellent CMake command:
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/version.h.cmake
${CMAKE_CURRENT_BINARY_DIR}/version.h
)
But I have to implement that in Makefile. Could you please help me? How to do it?
Configuration file (version.h) is very simple:
#ifndef _VERSION_H_
#define _VERSION_H_
#define VERSION_MAJOR #VERSION_MAJOR#
#define VERSION_MINOR #VERSION_MINOR#
#define VERSION_BUILD #VERSION_BUILD#
#define VERSION_REVISION #VERSION_REVISION#
#endif // _VERSION_H_
This won't work. Well it might be, but it will be a hassle. These config.h files are made to communicate the result from a configure tool (configure from Autotools, CMake etc.) to the compiler.
When you use Makefiles, you can simply attach necessary flags or variables to the C(++) compiler call (with -D). There is no need to add the complexity of a config.h.
Is there a way do define a global macro, like _DEBUG in VS 2013 to be global per project?
I want to use macro for conditional buld for different versions of application and avoid to include *.h.file containing the definition.
#define APP_VERSION_MAJOR 1
#define APP_VERSION_MINOR 0
#define APP_VERSION_HOTFIX 0
#define APP_VERSION_DEV a
#define APP_VER_STR_(s) #s
#define APP_VER_STR(s) APP_VER_STR_(s)
#define APP_VERSION APP_VER_STR(APP_VERSION_MAJOR) "." APP_VER_STR(APP_VERSION_MINOR) "." APP_VER_STR(APP_VERSION_HOTFIX) "." APP_VER_STR(APP_VERSION_DEV)
I would use the build system to pass the definitions to the C / C++ compiler using the -D syntax:
-DVERSION=2.0.3
I have 2 Visual C++ projects which both have an RC file where the Field Product Version is defined. How can I make both projects to get this version from a global place? Global RC file or what solutions are there?
What works well for me is adding two "Solution Items". One is a .h file that #defines some version strings, and another is the .rc file that has an include to the .h and BLOCK "StringFileInfo" that uses the defines.
Individual resource files for each project use a TEXTINCLUDE to bring in the contents of the solution's .rc.
That is a lot to take in. Let me show you what I mean...
1) The two solution items are added as so:
2) version.h has some #defines that will be used in VersionInfo.rc2
#define SOLUTIONFILEVERSION 1,00,0000,00000
#define SOLUTIONFILEVERSIONSTRING "1,00,0000,00000"
#define COPYRIGHT "Copyright 2012"
#define PRODUCTNAME "Your product name"
#define COMPANYNAME "Your company name"
3) VersionInfo.rc2 uses the defines
#include "version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION SOLUTIONFILEVERSION
PRODUCTVERSION SOLUTIONFILEVERSION
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", COMPANYNAME
VALUE "FileVersion", SOLUTIONFILEVERSIONSTRING
VALUE "LegalCopyright", COPYRIGHT
VALUE "ProductName", PRODUCTNAME
VALUE "ProductVersion", SOLUTIONFILEVERSIONSTRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
You will want a new line at the end of this file to make the resource compiler happy when it is included in the next step.
Another field you might like to set is "FileDescription" but that is typically on a per-project basis. Remember, this can contain anything you would like to be shared between your projects.
4) Include the VersionInfo.rc2 in each process. This is done by right clicking on the each project's .rc in the Resource View and selecting Resource Includes.
Add to the Compile-time directives: #include "../VersionInfo.rc2"
This could be done manually by adding the following to the project's .rc file but it is probably better to let Visual Studio manage everything it can for you.
3 TEXTINCLUDE
BEGIN
"#include ""../VersionInfo.rc2""\r\n"
"\0"
END
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "../VersionInfo.rc2"
/////////////////////////////////////////////////////////////////////////////
Phew....that was a mouthful. But now you should be able to change your product versions from one spot.
Ok i have solve it.
I had to add following as well at the bottom of the project's recource file
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "VersionInfo.rc2"
/////////////////////////////////////////////////////////////////////////////
Now everything works great. Thanks
I'm working on creating build configurations based on a previous question of mine. I've got the Build Configurations created, and I have conditional declarations for the different builds in a file called custom.h. It currently looks like this:
#pragma once
#if defined(ELITE_BUILD)
#define BUILD 3 // 1: personal, 2: select, 3: elite
#elif defined(SELECT_BUILD)
#define BUILD 2
#elif defined(PERSONAL_BUILD)
#define BUILD 1
#endif
In one of my .rc files there is an include for versionconfig.h that looks like this (somewhat redacted):
#if BUILD == 1
#define STRDESCRIPTION "Personal Edition"
#elif BUILD == 2
#define STRDESCRIPTION "Select Edition"
#elif BUILD == 3
#define STRDESCRIPTION "Elite Edition"
#pragma message(STRDESCRIPTION)
#endif
I added the #pragma command as a logging effort. After that include, the relevant parts of the .rc file looks like this (again, a bit redacted for brevity):
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", STRDESCRIPTION
END
END
END
When I attempt to compile this project I get the error error RC2104 : undefined keyword or key name: STRDESCRIPTION. I'm at a bit of a loss. The value exists, I can log it immediately after setting it, and there is no #undef command for it.
-- EDITED --
If I add placeholder defines outside of the if block the project will compile, but the values aren't showing up, so my problem appears to be related to conditional definitions. What's confusing me most at this point is that I can put a #pragma message command inside the conditional block and it's executed properly, but the values defined there are non-existent. Hoping someone can shed some light on this for me.
I found it. In Visual Studio you have to set pre-processor definitions for the Resource Files separately from the Project. As soon as I added ELITE_BUILD to the pre-processor section for the resource everything worked as expected.
I would like to know if there is a way to get rid of CDT syntax error warnings when using gcc's "__attribute__" keyword.
It goes without saying that I would not like to switch off CDT syntax check.
The "ECLIPSE_THINKS_THIS_IS_SET_BUT_GCC_DOESNT" definition (from ams's answer) really extsts and it called __CDT_PARSER__. For example:
#ifdef __CDT_PARSER__
#define __FILE__ "<file>"
#define __LINE__ (-1)
#define __DATE__ "<date>"
#define __TIME__ "<time>"
#endif // #ifdef __CDT_PARSER__
Hope this will be helpful.
I've not tried it, and I've not used Eclipse for some time, but here's an idea:
In the CDT settings for Eclipse (or maybe just your project) set up a predefined macro (I seem to remember you can tell it what the compiler auto-defines) named __attribute__ that takes one parameter, and expands to nothing.
Maybe I haven't explained that right. Let me try again with an example. Basically, the aim is to define a macro that works like this:
#if ECLIPSE_THINKS_THIS_IS_SET_BUT_GCC_DOESNT
#define __attribute__(X) /* nothing */
#endif
but without putting anything actually in your code.
Project->Properties->C/C++ general->Path and Symbols->Symbols
Add->
Name: __attribute__(X)
Value: (leave blank)
Related links: You can use this technique basically with any offending keyword
ziu's answer is also working for XC8 Microchip compilers
Name: __interrupt
Value: (leave blank)
The function prototype now is clean:
void __interrupt ISRs(void);
And Eclipse won't complain about it.