Create VS path macro

I'm using VS 2005 to compile unmanaged C++.

VS defines macros such as $(SolutionDir) which provide path information I can use in specifying include directory paths in the project properties.

I don't see how to create one myself without creating an environment variable -- $(MyEnvVar), for example.

How can I create macros similar to $(SolutionDir) without creating an environment variable?
LVL 13
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

No. $(SolutionDir) is not an environment variable.
josgoodAuthor Commented:
I agree, $(SolutionDir) is not an environment variable.  It is one that VS generates as part of the project definition.

I was asking if I can create a macro, similar to $(SolutionDir) without creating an environment variable.
Check this:
MSDN. How to: Use Environment Variables in a Build
OWASP: Avoiding Hacker Tricks

Learn to build secure applications from the mindset of the hacker and avoid being exploited.

josgoodAuthor Commented:
This could be a solution...To define
    <ToolsPath Condition=" '$(ToolsPath)' == '' "> 
(their example), I'll need to edit the project file directly, I believe.

Is that right or am I missing something on the IDE?  I don't see that Project | Properties gives the ability to do this.

With this approach, the only environmental dependency is that there *not* be another definition of ToolsPath.
Check other links from the posted one:
MSBuild Properties
josgoodAuthor Commented:
I've added a property to the .vcproj
just before the <Configurations> element.

Before this, I had an environment variable MyPath defined and compilation was working.

Using this property definition, with the environment variable deleted, the compilation is not working...the path is not defined.

Am I tracking with you or am I doing something wrong?
AndyAinscowFreelance programmer / ConsultantCommented:
Why would you want to do this?
josgoodAuthor Commented:
Andy, I want to use project macros to define folder paths without defining an environment variable.

