user152949
user152949

Reputation:

Preprocessing of C/C++ metaprograms

We have a large C++ project and would like to ship only the code that a customer asks for, thus removing all code that is not needed. I.e. if we have some metaprograms like:

/** File: calc.c */
#ifdef ENABLE_SOME_ADVANCED_FEATURE
/** Advanced calculations */
void AdvancedCalc(int a, int b) {
   // ...
}
#else
/** Basic calculations */
void BasicCalc(int a, int b) {
   // ...
}
#endif

I would like some script that does preprocessing of C++ metaprograms, thus if I only wanted the basic calculations after running the script the file would look like this:

/** File: calc.min.c */
/** Basic calculations */
void BasicCalc(int a, int b) {
   // ...
}

Thus, all the code we did not want to ship has been stripped away.

I'm sure there must be something like this out there.

Update:

I think How to get rid of ifdef's in a large c project has the solution I was looking for.

Upvotes: 3

Views: 413

Answers (5)

Sigi
Sigi

Reputation: 4926

I'd prepare a script that:

  • comment-out all the includes and the defines that must not be touched, with some "magic wildcard", like //@TAKE_ME_BACK@ and save it to a temporary file;
  • run cpp -C or whatever preprocessor on the temporary file (cpp -C has the advantage that the file doesn't need to terminate with .c). Important: it must not strip comments (that's the -C for)!
  • uncomment-in all the lines previously commented out, restoring your includes

If you need to deal with recursive #ifdef's, I think that awk range syntax (pattern1,pattern2) could be of great help.

On the other side, if you just need to ignore includes, something like this will do the job:

sed 's|^#include|//@TAKE_ME_BACK@#include|' $file > $file.tmp
cpp -C $file.tmp > $file.tmp2
sed -e '/^#/d' -e 's|//@TAKE_ME_BACK@||' < $file.tmp2 > $file

(you need to take care also of the lines beginning with # dropped by the preprocessor in the last sed).

Note1: in the example I that I have proposed the original file is overwritten: handle with care :)

Note2: working but not tested - just a suggestion to be elaborated/customized.

Upvotes: 0

nhed
nhed

Reputation: 5999

Several options:

  1. You can use gcc -E like others suggest, but you can also add the -H flag to get a file listing.

    2 . You could just do your compilation with -MD, and .d files will be generated. You can either process .d files with a script or better yet you can probably create a rule to zip up all dependencies as part of your compile.

  2. I would also look to see how debuginfo packages are generated as they drop sources in /usr/src/debug (at least in the RPM ecosystem)

Upvotes: 0

Ben Crowhurst
Ben Crowhurst

Reputation: 8490

Clang or G++

g++ -E source.cpp

-E Stop after the preprocessing stage; do not run the compiler proper. The output is in the form of preprocessed source code, which is sent to the standard output.

Input files that don't require preprocessing are ignored.

Visual Studio

preprocessor output to stdout

cl /E source.cpp

preprocessor output to file

cl /P source.cpp

Example of how to cut down the unwanted output (ignore-header.pl)

#!/usr/bin/perl

use warnings;
use strict;

while (my $line = <>) {

    if ($line !~ /^#include/) {
        print $line
    }
}

Execute

cat source.cpp | perl ignore-headers.pl | g++ -E -nostdinc -nostdinc++ -x c++ -

Resources

G++ Manual

Visual Stuido Manual

GCC preprocessor

Upvotes: 1

user3217895
user3217895

Reputation: 17

gcc -E filename should do the trick GCC Options

Upvotes: 0

synapse
synapse

Reputation: 128

You can use GCC preprocessor

gcc -E

See GCC preprocessor

Upvotes: 0

Related Questions