Visual C++ project property # $ % macros - c++

In Visual Studio 2012 C++ project property Page, macro dialog
We can find different macro expanding syntax,
$(TargetPath)
%(OutputFile)
#(_TargetFramework20DirectoryItem)
What's the different?
BTW, Can we define our own new macro easily in Visual Studio 2012? Beside create a new project property sheet.
I just want to a simple new macro, if so, all my depends can be calculated base on this macro.
For example:
$(DependsBaseDir) = $(ProjectDir)..\..\..\
$(IncludePath) = $(DependsBaseDir)include;$(DependsBaseDir)abc\inc;$(DependsBaseDir)xyz\pub_inc
$(LibraryPath) = $(DependsBaseDir)lib
Using project property, I cannot archive my purpose. Since $(DependsBaseDir) depends on $(ProjectDir). I have to use environment variable, which is a VERY VERY BAD decision and it is hard to move project among machines. Or I have to repeat $(DependsBaseDir) value everywhere. If $(DependsBaseDir) changed, it do change, fix depends is a disaster. I have to calculate right dots, then replace it everywhere...This simple example is hard enough. Do not say $(SolutionDir), project shared in different solutions.

$ expands a property, % expands an item definition. Look at text of a vcxproj and you can see the difference.
You can define your own properties in the project file, and the suggested place is under "UserMacros". Yuo can define your thing like
$(ProjectDir)......\
there, and use it with $(DependsBaseDir) later on. AAMOF you can even use expressions applicable to C# string.
If you don't want to edit the project itself, you can put that in a separate .props file and import that manually or using the property manager.

Related

How to make multiple projects within one solution in Visual Studio 2017

I have a solution called book_example with one project inside called first_project. I want to make several more example projects called second_project, third_project etc. within this solution.
So, when I open book_example in the solution explorer it would show all of my projects. I want them to share source code so all file paths etc. should be the same.
When I right click the solution Add -> New Project even if I use a template that is exactly the same as my existing first_project all of the paths do not work. Basic things like my source.cpp say "This file does not exist or has been moved".
Edit: To be more clear, when I try a solution like the one proposed by madocter below, I get errors with the project. I.e.:
What is the correct way to create several projects within one solution that share code?

VS2010 does not find #include via environmental variable

I'm currently running into a problem that drives me a little bit mad. I hope it's a little stupid mistake on my side.
For convenience, I added an environmental variable in Windows 7, VS_BOOST_INCLUDE_HEADER with the value set to D:\01_Programs\boost_1_55_0\. My VC C++ include directories contain $(VS_BOOST_INCLUDE_HEADER).
Remark: I changed that variable this morning, but I've rebooted my computer since than multiple times.
Now my VS project complains it can't find any of the boost includes anymore, e.g. <boost/asio.hpp>. If I add the whole path manually to the include paths (adding D:\01_Programs\boost_1_55_0\ as text to my VC C++ include directories), everything works as expected.
To avoid a simple typo, I added a post-build event:
echo $(VS_BOOST_INCLUDE_HEADER)
That works as expected:
1>PostBuildEvent:
1> D:\01_Programs\boost_1_55_0\
All my other environmental variables still work as expected, even those that were renamed this morning as well.
Any ideas?
What am I doing wrong?
Maybe I'm late to the party, but a possible scenario is when you
run VS as administrator
adjusted a User environment variable
Then it would make some sense for VS to see the System environment only and still use the old value.
If you decide to use property sheets the msdn has clear docs
"If you have a common, frequently used set of properties that you want
to apply to multiple projects, you can use Property Manager to capture
them in a reusable property sheet file"
Under the view menu, chose property manager and add a new sheet.
You can then make your project inherit its settings from this property sheet, thereby just setting this in one place.

Renaming a form in Visual C++

