Sharing classes between projects while getting around stdafx.h dependencies - c++

I have a Visual Studio 2010 solution with several very closely related projects. Would like to get away from copy-paste code sharing and share some common classes between the projects. We have tried adding a reference to the class from project A into project B, but are getting compile errors where the shared class is referencing the wrong stdafx.h file. Note that precompiled headers are on (by default) for both projects.
We have also learned that it is not possible to #ifdef the correct stdafx.h file using preprocessor definitions.
At this point it looks like our options are to either build a static library project or multiple projects and reference that from both project A & B, or to try some pre-build event copying of the correct stdafx.h file into the shared-code subfolder. Third would be to re-architect both projects to not use stdafx.h at all.
All of these options seem like overkill to me. Is there an easier solution that I am missing?

The two that popped straight into my head when I was reading your question was to:
turn off precompiled headers.
compile the common code as a shared library.
In your instance 1 would allow you to be more productive quicker, but don't delete stdafx from the project it as that would mean having to go through your project and turning off the precompiled header. Simply remove all the stuff you added and leave it default for both projects. It's been a while since I had to do this, but I think I then would then right-click and compile each cpp file individually. This would give you the missing header files for that compilation unit. Add them and then rinse and repeat for each.
Running code through static analysis would highlight things that could speed up compilation (forward declares vs includes, etc.).

When I have run into this problem I fixed it by:
Rename all stdafx.h files specific to their project (stdafx_prj_A.h, stdafx_prj_B.h, etc.).
Also, you will need to update each solution to use the correct precompiled header file. The setting for this is in Configuration Properties -> C/C++ -> Precompiled Headers -> Precompiled Header File.
Do not forget to make this set for all Configurations and Platforms.
Be safe. Each StdAfx.cpp only needs to include the correct header file. So do not include all of the stdafx headers in 1 StdAfx.cpp file.
Move any classes that are shared between projects to their own project.
This still allows you to use PCH files, and you do not have to worry about the compiler using the wrong file. If I recall correctly VS will use the currently specified PCH file name for any new class that you create.

We create .cxx files with the original source EXCEPT for the #include "stdafx.h". This is the main file that implements the class.
Then we create separate project specific .cpp files that just contain (for example NumEdit.cpp)
#include "stdafx.h"
#include "\pathtoimplementation\NumEdit.cxx"
Then each project's debug and release folders have the project specific .obj file.

Related

Removing extra files generated while creating a dll project in visual studio

While creating a dll project in VS17, I see multiple files were created on initialization.
But whichever project on C++ I work on, I don't see any such files in their environment. How can I get rid of these files in my environment. Is there any workaround to remove them entirely or reduce these 4 files to one file to reduce mess?
Also before VS17 we used to have stdafx.h, it is mandatory to include this header but in few projects I couldn't find this file, is there any way to remove these initial files entirely?
When you create a new project in Visual Studio, a precompiled header file named pch.h is added to the project. (In Visual Studio 2017 and earlier, the file was called stdafx.h.)
For more details about pch.h and stdafx.h, I suggest you could refer to the Doc:
Precompiled Header Files
If you couldn't want to use precompiled header file, I suggest you could choose to not use precompiled headers (Configuration Properties > C/C++ > Precompiled Headers).
When you create a dll project, you also directly choose uncheck Precompiled header or check Empty project.
stdafx.h/cpp resp. pch.h/cpp are the default generated files for supporting precompiled headers. If you don't want them you can delete them. In order to compile you then have to go to your project settings Configuration Properties -> C/C++ precompiled headers and change the Precompiled Header setting to Not using Precompiled Headers.
Before you delete thos files, you should check the cpp/h file and put the include files into your files.

Is it OK to make a stdfx.h file myself?

Now, I realized that I need a precompiled header for my project. However, at the beginning, I created my project as an empty project which doesn't have a stdfx.h header file. So, this is what I did:
- I created a header file name stdfx.h
- In that file, I included some libraries.
- I went to the project Property Pages -> C/C++ -> Precompiled header -> set the PRECOMILED HEADER option to Use (/Yu).
- Finally, I included stdfx.h in every cpp file.
It works. However, I am wondering if the stdfx.h file that I created myself works like the one that is automatically created by Visual Studio? I mean is it really a precompiled header which will save time when compiling or just a normal header file?
It's normally named stdafx.h, but it really doesn't matter. You can name your precompiled header whatever you want.
You are missing one final step.
You also need to create a stdafx.cpp. This is an empty file that only has a #include "stdafx.h" line.
For this particular file, right click on it in the Solution Explorer and select Properties. This will bring up a Properties page with settings specific to this source file (in inherits your project settings by default). For this particular file, select /Yc as the compiler option instead of /Yu for the Precompiled setting. If you don't do this, you may not observe the build speed improvements of precompiled headers.
When Visual Studio builds, it will build your stdafx.cpp file first. And along with that, it will build the .pch file that the other source files will pick up.
And while I'm here. The things to include in the precompiled header file are all the system and C/C++ runtime header files. (e.g. <windows.h>, <stdio.h>, <string>, <map>, etc...). You'll get the most gains by including all these files - since they never change from build to build.
You definitely can make stdfx.h by yourself or other precompiled header file (name is not really important). But you should follow some rules described in MSDN.
You can read more about precompiled headers in the Documentation

