1

In the context of a coding contest, I must copy/paste all my C++ code in a single html input form, the code being compiled remotely. With the code getting bigger, I'd like to split the code into several files.

So, I have several C++ source files, one is main.cc and some others headers such as f.h. I'd like these source files to be concatenated in a single source file allinone.cc with so that i can compile with clang++ allinone.cc. I guess this can be achieved using clang preprocessor.

A minimal example would be:

  • main.cc

    #include <iostream>
    using namespace std;
    
    #include "f.h"
    
    int main() { 
       f();
    }
    
  • f.h

    #pragma once
    #include <iostream>
    using namespacestd;
    
    void f() { 
      cout <<
    }
    

The closest I could get is with :

clang -E -nostdinc main.cc | grep -v "^#" > allinone.cc 

which produces:

#include <iostream>
         ^~~~~~~~~~
1 error generated.

using namespace std;
using namespacestd;

void f() {
  cout <<
}

int main() {
   f();
}

The -nostdinc option successfully avoids including code from standard includes. However, the original #include <iostream> disappears and the namespace specification is repeated.

Is there a way to invoke clang preprocessor to achieve the concatenation described in a straight forward manner?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
user1551605
  • 166
  • 9
  • 1
    Heaven deliver us from the restrictions imposed by bad courses... – DevSolar Apr 06 '20 at 00:20
  • @user1551605 I recommend describing the motivation in the question. I have another question: Why use clang pre-processor when g++ is used for compilation? – eerorika Apr 06 '20 at 00:23
  • What kind of contests are you doing? As a competitive programmer myself I find no reason to split code into multiple files. If the competition only allows submitting a single file it's easiest just to write code in a single file. – eesiraed Apr 06 '20 at 00:30
  • @eerorika i have edited the question to follow your advice. I used g++ in the text as a generic invocation of the C++ compiler, which links to clang++ in my setting. Also edited this as it is might be confusing. – user1551605 Apr 06 '20 at 00:30
  • If your project is a single source file, then it's easy to use a text editor. Find all the `#include` (in `"filename"` form), replace each one with the content of the header. If that brings in more `#include`s, repeat, but don't copy any header a second time. Remove non-standard constructs (vary between compilers) like `#pragma once` (the effect of those constructs is unpredictable if you have copied the content of header files manually). If your code will be checked by a human, remove any `#include` guards (and use this as a sanity check that you haven't copied any header more than once). – Peter Apr 06 '20 at 00:35
  • @Legolas Thanks ! This is exactly this, missed this post. The contest mentioned in the is the one i'm struggling for. – user1551605 Apr 06 '20 at 00:41
  • You could possibly #include all the files into one, and see https://stackoverflow.com/a/21671446/1766544 – Kenny Ostrom Apr 06 '20 at 00:56

1 Answers1

1

clang -nostdincdoes another thing, not what you expect. This key disables the standard include directories from the include search paths. So, you get the error since the preprocessor is unable to include the file -nostdinc, could not find it in the known include search paths.

What you want is impossible to achieve. You should use cat your files and clean the result manually or use a special software that can remove #include. I suggest you just use a combinations of grep, sort, uniq and place removed and filtered #include into the top of the concatenated file.

273K
  • 29,503
  • 10
  • 41
  • 64