NO

Author Topic: Local inclusions  (Read 5744 times)

cane

  • Guest
Local inclusions
« on: May 03, 2006, 06:27:20 PM »
Hi, let's suppose I have a project with a direcotry structure organized this way:

project  --  main dir
project\src  --  sources dir
project\lib\mylib\  --  libraries (one dir for each lib, each dir containing both .lib and .h files)

Now, in the sources dir, let's have a file main.c with a local inclusion defined like this:
Code: [Select]
#include "..\lib\mylib\header.h" and a simple header file named header.h in project\lib\mylib.

Shouldn't the compiler get the relative path according to main.c location?

If I try to compile main.c from the project dir I obtain the following error:

cc src\main.c
src\main.c
src\main.c(1): fatal error #1035: Could not find include file "..\lib\mylib\header.h".

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Local inclusions
« Reply #1 on: May 03, 2006, 09:16:08 PM »
The IDE will set the project's top level directory as the working directory when it starts to build a project. The compiler will use the working directory when it expands a relative path. Too many projects already expect this behaviour.

If you for some reason can't loose the relative path in the source files, and can't add one or more search path's for #include files to the project, you can always add CD <dir> commands to the build rules. A bit tedious, but you should end up in the directory you want...

Pelle
/Pelle

cane

  • Guest
Local inclusions
« Reply #2 on: May 04, 2006, 05:09:44 PM »
It's a kind of strange behavior compared to other compilers.
OTOH, the C standard says this behavior is compiler dependent.
I think I can live with it. :)

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Local inclusions
« Reply #3 on: May 04, 2006, 05:18:40 PM »
No, it's not.
/Pelle

cane

  • Guest
Local inclusions
« Reply #4 on: May 04, 2006, 05:28:00 PM »
It's not compiler dependent?
I thought this stated so:
Quote from: "C99"

A preprocessing directive of the form
# include "q-char-sequence" new-line
causes the replacement of that directive by the entire contents of the source file identified by the specified sequence between the " delimiters. The named source file is searched for in an implementation-defined manner. If this search is not supported, or if the search fails, the directive is reprocessed as if it read
# include <h-char-sequence> new-line
with the identical contained sequence (including > characters, if any) from the original directive.

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Local inclusions
« Reply #5 on: May 04, 2006, 07:51:29 PM »
I meant the compiler behaviour isn't that different from other compilers. The problem isn't in the compiler, it's in the IDE build system.

If you click the 'Target files' button above the project tree, and choose 'Properties' for an OBJ file, you see: $(CC) ...

Currently, the compiler is running from the top level directory of the project, with a path into the subdirectory with the source file. a CD <subdir> before the $(CC) ... line will *probably* solve the problem. This way the compiler is running from the correct (source) directory, and the relative path for the include file will be resolved correctly.

I'm pretty sure I don't want to mess with this too much right now, with a new release coming up. Changing an already created project is *dangerous*, so any change in this area will always be for new projects only.
/Pelle

cane

  • Guest
Local inclusions
« Reply #6 on: May 05, 2006, 11:34:50 AM »
Ok, the following is really pedantic, so I beg your pardon in advance.

I haven't used POIDE for compiling my stuff, the example I reported was related to command line. Don't get me wrong: I understand what you're saying about the IDE build system. And the IDE build system does exactly what I did from command line:

c:\> cd project
c:\project\> cc src\main.c

I mean: if the IDE build system is molded on the behavior of the compiler, hence what needs to be "corrected" (let me state: I'm now definitely aware that this is not a bug) is in the compiler. What I'm trying to say is that: despite this behavior is perfectly legitimate it does not sound too much sensible. It's a matter of interpretation of relative local paths: relative to what? To the directory in which the file containing relative local inclusions resides, I would say.
The inclusion of header files by mean of relative local paths is actually different from other compilers. Try: MS, gcc, watcom, DMC. They all do well in the above situation.

The "solution" for not breking the compatibility with the present behavior might be to add a searching rule with a higher priority: search first in the path relative to the one in which the file requiring local inclusions dwells. Then search in the path relative to the working directory.

Thank you for your patience. :wink:

Offline Pelle

  • Administrator
  • Member
  • *****
  • Posts: 2266
    • http://www.smorgasbordet.com
Local inclusions
« Reply #7 on: May 05, 2006, 01:28:46 PM »
OK, sorry, I assumed you used the IDE - it seems to be the "popular" choice.

What is confusing to me is that the include file behaviour was changed a couple of years ago, to act like in "other" compilers. A couple of years is a long time, so I don't remember the exact details, but the setup was similar to yours, and then the *only working solution* was to use the current directory as the reference point. Maybe this is only correct in some cases, but at the moment I don't have enough information to see the difference to other cases...

I will try to set up a test case, but this will take some time.

Pelle
/Pelle

cane

  • Guest
Local inclusions
« Reply #8 on: May 05, 2006, 02:11:10 PM »
Quote from: "Pelle"
OK, sorry, I assumed you used the IDE - it seems to be the "popular" choice.


That's a good thing instead. What has been pointed out is also valid for the IDE build system. Because the IDE mimics what has been done from command line (or viceversa, you choose :D).

Quote
What is confusing to me is that the include file behaviour was changed a couple of years ago, to act like in "other" compilers. A couple of years is a long time, so I don't remember the exact details, but the setup was similar to yours, and then the *only working solution* was to use the current directory as the reference point. Maybe this is only correct in some cases, but at the moment I don't have enough information to see the difference to other cases...

I will try to set up a test case, but this will take some time.


Setting the working directory as the reference point could be a good choice, but this implies taking all relative paths and relativize them to the working directory trimming or adding things like "..\" and named partial paths in the head, if you want to stay with the interpretation I gave to relative local includes.

Anyways, the trick for me now is to relativize the paths to the working dir. this way in the code:
Code: [Select]

#ifdef __POCC__
   #include "lib\mylib\header.h"
#else
   #include "..\lib\mylib\header.h"
#endif

This fools both the IDE and the compiler pretty well.

Strictly regarding the IDE: the CD <subdir> "hack" partially does the trick (without using #ifdefs) modifying the object properties in this way:
Code: [Select]

cd src
$(CC) $(CCFLAGS) "$!" -Fo"$@"
cd ..

Note you need CD.. after compilation to avoid linking issues.

I've attached a workspace which presents 2 problematic cases (projects local3 and local4) and 2 "normal" situations.

I'm very glad you're taking this subject into account. Thanks again!