Bug #3127
closedIncludes heavily rely on include paths
100%
Description
While importing NFD and ndn-cxx into ndnSIM, I encountered a bugging issue that include directives in NFD codebase rely heavily on include paths. The issue is better with ndn-cxx, where we made sure all includes in header files are relatively and don't require proper -I
flags.
I'm proposing to do the same with NFD: make all include statement (at least in header files) relative. If we do it everywhere, we can significantly reduce "includes" statements.
While this is not an issue for NFD itself, there is one problem in ndnSIM. Specifically with common.hpp
include: the same name used in NFD and ndn-cxx. When -I
flags are properly configured, everything is fine: ndn-cxx finds its own common.hpp
and NFD finds its own. However, there could be cases when it is hard or impossible to configure proper -I
.
Updated by Davide Pesavento about 9 years ago
Why is this an issue? In fact, I find relative paths in #include
directives very ugly and fragile... think about for example when the file/directory hierarchy changes...
I've never heard anyone saying that relying on -I
flags is bad. In fact, I often see long lists of -I/path/to/foo -I/path/to/bar
(both absolute and relative paths) when I compile other software.
Updated by Davide Pesavento about 9 years ago
Alex Afanasyev wrote:
While this is not an issue for NFD itself, there is one problem in ndnSIM. Specifically with
common.hpp
include: the same name used in NFD and ndn-cxx. When-I
flags are properly configured, everything is fine: ndn-cxx finds its owncommon.hpp
and NFD finds its own. However, there could be cases when it is hard or impossible to configure proper-I
.
This is somewhat orthogonal to the -I
thing, and a proper solution would be simply to rename NFD's common.hpp
to nfd-common.hpp
.
Updated by Junxiao Shi about 9 years ago
An issue should have a clear boundary.
Update the issue description to clarify whether the change applies to (a) headers only (b) also the implementation (c) also the test suites.
I can agree with (a) headers only, because NFD, when appearing in ndnSIM, is a library, so it makes sense for headers to use relative paths.
This shall also help with #2662.
I will disagree with (c) because NFD test suites won't affect ndnSIM in any way.
Updated by Junxiao Shi about 9 years ago
a proper solution would be simply to rename NFD's
common.hpp
tonfd-common.hpp
.
I agree with the basics of this solution, but disagree with a detail.
ndn-cxx's common.hpp
is the one that should be renamed, because it has been declared to be an implementation detail.
NFD and several other projects have common.hpp
, and we shouldn't restrict the available file names for all those dependent projects.
Updated by Davide Pesavento about 9 years ago
Just to be clear... all paths in #include
directives are relative. The two cases we want to differentiate are (I guess):
- relative to a
-I
path, e.g. the project root:#include "foo/bar.h"
- relative to the directory that contains the current file:
#include "bar.h"
(omitting./
) or#include "../blah/bla.h"
If you want to reduce the number of -I
flags (for reasons unknown to me), the proper solution is always using the full (relative) path from the project "root" in #include
s, and only passing the "root" directory in -I
flags.
Updated by Alex Afanasyev about 9 years ago
I will be happy with inclusion from the project "root". We almost followed that, with exception that core
, daemon
, and rib
are considered project roots. It is fine for NFD itself, but creates a minor hassle when integrating NFD somewhere else.
I kind of agree with Junixao's note 4, that the real problem I was having is ambiguous "common.hpp". As of right now the code magically works because all ndn-cxx headers use relative paths (real relative paths) to include common.hpp, and I've prioritiezed NFD's common.hpp to be included in other cases.
Updated by Davide Pesavento about 9 years ago
So what do you propose, besides renaming common.hpp?
Updated by Alex Afanasyev about 9 years ago
I would still update NFD code and change includes to start from "NFD root" (e.g., adding daemon, rib, and core prefixes to most of the includes). This way, common.hpp
(and, btw, version.hpp
too) in NFD will also become relatively unique.
Updated by Junxiao Shi about 9 years ago
I disagree with note-8.
daemon
and rib
are considered project roots, and it should be kept this way.
I could agree with changing all includes in NFD headers to use paths relative to the current file (eg. #include "../../core/scheduler.hpp"
).
Updated by Davide Pesavento about 9 years ago
Junxiao Shi wrote:
I could agree with changing all includes in NFD headers to use paths relative to the current file (eg.
#include "../../core/scheduler.hpp"
).
As I already said, this is fragile and very ugly. Also, there's no reason to make this change.
Updated by Davide Pesavento about 9 years ago
Alex Afanasyev wrote:
I will be happy with inclusion from the project "root". We almost followed that, with exception that
core
,daemon
, andrib
are considered project roots. It is fine for NFD itself, but creates a minor hassle when integrating NFD somewhere else.
I'd like to point out that NFD is an application, therefore it's extremely rare that it has to be integrated into something else. It should be ndnSIM that adapts to NFD, not the other way around. Of course if some changes in NFD can make things easier, great, I'm all for it, but this must not come at the expense of the NFD codebase.
Since it seems that the only real issue is with common.hpp, let's just rename that file and be done with it.
Updated by Alex Afanasyev about 9 years ago
Just a small note. There are at least three instances where NFD is not just an applications: NFD within ndnSIM, NFD as part of android app, and NFD as part of OS X app (we had initial not-yet-publicly-released prototype). So, not too rare.
Specifically within ndnSIM (and possibly with android), there will be other applications that needs to be compiled against both ndn-cxx and NFD as libraries.
The minimal change I would like to see is updating #include "common.hpp"
and #include "version.hpp"
in NFD codebase to #include "core/common.hpp"
and #include "core/version.hpp"
, as these two are the source for my future problems. I think in general, anything that crosses "subproject" boundary in NFD (e.g., accessing core headers from daemon and rib), should use path from root of NFD.
Updated by Junxiao Shi about 9 years ago
I agree with the minimal change in note-12, but it should be expanded a little that all headers in core/ should be included with core/ prefix.
That solution also implies moving common.hpp into core/, which I agree as well.
Updated by Davide Pesavento about 9 years ago
Junxiao Shi wrote:
I agree with the minimal change in note-12, but it should be expanded a little that all headers in core/ should be included with core/ prefix.
That solution also implies moving common.hpp into core/, which I agree as well.
Fine with me.
Updated by Junxiao Shi over 8 years ago
- Tracker changed from Task to Bug
- Category set to Core
- Estimated time set to 3.00 h
Updated by Junxiao Shi over 8 years ago
- Assignee set to Junxiao Shi
- Target version set to v0.5
Updated by Junxiao Shi over 8 years ago
- Status changed from New to Code review
- % Done changed from 0 to 100
https://gerrit.named-data.net/3022 fulfills note-13 design.
I used this command to replace #include
lines in other files:
for H in config.hpp version.hpp $(cd core && ls *.hpp); do for F in $(grep -lr $H daemon/ tests/ tools/ rib/); do sed -i 's|#include "'$H'"|#include "core/'$H'"|' $F; done; done
#include
lines within core/
itself is not changed, because I think the current directory is always preferred over any other directory specified through includes paths.
I'm unsure whether any include paths in wscript
can be deleted, so I didn't touch it.
Updated by Junxiao Shi over 8 years ago
https://gerrit.named-data.net/3022 patchset2 corrects a mistake with PCH.
I also removed core
from core-objects export_includes. The effect is that any file outside core/
cannot directly #include "common.hpp"
.
Updated by Davide Pesavento over 8 years ago
Junxiao Shi wrote:
#include
lines withincore/
itself is not changed, because I think the current directory is always preferred over any other directory specified through includes paths.
Correct, if you're referring to double-quoted includes. https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html says:
GCC looks for headers requested with
#include "file"
first in the directory containing the current file, then in the directories as specified by-iquote
options, then in the same places it would have looked for a header requested with angle brackets. For example, if /usr/include/sys/stat.h contains#include "types.h"
, GCC looks for types.h first in /usr/include/sys, then in its usual search path.
Other compilers do the same AFAIK.
Updated by Junxiao Shi over 8 years ago
- Status changed from Code review to Closed