Project

General

Profile

Actions

Bug #3127

closed

Includes heavily rely on include paths

Added by Alex Afanasyev over 8 years ago. Updated over 7 years ago.

Status:
Closed
Priority:
Low
Assignee:
Category:
Core
Target version:
Start date:
08/21/2015
Due date:
% Done:

100%

Estimated time:
3.00 h

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.

Actions #1

Updated by Davide Pesavento over 8 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.

Actions #2

Updated by Davide Pesavento over 8 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 own common.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.

Actions #3

Updated by Junxiao Shi over 8 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.

Actions #4

Updated by Junxiao Shi over 8 years ago

a proper solution would be simply to rename NFD's common.hpp to nfd-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.

Actions #5

Updated by Davide Pesavento over 8 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 #includes, and only passing the "root" directory in -I flags.

Actions #6

Updated by Alex Afanasyev over 8 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.

Actions #7

Updated by Davide Pesavento over 8 years ago

So what do you propose, besides renaming common.hpp?

Actions #8

Updated by Alex Afanasyev over 8 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.

Actions #9

Updated by Junxiao Shi over 8 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").

Actions #10

Updated by Davide Pesavento over 8 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.

Actions #11

Updated by Davide Pesavento over 8 years ago

Alex Afanasyev wrote:

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'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.

Actions #12

Updated by Alex Afanasyev over 8 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.

Actions #13

Updated by Junxiao Shi over 8 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.

Actions #14

Updated by Davide Pesavento over 8 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.

Actions #15

Updated by Junxiao Shi almost 8 years ago

  • Tracker changed from Task to Bug
  • Category set to Core
  • Estimated time set to 3.00 h
Actions #16

Updated by Junxiao Shi over 7 years ago

  • Assignee set to Junxiao Shi
  • Target version set to v0.5
Actions #17

Updated by Junxiao Shi over 7 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.

Actions #18

Updated by Junxiao Shi over 7 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".

Actions #19

Updated by Davide Pesavento over 7 years ago

Junxiao Shi wrote:

#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.

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.

Actions #20

Updated by Junxiao Shi over 7 years ago

  • Status changed from Code review to Closed
Actions

Also available in: Atom PDF