As part of a build process, I need to take an environment variable defined by a batch script and use it as a constant within the code at compile time.
For example, say I have defined an environment variable named BUILD_VERSION and set it to 1.0.0, when compiled I want 1.0.0 to be baked into my code. EG:
Batch file:
set BUILD_VERSION = 1.0.0
; call vs compiler
C++ File:
const std::string build_version = BUILD_VERSION // Which will result in "1.0.0".
How would I go about doing this?
In the end I followed txchelp advice and added a /D flag into the Command Line -> Additional Options section of the project properties to declare the environment variable as a preprocessor definition.
It looked something like this:
Then in the batch script that started the build:
set SVN_BUILD_VERSION=1.0.0
And finally to extract it as a string within the source code:
#define STRINGIZER(arg) #arg
#define STR_VALUE(arg) STRINGIZER(arg)
#define BUILD_VERSION_STRING STR_VALUE(BUILD_VERSION)
// ...
const std::string version = BUILD_VERSION_STRING; // Results in "1.0.0".
You can use a prebuild step (I suppose you are on Visual Studio) which will run script which will get this environment variable value, parse C++ source file and change the value
"1.0.0.0" to "1.0.0.1".
Such substitution can be conveniently done by awk.
A VERSION_INFO resource could be a good way go.
The version info so embedded can be inspected by right-clicking the executable and checking its properties.
To do that at the command line:
Redirect output from a batch file to an [.rc] file defining the resource.
Compile the resource using rc.exe.
Embed the resulting .res file by simply passing it to the linker.
Within Visual Studio it might be more complicated.
Related
I use C-SPY macros for automated testing. For this purpose I load a startup macro file and it loads additional macro files using the following code:
execUserSetup()
{
__registerMacroFile("$_ENVVAR_$\\macros-1.mac");
__registerMacroFile("$_ENVVAR_$\\macros-2.mac");
...
}
This works like a charm when I run the startup macro from within the IAR Embedded Workbench.
But what I really want to do is running the tests with CSpyBat.exe. There I specify my startup.mac using the option --macro startup.mac.
The files macros-1.mac and so on won't be found then. Instead I get error messages for the macro files (with garbage file names, see below):
ERROR: Could not open macro file: #۸0ٸ`ٸ#2#u
If I use the pathnames without the environment variables, everything is okay.
What am I doing wrong?
The answer is: The workbench supports expanding environment or project variables, but CSpyBat doesn't. So told me IAR support. Also they gave me the following pointer:
See 'C-SPY Debugging Guide' - "Using C-SPY in batch mode", "INVOCATION SYNTAX", page 492:
Note: In those cases where a filename is required—including the DLL files—you are
recommended to give a full path to the filename.
In one cpp-file I use the __DATE__ macro to get the compile-date.
It gives me the date of the last compile of that file. But as the file is not changed very often, the date is old in most cases, sometimes several months.
What I actually want is the date of the last build of the project.
Is there an setting to force VS2010 to rebuild that single cpp-file on every compile of the project?
Regardless of changes in the file?
The only way I found until now is to modify the file or delete the created obj-file by an script before the build, I would prefer an solution inside VS if that is possible.
You could probably add a Pre-Build Step that touch (see this thread) the file?
To add a Pre-Build Step, open your Project Properties, then Configuration Properties > Build Events > Pre-Build Event then add the command line you want to have executed in Command Line.
Following the suggestion from Amitd, apparently you can also touch the file using PowerShell, see this for explanations.
As suggested by Adrian McCarthy in the comments below, deleting the .obj file would be preferable in the context where source control is used and you want to keep the .cpp read-only. Using the "macros" exposed by Visual Studio, deleting them can be made easy:
del $(TargetDir)sourcefile.obj
Quoted from Cheers and hth. - Alf as another way to achieve this
nmake (bundled with Visual Studio and the SDK) option /t does a touch, it was once the conventional way to do this for Windows programmers.
You can add the following pre-build step, were you simply touch the date stamp of the file. The +,, is a special flag to the copy command, telling it to update the timestamp of the file:
copy file.cpp +,,
As suggested by Adrian McCarthy, you can simply delete the object file every time you build the project.
Therefore, create a pre-build event invoking the del command. According to Microsoft, you can use the $(IntDir) macro to refer to the directory wher the object file is stored (you should not use the $(TargetDir) macro).
I had issues with the return code of the command (error MSB3073), therefore I changed the command to always exit with 0.
del $(IntDir)datefile.obj & exit 0
Create this build event in the project configuration, under Configuration Properties / Build Events.
I would like to change the dynamic variable ${selected_resource_loc} such that I get rid of the extension (and can add another one).
The purpose is to build the current selected file, but therefore I don't need the .cc-file in my command but the .o-file with the same name.
Detailed description:
I have a customized make command (lets say make) and would like to execute make selectedFileName.o, where the current selected file in eclipse is selectedFileName.cc. (I put the command as build command in project properties -> C/C++ Build.) With variable ${selected_resource_loc} in behaviour tab I get make selectedFileName.cc.
I solved my problem by writing a skript where I modify the ${selected_resource_loc} and included it via external tools in eclipse.
I'm using a batch file to define some variables that will be used in my program.
I want the batch file to change the environment variable and use it in my code , but it's just now working - the macro is not being changed.
to be more specific and clear :
I have a program that creates a DLL and sets it's version
In the common setting of the project - I created a new macro (Common properties->User macros) : TEST_VER = 5
now I want to add a batch file , that will run in the pre-build command and change the value of TESTER
I wrote this in the batch file:
set TEST_VER=9
and used the path of the batch in the pre-build.
BUT it doesn't recognize it.
and still uses 5 as the value
I though doing :
propeties of the project - > resourcses ->general
and add : TEST_VER=$(TEST_VER)
and still didn't work
is there a way to do it??
thanks!!
When Visual Studio starts a program, it runs that program in a new sub-process. In this case, that's a new CMD.EXE, the command prompt shell. Changes made to the environment in a sub-process, a child, have no effect on the parent. Visual Studio has its own set of environment variables which it inherited when it started. Your batch file can't change those values. You can't do what you want the way you're doing it.
I've got an NMake project in Visual Studio 2008 that has the Build command set to a custom tool that performs a long build task.
Build = "#call MyTool -config $(ConfigurationName)"
I want a way to to pass a special flag ("-quickbuild") to my tool to tell it to do a quick subset of the overall build.
Build = "#call MyTool -config $(ConfigurationName) -quickbuild"
However I want it to be easy to switch between them so I don't actually want to change the build command.
My thought was to change the build command to this:
Build = "#call MyTool -config $(ConfigurationName) $(ShouldQuickbuild)"
and create a visual studio macro that will set the "ShouldQuickbuild" environment variable to "-quickbuild" then call DTE.Solution.SolutionBuild.BuildProject(...) on the project. The problem is it doesn't see the "ShouldQuickbuild" environment variable.
Any ideas on how I can get this working. Is there a better approach for doing what I want?
Use a batch file and check, If the environment is passed on to the batch file, then you can get that in the batch file and call the actual tool that you want.
The batch file would look like this :
#echo off
MyTool -config %1 %ShouldQuickbuild%
IF the environment is not passed to the batch file, you have to somehow get the info across, globally. Is it possible to create a file from a VS macro? Or call an EXE? Then it's quite simple..
Try putting your variable inside of % delimiters, as in %ShouldQuickBuild%.
You can you control this with the "Solution Configureation". Create two new configureations "Debug Quick" and "Release Quick". These would be copies of the originals. Then change the build command for each configuration.