I am using GCC via MinGW/MSYS under Windows.
Currently i am using a home-brew IDE based on several Python & batch scripts, using Notepad++. Every time i compile my program, i run two scripts. One scans for all header files in my project, then writes a file called
"_include.hpp" that looks like this:
1 2 3 4
|
#pragma once
#include "file1.hpp"
#include "file2.hpp"
//...
|
The second reads all my header files and looks for class definitions, and puts all the forward declarations in a second header file. This header file i name
"_fwclass.hpp" and usually looks like this:
1 2 3 4 5 6
|
#pragma once
struct mystruct;
struct secondone;
union int_float;
class person;
//...
|
Then i have another header file called
".project.hpp" that includes everything and defines some other things. This header looks a lot like this:
1 2 3 4 5 6 7 8 9 10 11
|
#include <cstdlib>
#include <dependency_1/header.h>
#include <depencency_2/header.h>
#define MACRO_I_USE_A_LOT "Whatever"
enum Errors { noError, ioError, runtimeError };
#include "_include.hpp"
#include "_fwclass.hpp"
//EOF
|
So usually, in all the different modules i have in my program, i only have to write it like this:
1 2 3 4 5 6 7 8 9
|
//class.hpp
#pragma once
#include ".project.hpp"
class person {
std::string name;
void setname (std::string& arg);
};
//EOF
|
1 2 3 4 5 6
|
//class.cpp
#include ".project.hpp"
void person::setname (std::string& arg)
{ this->name = arg; }
//EOF
|
I then compile each module separately, then link together at the very end. I have been using this system for a long time now with 60+ files in my project and have never run into any issues. I like that all i have to do is #include one file and the rest is automagically generated.
Today, i decided to re-write my program from scratch to take advantage of some toolkits that would speed up development. I figured i could take the opportunity to improve on my current project structure while i'm at it. Something that i want to do is incorporate the header file into the source file, so there is only one file per module instead of two. Something that i've commonly seen in some single-file libraries is the following:
1 2 3 4 5 6
|
int foo( int bar, int wee );
#ifndef HEADER_ONLY
int foo( int bar, int wee )
{ return bar + wee; }
#endif
|
So i thought i might be able to take advantage of the separate compilation of each file in my project to combine this sort of format with my project's current structure. I was thinking about modifying my
".project.hpp" file by adding a line to the end as follows:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
#include <cstdlib>
#include <dependency_1/header.h>
#include <depencency_2/header.h>
#define MACRO_I_USE_A_LOT "Whatever"
enum Errors { noError, ioError, runtimeError };
#include "_include.hpp"
#include "_fwclass.hpp"
#define IMPLEMENT_MODULE
//EOF
|
And then in my individual modules, structure them like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
//class.cpp
#pragma once
#include ".project.hpp"
class person {
std::string name;
void setname (std::string& arg);
};
#ifdef IMPLEMENT_MODULE
void person::setname (std::string& arg)
{ this->name = arg; }
#endif
//EOF
|
This would combine the
".hpp" and the
".cpp" files into a single file and make it a lot easier for me to manage my code base.
Here is my thought process and justification:
Suppose you have two modules,
"foo.cpp" and
"bar.cpp". When compiling foo, the project header will be included, which will then include
"_include.hpp" which then attempts to include both foo and bar. The pragma statement prohibits foo from being included again, so the only thing that is included this time around is bar. The "header" portion of bar is included, but the actual implementation is skipped because
IMPLEMENT_MODULE is not yet defined. It is defined at the end of the project header, thereby leading to the compilation of the implementation of foo.
I was hoping to have some sort of macro to use that would look like this...
1 2 3 4
|
#define END_OF_HEADER \
#ifdef IMPLEMENT_MODULE \
#error \
#endif
|
Of course that would not directly work. I've looked into the
_Pragma functionality that C++11 has to offer, but i was hoping to avoid C++11 if at all possible.
I was hoping for some feedback on this system. How well would it work?