I have a VS generated C++ Win32 DLL project. It has the following files:
stdafx.h
targetver.h
myProject.h
dllmain.cpp
myProject.cpp
stdafx.cpp
I can remove targetver.h, and merge dllmain.cpp into myProject.cpp. What more can I do to get the simplest file structure, preferably one file. I need to dynamically emit this code file and build it into a Win32 DLL.
If you want a minimalistic file structure, you could just create the files yourself. Start an empty project, or delete all the files. Heck, just make a folder, write main.cpp, and compile it from the command line with cl.
Few IDEs really try to minimize files like you're trying to -- but when you create the project, you can cut back a little: stdafx.[h, cpp] are for precompiled headers, which you could disable when creating the project.
That said, I don't really see the value in minimizing the amount of source code in a compiled language project -- it's not going to have a meaningful impact on the number of output files/dlls and, properly used, using more files only helps your code's clarity.
In addition to what Andy said, you can merge the myProject header and implementation files as well with dllmain.cpp. But why not just keep these files and create the vsproj file at runtime?
Or you could just create an empty project.
IIRC, myProject.h and myProject.cpp both contain an example of an exported class. You can easily delete those.
stdafx.cpp and stdafx.h are used for the standard precompiled header file. If you turn off the setting that requires a precompiled header, then those files won't be necessary, either.
You could #include your generated file into a existing multi-file project. That way you can have a shell of a complicated project and only emit something smaller, like a simple function.
For example:
#include <system_stuff>
void main()
{
Go();
}
#include "generated_file_that_has_method_go.cpp"
void other_code()
{
}
Related
Background: I'm using Project Euler as an excuse to test various C++ features and find holes in my knowledge. I have a project that creates an executable which solves various math problems. It's getting unwieldy and I'm splitting the problems out into separate executables. A lot of the math functions are re-used in several of the problems.
First: I want to create a DLL file with math helper functions. Rather than provide one single mathhelp.h file for the entire dll, I'd prefer to have several separate .h files e.g. primes.h, cartesian.h etc./ that each provide access to separate namespaces in the dll.
Is this possible?
Second: Separately, I do want a single mathhelp.h file for those projects big enough they just need access to every helper function without including fifty separate headers. How to do this is answered in:
How to export multiple header files as a single header file in C++?
but that answer gives me a follow-up question: If, in an executable project, I include the following header from the DLL project:
#ifndef MATHHELP_H
#define MATHHELP_H
#include "primes.h"
#include "cartesian.h"
#endif
...how does that compile if I don't also have primes.h in the executable project? Won't the pre-compiler reach the first #include and choke on the fact that I don't have primes.h in the project?
When you provide a c++ compiled API to a user ( let's say it is compiled in a .dll file) you should provide beside the .dll file also the .h files (containg all header that were used to compile that .dll) and .libfiles ( containg the exported symbols from that .dll ).
Now let's say that your user has the executable a.exe, and wants to use your compiled API. Usually you will provide them a file structure which looks more or less like that :
include / primes.h
cartesian.h
mathhelp.h
lib / Api.lib
bin / Api.dll
When an external executable uses your code he will need to add external flags in the compilation procedure like : -I/pathToInclude -L/PathToLib -l/yourLibrary ( you need to check the exact sintax for doing that).
In your code you you will have something like this:
#ifndef MATHHELP_H
#define MATHHELP_H
#include <primes.h>
#include <cartesian.h>
#endif
In this case the compiler will look firstly in the current directory ( where he won't find the headers) and then in the folders specified by the -I flag ( where he will find your headers).
I have a solution which contains several projects. My projects (but not all of them) use precompiled headers. I decided to use protobuf and I've met a problem. After generetaing *.pb.h from *.proto by protoc.exe I'm trying to include the header and get the error - precompiled header wasn't included into *.pb.h.
How I can solve this problem? I have an idea (but I don't like it at all) - after protoc generates *.pb.h I can run some script, which'll include my precompiled header into the *.pb.h. But I don't like it because some projects may not use PCH, and PCH file name can be different.
I understand that I can just remove PCH from my projects, but I don't like that idea too.
Dont add the generated myproto.pb.cc to your project. Instead, create a myproto.cpp with
#include "pch.h"
#include "myproto.pb.cc"
I resolved my problem by creating a static library called proto-objects (without PCH) and including all my *pb.h(cpp) files there. After it I link that library to every project where I need my protobuf objects. Profit!
You can disable the pre-compiled header option on a file-by-file basis.
Given that the pch option is intended to speed up compilation, you can turn it off for the whole project, and no further changes should be necessary.
The choice of name of the header file, and the pch file are also selectable per file in the project
Update
The idea behind Microsoft's Pre-compilation PCH system is to
Speed up compilation
Make it easy to use
The header file system in C/C++ is problematic, as it is really a textual replacement.
That means that
#include "localdefs.h"
#include <windows.h>
#include "project.h"
#include "support.h"
Is in no way similar to
#include <windows.h>
#include "project.h"
#include "support.h"
That is because localdefs.h can redefine the behavior of all of the other includes.
Further to this the costs of walking through the complexities of the windows.h header files, is time consuming.
The PCH system tries to solve this by the observation that most projects have a fixed set of include files which are included by most/all of the CPP files.
Defining this set in stdafx.h allows the textual result of that parsing to be pasted in the cpp file and save a lot of work.
If most of the includes in the project are different, then there is no need to use it.
So if you are including the same qt header files in lots of places - add them to a pre-compiled header file. The more of the common includes added to this file, the better the compile speed improvements will be.
Any non-standard cpp file can be excluded by being specifically disabled - examples are "generated files". Where the template generator does not understand the MSVC system.
If all the files are different, then only limited performance benefit will be gained - as each compile would probably also include a pch recompile.
I am having a problem of getting compile errors (red underlines) like:
Error: cannot open source file "stdafx.h"
Here an edited screenshot of the environment:
On the LEFT is my Visual Studio Solution Directory list with the "Show All Files" off.
I am working on a school project, and each Folder are the source files of different parts of the project with different people who are in-charge of them.
For example, Student A and B are incharge of AST and PARSER folders (we will call them sub-projects).
We have an API for each sub-project so other sub-projects know what to call.
At the TOP-CENTER, we have my Source File for a class QueryProcessor. (just the first few lines)
Below it, is the Output for the Build Success.
The red lines are all over all the classes, mainly cause the #include "stdafx.h" cannot be opened by the environment.
On the RIGHT, that is the stdafx.h where we include all the different sub-projects so we save the trouble of each project having a different stdafx.h
However, I am able to build the project. I am pretty sure I am doing this directory/linking wrongly.
This should work
Right click on the solution file
Click Open in Windows Explorer
Find file stdfx.h in explorer and copy the path of the folder
In visual studio solution explorer, Right click on the project file
Click properties-> C/C++ -> General
In the Additional Include Directories paste the path
Combining folders and virtual folders in VC is from my point of view messy because the virtual folders indicate that all files are in one directory and the folders created on the harddrive obviously indicate that all files are in different directories. You can combine it if you know what's going on but in your case I would not recommend it.
I assume you missunderstand the purpose of stdafx.h The purpose of this header file is NOT to put all header filles into it and then just include it to all other files. Here is a SO question about this Purpose of stdafx.h
After cleaning up your stdafx.h file include as many header files into your .cpp files and only put these includes in your header files if they are required in the header file
Turn on show all files, now you will work with actual folders and you can be sure that if you adress a folder like "PKB" that this folder really exists since you can see it in the left solution explorer.
If you use using namespace std; for example make sure you also include the required header files. You might think "hey I already included e.g. iostream in another header file which I now include in this header file so I don't need it" That will really destroy you when you work with bigger projects.
Oh and regarding the stdafx.h include problem as soon as you switch to show all files I assume you will realise that stdafx is in a different file than the file where you use the include. Maybe something like #include "..\stdafx.h" is required (depending on your structure).
I think it's obivious but if you include a header file the include is allway relative to the file which is including the other header file.
stdafx.h is commonly used for creating a precompiled-header, which essentially is a compile-time optimisation such that the compiler will not continually compile these headers for every compilation unit.
If any of these headers changes, you will need to do a full system rebuild.
In reality it is preferable only to use it to include standard headers plus third-party headers (like boost libraries and similar) that you are not ever going to change.
You may decide that some of your own libraries are "set in stone" and can also be included.
Every project, i.e. every part of the project that is built into a separate unit (DLL or .exe) should have its own precompiled header and its own version of stdafx.h
Projects should only ever include their own .stdafx and not those of other projects, therefore this header file can also be used to define your dllexport macro.
When arranging your project headers you should be aware of:
1. Which headers are included externally
2. Which headers are only included internally, and are not even included indirectly externally.
The latter sort should include your stdafx.h file and should ideally not be in the same directory as those headers included from outside your project.
I am working on a project that has a vendor-provided API. I've made a class that uses that API in my project and I've included the vendors header file in my stdafx.h file. Things would not compile.
I then put the #include directly into my class' header file and now things compile (And yes, my class includes stdafx.h so that isn't the reason.
Do any of you have any guesses as to why it wouldn't compile the first time around? This isn't a project-stopper by far but I'd prefer if I could keep all vendor API files in stdafx.h where they belong.
EDIT: Problem solved, I'd created a cyclic dependency by forgetting to #ifndef a header file and then including them in the wrong order. I feel like an idiot.
stdafx.h is mainly used in the VS generated projects as the 'container' of headers to be precompiled.
When you added a new #include to stdafx.h it didn't get included because your project is probably configured to use precompiled headers, and when you add something to stdafx.h you need to regenerate the .pch file that contains the precompiled information.
One way to do that is to have a .cpp file in your project that does nothing but #include "stdafx.h". Maybe call it `precompile.cpp". Then go to the project settings for that one .cpp file and change the following setting (for all configurations):
"C/C++ | Precompiled Headers | Precompiled Header" setting
and select "Create /Yc".
That will set up the build so that when precompile.cpp needs to be built (because the stdafx.h header it includes has changed), it'll rebuild the .pch file that everything else uses.
EDIT: Wait - I don't think I read the question right. May still be helpful, though.
Another name for stdafx.h is a 'Precompiled header'
There aren't really any 'vendor specifics' in stdafx.h, what it does is it precompiles headers so that the compiler doesn't have to re-compile them every time you build the project.
It's only really helpful if you have a huge project (or a small one that includes tonnes of headers).
I use visual studio 2010 as well, generally it's not worth the fuss - I just disable it (which would solve your class inclusion issue also - make your own header, stick the vendor's in there).
I just have a quick question. I've noticed that I don't have stdafx.h in my compiler(mingw32 on windows)
Am I supposed to have it? Or maybe is there a way to get around it?
Thanks for reading
EDIT: ok here is my current build log once I took out ALL of the includes of stdafx.h
http://pastebin.com/bczLr8xY
Read this wikipedia article. The paragraph I linked and the paragraph below it (mingw32 uses GCC).
http://en.wikipedia.org/wiki/Precompiled_header#stdafx.h
Since stdafx.h contains the most common headers I would remove every instance of #include stdafx.h and try to compile. If you get compile errors that a certain function is missing, add the appropriate header. Rinse and repeat.
No. Stdafx.h is created with MSVC++. It usually contains most common headers files. And Stdafx.h is included in every .cpp file in the beginning. It's precompiled header (if you've chosen so in the settings) created by MSVC++.
To all:
Using the pre compiled header file stdafx.h in the visual C++ always creates one or the other problem n case u have created a "Windows Console App" from Visual C++.
The Solution to it is that, just create "Empty Project", rather than the pre-compiled windows console application. After creating the Empty project, create the source File. Write the business logic and add all the required resource and header files. Keep the external dependency files in the same directory in which your source code is: e.g., C:\Users\John\Documents\Visual Studio 2010\Projects\xyz.cpp\xyz.cpp.
Finally add the source file to the global scope, that is add it to the "Empty Project" created already. It can be done by Clicking "File" on Visual Studio prompt and select the option of adding the source file to the project.
Thanks and Regards:
Rouf Khan