1

I am trying to include a header file whose name is version dependent. The concrete name is given by concatenation of strings with the version number. The last one is retrieved from CMakeLists.txt using a configuration file.

#include "config.h" # load PROJECT_VER
#define HEADERROOT "foo-"
#define HEADERBASENAME HEADERROOT PROJECT_VER
#define HEADER HEADERBASENAME ".h"
// Equivalent to: #define HEADER "foo-5.1.h"

The string generated is correct, however, it is not possible to include it (appending to the previous statements)

#include HEADER
#include <iostream>
using namespace std;

int main() {
    
    cout << HEADER << endl;
    return 0;
}

The error is

main.cpp:6:10: warning: extra tokens at end of #include directive
 #include HEADER
          ^~~~~~
main.cpp:6:16: fatal error: foo-: No such file or directory
 #include HEADER
                ^
compilation terminated.
Zythos
  • 180
  • 2
  • 8
  • Yup, because the thing in the `#include` is not a string – CoffeeTableEspresso Nov 13 '20 at 21:35
  • 1
    You'll want to either find a way around the different names, or generate the name with a bash script or something. – CoffeeTableEspresso Nov 13 '20 at 21:38
  • 1
    You have to store the whole file name in a single macro from the very beginning. – HolyBlackCat Nov 13 '20 at 21:42
  • 1
    One issue with your approach is that the preprocessor is phase 4 of compilation, while the concatenation of adjacent string literals is phase 6. So for this purpose, `#define HEADER "foo-" "5.1" ".h"` is **not** equivalent to `#define HEADER "foo-5.1.h"`. *(Hmm... I'm assuming your implied question is how to accomplish your goal, rather than why your approach fails? If that assumption is wrong, I could transform this comment into an answer.)* – JaMiT Nov 13 '20 at 21:44
  • I solved it adding another `#define` in `config.h.in` with the full name. – Zythos Nov 14 '20 at 00:34

1 Answers1

0

You can't use a macro to define the filename for an #include statement. This kind of task is better handled in an external build process that creates the necessary source code before the preprocessor/compiler is then invoked.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    You can write `#include HEADER` as long as the macro name expands to either `”header.h”` or ``. The trouble in the question is that the macro expands to multiple strings and string concatenation only occurs after preprocessing is complete. – Jonathan Leffler Nov 14 '20 at 00:48