1

I have a C program which has lots of includes in it, There are lots of macros in use to auto generate functions for the modules and in the build process, for example

#define MODULE_DEFINE(M) void M##_init (module* module) {\
        module->name = #M;
#define MODULE_END };

MODULE_DEFINE (hello)
        printf("module name is : %s\n",module->name);
MODULE_END

Now once the modules are compiled and linked, i need to include them all inside a common header file . One method would be to manually include all of them, but i am wondering if there is some better way to go around it ? I am already passing on them as as array shown below.

module mod_list[] = {
        MOD( hello )
};

The MOD used is yet another macro. Now the relevant part is, all the modules follow the include as

#include <modules/hello.h>

as in the example shown above. Can i somehow iterate over or create a list to auto-include from the list ? I don't mind changing from array to something else because i know that an array is defined at runtime and not possible for macro to actually iterate over that. If the iteration is possible i can define a common list to make all includes and define the array thereby automating the process a little. Thanks for any help.

Edit

As pointed this is not entirely possible only with macros. Now i am using CMake as my build tool. All the modules are placed in a separate directory in the format

modules
└── hello
    ├── hello.c
    └── hello.h

So can i somehow list all folders in CMake inside modules and pass them to configure_file to make the needed imports ?

georoot
  • 3,557
  • 1
  • 30
  • 59
  • `So can i somehow list all folders in CMake inside modules` - [file(GLOB)](https://cmake.org/cmake/help/v3.9/command/file.html) should help you in that task. `and pass them to configure_file to make the needed imports?` - With `for` loop on folders found, you may fill a variable with a list of `#include<>` directives. Then you may use this variable in `configure_file`. – Tsyvarev Oct 22 '17 at 12:59

2 Answers2

2

The C preprocessor itself is not a sufficiently capable language to do this sort of thing. What you might want to look at is code generation, where you have some kind of pre-build step that reads your file with the MOD( hello ) lines, and generates a file that lists the corresponding #include <modules/hello.h> lines. Then, include your generated file where you need it.

You can write this pre-build step in whatever language you want, reasonable choices could be: sed, awk, perl, C, Python, Ruby, etc.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Okay so i am using cmake as my build tool and the `MOD` is a simple macro function that gets the reference pointer to init method for the module. Are you suggesting to make changes in my cmake build file rather ? – georoot Oct 22 '17 at 06:40
  • @georoot: Yes, you could probably set this up with cmake. I'm afraid I'm not familiar enough with cmake to suggest exactly how you might do that. – Greg Hewgill Oct 22 '17 at 06:43
  • I really appreciate the time you took to point me in the right direction. Now i am clear on which side i need to go. Let me edit the question and add cmake tag with the modifications :) – georoot Oct 22 '17 at 06:44
  • "The C preprocessor itself is not a sufficiently capable language to do this sort of thing." [Are you sure?](http://coliru.stacked-crooked.com/a/268f625bed3323b4) – H Walters Oct 22 '17 at 17:01
  • @HWalters: That's using literals. That's not reading from the `mod_list` initialiser and dynamically generating `#include` directives. The point is, the OP only wants to have to list the modules once. – Greg Hewgill Oct 22 '17 at 17:09
  • @GregHewgill "That's using literals." What literals? Look closer. This iterates over `(FILE_A,FILE_B,FILE_C)`. "That's not reading from the mod_list initialiser" ...which isn't being asked, so no problem. "only wants to have to list the modules once." And that "once" can't be a preprocessor tuple? My comment, btw, is specifically about the part of your answer where you're saying the C preprocessor isn't sufficiently capable. – H Walters Oct 22 '17 at 18:03
0

CMake offers the command generate_file. You use it, to replace some variable with by its values. If you use ##_init (module* ${MODULE_NAME}) and have a CMake variable within the loop over the modules called MODULE_NAME, you can reach a solution.

I am not sure whether that's a good idea. Why can't you use some configure header file?

usr1234567
  • 21,601
  • 16
  • 108
  • 128