I'd like the path definition to be in the project file.  I think the beginning of this question explains...if not, please say so and I will clarify.
AndyAinscowFreelance programmer / ConsultantCommented:
I understand the question.
I'm just puzzled, for some reason you want a path that isn't one supplied as a predefined macro.  (Maybe there is an alternative you haven't thought of - or maybe you are going the best way)
josgoodAuthor Commented:
I'm building an integration test project, where I'm testing several components of the solution.  It is in the same solution as the production application, so that it tracks changes to production code.

One way to think of this is that my test application replaces the production application.  The test application, naturally, is in a different folder than the production application and is, for reasons of orderliness, at different level on the folder tree.

I could use paths like
but that's awkward and, if I move MyTest, requires me to re-edit multiple paths in all configurations of MyTest.  All that editing opens the door to a mistake requiring careful reading of the project settings to find.

I'd like to place that path information into a single macro and then just reference that macro.
Walkthrough: Creating an MSBuild Project File from Scratch
CodeProject. Practical .NET2 and C#2: An introduction to MSBuild

I'm not a configuration manager. Your way , maybe, could work for C#/J# project.

You know that there are post- pre build events (right click on the project). From this place you can launch a batch file and declare any variable in DOS like style.
Pre-build Event/Post-build Event Command Line Dialog Box


I found just now:

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
josgoodAuthor Commented:
These are great suggestions -- particularly the pre-build event -- and I will look into them in a couple of hours.  (have to do something else for a bit) Thank you!
josgoodAuthor Commented:
Well, I think the idea of setting environment variables at the pre-build step doesn't work.  I wrote a small batch file
   Set MyEnvVar=D:\MyPath\MyFolder
   REM (where MyPath is quite a bit longer)
The 2nd Set shows the environment variable created and set to the correct value.

However, the build doesn't see the environment variable...Probably because MSBuild opens a new command environment to run the batch file.  Once that command environment is closed, the new environment variable is lost with it.

I could download Setx, which will write to the registry so that the environment variable is preserved, but then MSBuild will need to be reloaded to get the new environment variable.  That isn't what I want either.

I tried
   Set MyEnvVar=D:\MyPath\MyFolder
directly in the pre-build event command list, but got the same result.  I suspect the same issue with a command environment being opened to run the pre-build commands.

I'll look at your other suggestions now.
If I understand you correctly, you want to build separate versions of the code for testing.
If this is true, have you considered using a third-party testing tool such as NUnit?
Another alternative would be to create your Integration Test program and then include your components to this project as dependent projects. In that way you don't need to fiddle with macros, you can conditionally compile different dependent projects to produce your final executable and achive the same result.
josgoodAuthor Commented:
>>you want to build separate versions of the code for testing
Yes, you understand correctly

>> considered using a third-party testing tool
I could use CppUnit, or Boost:Test.  I believe NUnit isn't applicable to unmanaged code, but I don't know that.  I should probably look, huh? <G>

>>include your components to this project as dependent projects
I'd love to do so, but this code base is currently too monolithic for that.  My real objective is to extract part of the monolith into a component.

I've included project references in C# solutions, but never in unmanaged C++ solutions.  I didn't realize you could do that.  Or do I misunderstand?
No, my bad, NUnit is only for managed code, don't boither going there.
To restate my question:
You have a "monolithic code base". Does this mean that if you copied out the sections of code you wanted, by the time you copied all the header files, and their dependents, they are so interlinked you would end up with almost the whole codebase again? However, you can't just copy or rewrite the code bits you want because there are other projects using this code and you would miss any changes they made to the original code, yes?
josgoodAuthor Commented:
You have it exactly, my friend.
A further question. From your previous answer, I take it that you will not be modifying the code in any way in your integration test? Or any changes you do make are local (for the life of your testing ) and will not be part of the production code?
What version control software are you using?
josgoodAuthor Commented:
We're using Perforce.

I'll be making changes on a branch and then merging back to the trunk.  I've defined several iterations because I believe in merging early and often.

My initial intention is to build an integration test using the current production source with minimal (none, if possible) changes.  That lets me establish a baseline that confirms the integration test is performing correctly.

Then, using the same integration test, I'll make iterative changes on branches, merging often.  Integration tests are necessary because the code controls hardware and responds to hardware events.. This prevents a  unit test from doing thorough testing.

At the end, production code will be modified -- a component will be extracted from the monolith and the remaining monolithic code will use the new component's interface.
Is this monolithic code base compiled into a single executable or a com object or a library, or what?
josgoodAuthor Commented:
The primary target is an executable.  There are some statically linked .lib files.
AndyAinscowFreelance programmer / ConsultantCommented:
Many years ago I made UNICODE and ASCII builds (Win95/98 vs Win NT).  There I had different configurations, a DEBUG_UNICODE and the standard DEBUG.  Each path is different based on the configurations.

That sounds exactly like what you require.

Goto the project properties and click the configuration manager button, add a new configuration (combo box option), base it on what you have as an existing configuration.  Then go into the macros and look at things such as output path.  You can define preprocessor definitions based on the configuration so you could switch on/off blocks of code at compile time.
The short answer is, that there is no short answer.
Before you modify any projects or code, I presume you have permission from the other users/owners of this code base to make such changes? If no, then the problem is harder, if yes, here is one solution.
I presume from your responses that this is not going to be a one-off affair? That this will be an on-going task for you over the lifetime of the product? Obviously, a rewrite is out of the question? Yes.
One possible way to move forward would be to create a separate project for a static library. The task would go something like this:-
1. Create a new project - of type Static Library, and give it a unique namespace
2. Copy all the underlying source code from the legacy application into this project. This is everything except the main application code.
3. Remove all these files from the old project and then add the static library to the project and rebuild both. This should give you an executable that is functionally unchanged from the old one.

Step 3. Create a project for your test harness of type executable.
Step 4. include this new static library in the project; remembering it is under a different namespace..
Now you have a common code base, and if you want to change a function, you can code up the new functionality in your test harness.
You can ditinguish between your functions and the same functions in the old code by accessing them through the different namespaces.

Its not elegant, or even pretty, but its a solution.

josgoodAuthor Commented:
My original issue was my preference for not using an environment variable.  After this discussion, an environment variable seems the best available solution -- primarily because it is one simple thing.

This discussion verified that I'm not missing some simple idea that would handle my objection to using an environment variable.

I appreciate your help and your thoughts.

Thank you.
josgoodAuthor Commented:
Thank you, all.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.