Reputation: 21
I am stuck in CMake dependency issue. CMake does not rebuild the program when I modified the CXX header files.
My file structure is as such
$ tree
.
├── a
│ ├── a.h
│ └── c.h
├── b
│ ├── b.h
│ └── c.h
├── CMakeLists.txt
└── main.cxx
File contents:
a.h
$ cat a/a.h
#include "c.h"
b.h
$ cat b/b.h
#include "c.h"
main.cxx
$ cat main.cxx
#include "a/a.h"
#include "b/b.h"
int main()
{
}
CMake depend.internal
$ cat CMakeFiles/hello.dir/depend.internal
# CMAKE generated file: DO NOT EDIT!
# Generated by "Unix Makefiles" Generator, CMake Version 3.7
CMakeFiles/hello.dir/main.cxx.o
/proj/mtk09331/work/tmp/cmake/a/a.h
/proj/mtk09331/work/tmp/cmake/a/c.h
/proj/mtk09331/work/tmp/cmake/b/b.h
/proj/mtk09331/work/tmp/cmake/main.cxx
CMakeLists.txt:
$ cat CMakeLists.txt
add_executable(hello main.cxx)
As you can see, b/c.h does not exist in the dependency list. Therefore, CMake won't rebuild the program if I modified b/c.h.
Does cmake not allow the same header file names? Altough it works with renaming the header files. But I would like to find a "correct" way to prevents this.
Thanks in advance
Upvotes: 1
Views: 2338
Reputation: 11
This appears to be a feature of make. As stated by @Tsyvarev, adding the sub-directory name in the #include
statement helps make find the correct dependencies but looks awkward in the source code.
ninja correctly determines the dependencies in the case above. To use with cmake install ninja and select it with ...
cmake -G Ninja
Upvotes: 1
Reputation: 65928
As @MABVT notes in the comment, CMake is unrelated here: the question is about proper projects' organization.
From the point of projects' organization, headers for every project can be devided into two parts:
private headers, which are used only for compile the project itself,
public headers, which are used by the outer world (by other projects).
Naming and organization of private headers are fully up to the project's author.
But for scalable projects naming and organization of their public headers should follow several rules:
Name of the public header should be unique among all projects.
Usually this is achived by moving these headers into the directory contained the name of the project.
Public header shouldn't include private header.
Public header should include other public header using only its unique name.
As you can see, headers a/a.h
and b/b.h
are public in your case.
But for headers a/c.h
and b/c.h
you should decide, whether they are public or private.
If you want to make a/c.h
private, then public header a/a.h
cannot include it (rule 2).
If you want to make a/c.h
public, then public header a/a.h
should include it using its unique name, that is #include <a/c.h>
(rule 3).
Upvotes: 1