dstep icon indicating copy to clipboard operation
dstep copied to clipboard

headers including other headers

Open chriscamacho opened this issue 6 years ago • 17 comments

Its a very common practice to split a libraries headers, in the easiest case the single header that you are supposed to use often has half a dozen or so includes and nothing else, while these can sometimes be handled manually, often these "local" (for want of a better word) includes can be more complex...

chriscamacho avatar Dec 31 '18 14:12 chriscamacho

I don't understand the issue/question.

jacob-carlborg avatar Dec 31 '18 14:12 jacob-carlborg

take a header like this (mylib.h)

#include "utils.h"
#include "foo.h"
#include "bar.h"
#include "core.h"

core.h probably relies on stuff in the other headers, and additionally paths for other local includes probably rely on a makefile giving the right include folders for them to compile... they might be in a folder called includes/mylib/ but be included as mylib/.... for example

chriscamacho avatar Dec 31 '18 14:12 chriscamacho

But what is the actual bug? So far you presented some facts. Please describe some examples of invalid/desired translation or a missing feature in dstep.

ciechowoj avatar Dec 31 '18 14:12 ciechowoj

DStep supports all flags that Clang supports. You can add include paths if necessary.

jacob-carlborg avatar Dec 31 '18 14:12 jacob-carlborg

I could be using it wrong, let me re-try a particular library I fail to use DStep with, and I'll try and give you something specific you can replicate...

chriscamacho avatar Dec 31 '18 15:12 chriscamacho

I'm not sure if this is a total fit for the issue, but the OP seems to have the same issue as I have. Assume the following "mylib.h" include file:

#ifndef MYLIB_H
#define MYLIB_H

#include "./mylib/a.h"
#include "./mylib/b.h"
#include "./mylib/c.h"

#endif

It would be nice to just give "mylib.h" on the command line.

Robert-M-Muench avatar Apr 27 '19 11:04 Robert-M-Muench

It would be nice to just give "mylib.h" on the command line.

Would that produce three D files or one, where all the declarations are inlined to mylib.h?

jacob-carlborg avatar Apr 27 '19 11:04 jacob-carlborg

Somehow related to #229

It would produce four .d files: a.d, b.d, c.d and one package.d which contains:

import mypackage.a;
import mypackage.b;
import mypackage.c;

Robert-M-Muench avatar Apr 27 '19 14:04 Robert-M-Muench

What would the package.d file contain? All imports for all the files specified on the command line or files matching #include in a specified file?

jacob-carlborg avatar Apr 27 '19 18:04 jacob-carlborg

By intuition, I would say all the files matching #include in a specified file. And, see my "Packages / imports & references between modules" thread in digitalmars.d.learn, then add an:

import mypackage;

to all generated files, to handle the forward referencing of C libs and work around the different semantics in D (the module needs to work by itself) and C (the file just inherits/sees everything that was included somehow).

Robert-M-Muench avatar Apr 28 '19 11:04 Robert-M-Muench

The reason why DStep doesn't already translate #include and why I'm reluctant to add that feature is because it's not reliable. I've seen header files which are using declarations from other files without containing a single #include. There can also be #includes that are not necessary.

jacob-carlborg avatar Apr 28 '19 12:04 jacob-carlborg

Well, if I specify explicitly which file to use when seeking for #includes I think that would work. Or I can explicitly list them on the command line.

Robert-M-Muench avatar Apr 28 '19 12:04 Robert-M-Muench

Well, if I specify explicitly which file to use when seeking for #includes I think that would work

It's still not reliable. Also, which #includes should be translated? #include <string.h>? Third party includes? How would DStep know which to translate and which not to translate? Should it translate includes transitively? How should it translate something like #include "../foo.h"? There are a lot of stupid things that are possible to do in C and with #include.

jacob-carlborg avatar Apr 28 '19 12:04 jacob-carlborg

I think most of the times using a package.d file is an anti pattern. What I've been thinking of for a while is adding support for specifying a whole directory that should be translated. Then it would be possible to automatically add imports for all declarations declared inside that directory. It could also create a package.d file with all files in that folder. This would be more reliable because DStep wouldn't need to translate #includes.

jacob-carlborg avatar Apr 28 '19 12:04 jacob-carlborg

Yep, that would make a lot more sense being a correct solution.

And an option to write out a single .d file that just contains everything would be great too. This would help a lot in post-processing the output, which is most likely needed anyway.

The other ideas & comments were more related to find a hack/workaround using the currently available features or extending them just a bit.

Robert-M-Muench avatar May 01 '19 08:05 Robert-M-Muench

I think there are several issue that can be solved by translating a whole directory. Like your issue with forward declaring structs.

jacob-carlborg avatar May 01 '19 08:05 jacob-carlborg

I think most of the times using a package.d file is an anti pattern. What I've been thinking of for a while is adding support for specifying a whole directory that should be translated. Then it would be possible to automatically add imports for all declarations declared inside that directory. It could also create a package.d file with all files in that folder. This would be more reliable because DStep wouldn't need to translate #includes.

Yes, please. I'm converting a project with a lot of .h and subfolders.

It would be useful to package each subfolder.

For example:

mylib/first/a.h
mylib/first/b.h
mylib/second/c.h
mylib/second/d.h

to:

mylib/first/a.d
mylib/first/b.d
mylib/first/package.d  <-- public import mylib.first.a; public import mylib.first.b;
mylib/second/c.d
mylib/second/d.d
mylib/second/package.d  <-- public import mylib.second.c; public import mylib.second.d;
mylib/package.d <-- public import mylib.first; public import mylib.second;

trikko avatar Sep 27 '19 12:09 trikko