C++ build systems are a bit of a black art and the older the project
the more weird stuff you can find so it is not surprising that a lot
of questions come up. I'll try to walk through the questions one by one and mention some general things regarding building C++ libraries.
Separating headers and cpp files in directories. This is only
essential if you are building a component that is supposed to be used
as a library as opposed to an actual application. Your headers are the
basis for users to interact with what you offer and must be
installed. This means they have to be in a subdirectory (no-one wants
lots of headers ending up in top-level /usr/include/
) and your
headers must be able to include themselves with such a setup.
└── prj
├── include
│ └── prj
│ ├── header2.h
│ └── header.h
└── src
└── x.cpp
works well, because include paths work out and you can use easy
globbing for install targets.
Bundling dependencies: I think this largely depends on the ability of
the build system to locate and configure dependencies and how
dependent your code on a single version is. It also depends on how
able your users are and how easy is the dependency to install on their
platform. CMake comes with a find_package
script for Google
Test. This makes things a lot easier. I would go with bundling only
when necessary and avoid it otherwise.
How to build: Avoid in-source builds. CMake makes out of source-builds
easy and it makes life a lot easier.
I suppose you also want to use CTest to run tests for your system (it
also comes with build-in support for GTest). An important decision for
directory layout and test organization will be: Do you end up with
subprojects? If so, you need some more work when setting up CMakeLists
and should split your subprojects into subdirectories, each with its
own include
and src
files. Maybe even their own doxygen runs and
outputs (combining multiple doxygen projects is possible, but not easy
or pretty).
You will end up with something like this:
└── prj
├── CMakeLists.txt <-- (1)
├── include
│ └── prj
│ ├── header2.hpp
│ └── header.hpp
├── src
│ ├── CMakeLists.txt <-- (2)
│ └── x.cpp
└── test
├── CMakeLists.txt <-- (3)
├── data
│ └── testdata.yyy
└── testcase.cpp
where
- (1) configures dependencies, platform specifics and output paths
- (2) configures the library you are going to build
- (3) configures the test executables and test-cases
In case you have sub-components I would suggest adding another hierarchy and use the tree above for each sub-project. Then things get tricky, because you need to decide if sub-components search and configure their dependencies or if you do that in the top-level. This should be decided on a case-by-case basis.
Doxygen: After you managed to go through the configuration dance of
doxygen, it is trivial to use CMake add_custom_command
to add a
doc target.
This is how my projects end up and I have seen some very similar projects, but of course this is no cure all.
Addendum At some point you will want to generate a config.hpp
file that contains a version define and maybe a define to some version
control identifier (a Git hash or SVN revision number). CMake has
modules to automate finding that information and to generate
files. You can use CMake's configure_file
to replace variables in a
template file with variables defined inside the CMakeLists.txt
.
If you are building libraries you will also need an export define to
get the difference between compilers right, e.g. __declspec
on MSVC
and visibility
attributes on GCC/clang.
In short: no. For you, the web page prints out in two physical pages. For someone that has the font size cranked way up, it could be 3 pages. Or maybe they're printing on A4 instead of letter (or vice versa). Or maybe they're on Linux, OS X, or Windows 2k and have different fonts loaded than you do. Are all those stupid headers/footers turned on or off? What's the default margin size? Throw in browser differences and you really have no chance of getting a consistent printing experience.
The only thing CSS offers that is related to printing is page breaks, but even there, you can't prevent page breaks, only insert them before or after a particular element.
Best Answer
You can achieve this by adding the following to the start of your CMakeLists.txt:
I don't see a problem with doing this for throwaway projects, although I guess production projects would normally have a predefined name which would be set explicitly in the
project
command.When you mention that you "copy the entire directory of one project as the starting point of another", I assume you don't include the build tree when you copy? CMake isn't really able to handle the build tree being moved.