How to include header files of another projects in the same solution?

I have two C++ projects (proj1 and proj2) in the same solution. How to include the header files from proj1 into proj2? I included those header files in proj2 by setting Additional Include Directories, but cannot link those functions - Error: unresolved externals.
you don't need to from the reference of porj2,add proj1,then the compiler will link proj1 when compile proj2.
So your problem is not the actual inclusion of the header files, it's linking to the object files of the other project.
There are basically two solutions to that problem:
Simply pull in the source file from other project into the project where they are needed. This will cause you to build the source files twice, once for each project. Note that I don't mean you should physically copy the files on disk, just drag and drop the source files in the solution side-bar.
Put common code in a third project, as a library. Then both your projects uses this library, and links with it.
I highly recommend the second solution.
While you are getting linking error that means you have compiled your code successfully and that means that you have included your headers correctly. Congrats! However, you are facing unresolved externals error. This is because you have just tell the compiler where to find the .h file but what about the real code? yes the one in the .cpp?
Options:
Put all your code in .h files which could be a fast solution but not an good idea (unless you need portable solution for templated code).
Build your first project as static library and link with the output .lib file (you could find how to do it by quick googling)
Bring your sources (.h and .cpp) to the other project and build them inside your project (Huge redundancy happened here).

folder structure in Visual C++ when there are many projects depending on each other

say I have a sln which contains 10 projects(named proj1 to proj10), and proj1 is the default project which generate the EXE file.
My problem is: how to place the 'include' folder?
I mean if proj2 uses proj3(that is including its header file and linking its lib file), how to place the 'include' folder?
there are two approaches:
place all header files and lib files in a different root folder which is in the same level of the project
make every project self-close, and the other projects who want to use this project should take care of the include-path and link-path. Of cause we should give a rule to the layout of every project(e.x. every project MUST have a 'include' folder and 'lib' folder in the root folder)
any suggestion?
thanks
When it comes to Visual Studio, I don't like either of the two approaches you suggested, although mine is most closely related to your Option #2. The way I like to organise it is like this:
<SolutionRoot>
<Project1>
project1.vcxproj
someheader.h
somesource.cpp
<Project2>
<Project3>
<Project4>
<Project5>
application.sln
In case that's not obvious, that's a quasi-directory listing showing some project folders and the base solution file.
All new projects are just added to the solution using Visual Studio's default settings. Trying to go against this and making projects work like Linux projects (lib, include, src etc) just ends up causing you grief, so don't do it.
Now, I set my "additional includes" path on every project to $(SolutionDir). Then if I want to include something from Project1:
#include "Project1/someheader.h"
The advantage of this is you don't clutter up your 'additional includes', so it's easy to see at a glance what external includes a project has.
As for linking to lib files, why not take advantage of Visual Studio's project references feature. Honestly, your life will be easier. Simply hook it up so that Project2 references Project1, etc... Then you don't have to worry about libraries and linker paths. You only do that for toolkits that are outside your solution tree (eg distributions such as libpng or openssl).
Again, you free up that setting so it only shows linkages outside of the solution. The other advantage is that your build order is implicitly defined if you use references.
I would go with the 1st solution. it make the project settings simple. As the C++ projects we worked on, we always put the header files together.

What is the difference between "Create Precompiled Header" (/Yc) and "Use Precompiled Header" (/Yu) in Visual Studio?

I read the documentation in MSDN, but in the end I didn't get a clear idea what is the practical difference between them, exactly. Both seem to require stdafx.h to be added at the top of every *.cpp file.
I'm using VS2008.
Can anyone help clear things up?
Short summary of how to use PCH files in Visual Studio:
All cpp files in the project have to include stdafx.h (you can change this to something else if you wish)
Select project in Solution Explorer and in Properties -> C++ -> Precompiled Headers set 'Create/Use precompiled headers' to 'Use'. Hit Apply
While the Property Pages are still shown select stdafx.cpp in solution explorer and set the value to 'Create'
Well, I think that you must first understand the purpose of precompiled headers. In large projects, it can take ages to process all the headers required by a single client extension for example, so some people prefer to distribute the .pch files along with their libraries. In order to generate the .pch files, you use the /Yc compiler flag and the person who wants to consume your library will set the /Yu flag. See here and here for details.