I start Microsoft Visual Studio 2010. I chose to start a new project on the Welcome Page. Ofcourse my preferred language is Visual C++ and I'm chosing to begin a Windows Forms Application. I give up a name like Calculator for this one. I do not touch the other options on this dialog. The project gets created and a new Form1.h is automatically added to the project, and a Form1.resX is also added. Because 'Form1' is useless to me, I'dd like to rename it to something more VB6 style, like "frmMain.h". So I right click the Form and simply chose "Rename". After accepting my new name, the necessary changes seem to be occuring. first impression But now, when I try to build this project, It gives a BUILD FAILED. When I look into my files.. Form1 is still mentioned..
So my question is: How do you actually/OFFICIALLY rename Forms?
I've been reading a lot about this and mostly the answer is to delete the form, and re add a new with the right name.. I've heard also that VS asks to rename all references to it, but that doesn't show up to me. Some other people say, you have to use the quick replace function, and rename all references to this class and its file.. This is not a good way to me.. Or is it really the standard procedure?
I have programming experience in C++ and I know about classes and polymorfism and so on. But this is one of the simplest things that keeps me annoying!
You are using VC++.NET to create .NET applications (Windows Form in your case). I must warn you that VS is not very friendly for VC (refactoring, renaming, and little intellisense).
In this case, you renamed the form which will make VS also rename the Form1.resX, but it will not rename the class. It will do it if in C# or VB.NET. Just open the .h file and rename the class itself to match the name of the file.
You also need to update the main .cpp file where "main" resides, and update the Application::Run(gcnew Form1()); in there as well include the "#include".
A solution replace will work (Ctrl+Shift+H), but be careful with this.
click on the form -> properties -> text (usually named as Form1) -> change it.

"Conditional" macros in visual studio 2010 property manager

