9

I'm confused on how to use macros in the #include directive. I've done this:

#include "../../../../GlobalDefintions.h"
#include "../../../../lib/libc++/" ARCH_FAMILY_S  "/" ARCH_S  "/stkl/printkc/printkc.h"

GlobalDefintions.h:

#ifndef _GlobalDefintions_
#define _GlobalDefintions_

/*Architecture Information Start*/


#define ARCH i386
#define ARCH_FAMILY x86


#define ARCH_S "i386"
#define ARCH_FAMILY_S "x86"

/*Architecture Information End*/

#endif /*_GlobalDefintions_*/

But what that gives me is this:

kernel.c++:24:88: fatal error: ../../../../lib/libc++/: No such file or directory  

#include "../../../../lib/libc++/" ARCH_FAMILY_S  "/" ARCH_S  "/stkl/printkc/printkc.h"

Is there a way to successfully append ARCH_FAMILY_S and ARCH_S to my #include directive string?

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
amanuel2
  • 4,508
  • 4
  • 36
  • 67
  • 1
    Generally this stuff depends on the compiler, and is very fragile. Instead, control the selection of headers to include via the compiler's header include path option and/or environment variable. E.g. `CPATH` for g++, and `INCLUDE` for Visual C++. – Cheers and hth. - Alf Oct 15 '16 at 18:52
  • 1
    For concatenation you could define a concatenation macro. But again, it depends on the compiler. I remember really struggling with that until I realized that the general approach, of using macros in include directives, was ungood. – Cheers and hth. - Alf Oct 15 '16 at 18:53
  • Take a look at this: http://stackoverflow.com/questions/9096201/concatenate-string-in-c-include-filename – nempat Oct 15 '16 at 18:55
  • @Cheersandhth.-Alf i am using Makefiles and since i am writing an operating system i use cross-compilers such as `i686-elf-g++` – amanuel2 Oct 15 '16 at 18:56
  • String concatenation occurs after the preprocessor is done. The preprocessor does not allow those shenanigans. In my book, you should be specify the directory on the compiler command line and not in the source code. See also [What are the benefits of a relative path such as `"../include/header.h"` for a header?](http://stackoverflow.com/questions/597318/what-are-the-benefits-of-a-relative-path-such-as-include-header-h-for-a-hea) – Jonathan Leffler Oct 15 '16 at 18:57
  • @JonathanLeffler yes i have talked about that with `glauxosdever`in #osdev , but right now i need to solve this problem before moving any further. – amanuel2 Oct 15 '16 at 19:06

1 Answers1

8

You can use a series of macros to create your include file. Unfortunately, I can't think of any cleaner (in-source) way of doing this. This works for arm-eabi-none-gcc v5.4.1.

#define LIBC_DIR ../../../../lib/libc++/

#define STRINGIFY_MACRO(x) STR(x)
#define STR(x) #x
#define EXPAND(x) x
#define CONCAT(n1, n2) STRINGIFY_MACRO(EXPAND(n1)EXPAND(n2))
#define CONCAT5(n1, n2, n3, n4, n5) STRINGIFY_MACRO(EXPAND(n1)EXPAND(n2)EXPAND(n3)EXPAND(n4)EXPAND(n5))

// Concatenate the five elements of your path.
// Of course, this can be simplified if there is only a prefix and a suffix
// that needs to be added and the ARCH_FAMILY, /, and ARCH are always present
// in the macro-generated #include directives.
#include CONCAT5(LIBC_DIR,ARCH_FAMILY,/,ARCH,/stkl/printkc/printkc.h)
amanuel2
  • 4,508
  • 4
  • 36
  • 67
lungj
  • 721
  • 5
  • 16
  • 1
    I'm not sure this works. The message I get is fatal error: ../../../../lib/libc++/\"x86\" /\"i386\" /stkl/printkc/printkc.h: No such file or directory, which looks strangely formatted – AndyG Oct 15 '16 at 19:31
  • `kernel.c++:32:78: fatal error: ../../../../lib/libc++/\"x86\" /\"i386\" /stkl/printkc/printkc.h: No such file or directory` – amanuel2 Oct 15 '16 at 19:31
  • Sorry... you need to use `ARCH` and `ARCH_FAMILY` instead of the `_S`-suffixed versions. I've updated my answer. – lungj Oct 15 '16 at 19:32
  • Also, to save yourself the possibility of forgetting to update `ARCH_S` and `ARCH` together (and similarly, for family), you can use the `STR` macro I provided to define `ARCH_S` as `STR(ARCH)`. – lungj Oct 15 '16 at 19:35
  • Now it's fatal error: ../../../../lib/libc++/x86 /1 /stkl/printkc/printkc.h: No such file or directory – AndyG Oct 15 '16 at 19:36
  • That's weird... are you sure the `ARCH` variable is set correctly? The `/1` seems to have come out of nowhere. At least the `x86` part seems to have pasted correctly, so it looks like we're on the right track for your compiler. – lungj Oct 15 '16 at 19:39
  • It works now.. You just had to not have spaces when using include directive `#include CONCAT5(LIBC_DIR,ARCH_FAMILY,/,ARCH,/stkl/printkc/printkc.h)` – amanuel2 Oct 15 '16 at 19:40
  • @AndyG the space.. `, ARCH_FAMILY` . Try to get rid of those spaces and it should work! – amanuel2 Oct 15 '16 at 19:46
  • @AndyG, it looks like the compiler used on ideone converts `i386` into the number 1. I'm not sure what feature of C/C++ that is, though. You can verify this at http://ideone.com/BkNrHm – lungj Oct 15 '16 at 19:48