The property manager allows having different property sets for different configurations - for example, release and debug.
However, it still means you have to manually assign each property file to each configuration.
Is there some method to automatically assign a property set to a project based on some parameters (like configuration or platform)
a specific example:
I have a solution with many sub-projects.
this projects depend on various external libraries.
for each external library I have a .props file with the relevant directories and other parameters (include , lib, dll's...)
In some cases the directory names can be easily constructed using the default macros such as $(Configuration), $(Platform), etc.
However some libraries come with a less standard \ consistent naming convention.
for these cases I create .props file which are specific to a configuration (Debug\Release) - but it requires assigning the manfully to each project, which is tedious and error prone.
This is possible, at least in principle, see this post, for example. However, I did not find a practical way to use the whole power of MSBuild in combination with c++ projects from within the IDE. Whatever smart MSBuild expressions you write down in your property sheet, once you fire up the property manager dialog in the IDE everything gets overwritten with either defaults or the values inferred from there. This is an odd behaviour and completely different from other project types. Looks like they just wanted to keep the old pre-MSBuild style of editing VCProjects...
You can record a macro and use VBA to create/generate these with a button click.

Is it possible to have identically named source files in one visual studio c++ project?

I'm working on a static library project for a c++ course I'm taking. The teacher insists that we define only one function per source file, grouping files/functions belonging to the same class in subdirectories for each class. This results in a structure like:
MyClass
\MyClass.cc (constructor)
\functionForMyClass.cc
\anotherFunctionForMyClass.cc
OtherClass
\OtherClass.cc (constructor)
Whether this is good practice or not is something I'd not like to discuss, since I'm simply obliged to organize my project in this manner.
I'm working in visual studio 2008, and somehow got strange link errors when using an identically named function (and thus filename) in two classes. This appears to be caused by the fact that visual studio puts all .obj files (one for each source file) in one intermediate directory, overwriting earlier generated object files when compiling identically named source files.
This could be solved by putting the object files in subdirectories based on the relative path of the input file. Visual studio allows one to configure the names of object files it generates and has macros to use in there, but there appears to be no macro for 'relative path of input file'.
So, is there some way to get this to work? If not, is using one project for each class the best work-around?
You are right, by default all object files are put into the same directory and their filenames are based on the source file name. The only solution I can think of is to change conflicting file's output file path in here:
Project Properties-C/C++-Output Files-Object File Name http://img37.imageshack.us/img37/3695/outputfile.png
PS. It sounds like the lecturer has a crappy (probably written by the lecturer himself) automatic code verifier that imposes this restriction. To get extra marks, offer to rewrite the parser so it works with normal/sane/non-weird projet layout.
Real answer:
Change
C/C++ => Output Files => Output File Name
to
$(IntDir)/%(RelativeDir)/
Every .obj file is going to be created in a sub folder so its not going to overwrite the previous on linking.
I can't think of any way to fudge the project settings to get VStudio to automatically split out the intermediate files into separate folders.
You have a few chances -
Build the class name into each file name. Most IDE's display just the file name in the tab view so if you do have several methods in different classes with the same name, its going to be difficult to tell them apart if the file name does not include the class name along with the method name. Which is really why I think your teachers advice is madness. I have not seen any programming style guide advocating that approach. Additionally it goes directly against the way various tools work - if you use Visual Studio to create a class, it creates one cpp file and one header, and automatically appends each new function to the single cpp file.
You could create a static library per class. When linking in static libs the obj files are all packaged up inside the .lib so conflicts are no longer a problem.
Switch comp-sci courses to one thats not being taught by a nut job. Seriously, this guy is completely out of touch with industry best practices and is trying to impose their own weird ideas on their students: Ideas that are going to have to be unlearnt the moment they leave the teaching environment.
You can also change output file name per file in its properties. Just make sure you use different names.
Can you use the class name in the filename to disambiguate? I'm thinking that you might have
MyClass
\MyClass.cc (constructor)
\function1_MyClass.cc
\function2_MyClass.cc
That would mean that every file would have a unique-enough name to defeat the problem. Is that an acceptable strategy?
You could probably arrange the properties of the project to put the object files into a folder which is below the folder of each source file. Once the project has this property, then every source file should inherit this property. (But if you've done experiments like Igor has suggested, then you may need to go through the properties as reset them back to the parent).
Having looked at the help files, I think you should go to project properties/C C++/Outpuf Files/Object File Name: and enter $(InputDir) (no trailing backslash). Every source file should then inherit this property and your .obj files should be separated.
You may need to do a Clean Solution before you make any changes.
Renaming the object files will work, but it's going to be a pain, and it will slow your compile/link cycle down. I've never figured out why, but it seems to confuse Visual Studio if the object files don't have the default names.
You could prefix the funciton name with the class name; e.g. myclass-ctor.cc, myclass-function1.cc etc.
You could have one .cc file per class which #includes the individual function files. In this case you'll need to prevent the #included files from being compiled seperately (either rename their extension or set Properties->Exclude From Build to 'Yes').
Out of curiosity, where does your teacher want you to put free functions e.g. local helper functions that might normally belong in an anonymous namespace?
If not, is using one project for each class the best work-around?
Not a good idea - apart from the fact that you won't end up with a single static library (without even more jiggery pokery), your link times are likely to increase and it will hide a
lot of pertinent info from the optimizer.
On another note; If the course is actually about C++ not OO programming, do what you need to pass but take your teacher's advice with a pinch of salt.
You don't have to put them in different translation units... why not put each function in a .h and include them all in one .cc per class? That will very likely give better output from the compiler.
I'd be asking why the teacher is insisting on this odd structure, too, the reasoning behind it should be explained. I know you didn't ask that of us, so that's all I'll say.
In Visual Studio 2010, I set
Properties -> C/C++ -> Output Files -> Output File Name
to
V:\%(Directory)$(PlatformName)_$(ConfigurationName)_%(Filename).obj
for OBJ files to end up next to the sources assuming the project lies on drive V (no idea whether there is a macro for it, yet).
By the way: $(InputDir) refers to the solution/project directory and will cause the same problem in another directory.