如何使clang -E省略预编译头

Luc*_*jer 11 c++ clang precompiled-headers

PrecompiledHeader.h:

#include "stdio.h"
Run Code Online (Sandbox Code Playgroud)

main.cpp中:

#include "PrecompiledHeader.h"
#include "stdio.h"

int main()
{
   return 123;
}
Run Code Online (Sandbox Code Playgroud)

创建预编译头:

clang -x c++-header PrecompiledHeader.h -o PrecompiledHeader.pch
Run Code Online (Sandbox Code Playgroud)

在main.cpp上运行clang预处理器:

clang main.cpp -include-pch PrecompiledHeader.pch -E 
Run Code Online (Sandbox Code Playgroud)

这当前输出许多页输出(stdio.h).但是,我想得到的只是main函数,并且从输出中省略了PrecompiledHeader.h的内容.

有没有办法让clang这样做?(如果有人知道visualstudio的cl.exe同样问题的答案,我也很想知道:)

Leo*_*eon 4

这种方式几乎不存在,也不会在未来内置到 clang(或任何其他 C++ 编译器)中。问题在于,预编译头用于加速编译步骤,这通常比预处理步骤昂贵得多。因此,如果您只想预处理源代码,则根本不会使用预编译头。产生您想要的结果的可能性微乎其微的一种方法是使用选项-include而不是-include-pch选项(请注意,您必须指定*.h而不是*.pch文件):

clang main.cpp -include PrecompiledHeader.h -E
Run Code Online (Sandbox Code Playgroud)

解决问题的有保证的方法是通过一个简单的过滤程序传输预处理输出,该程序查看指令# line "file"并删除来自#includeed 文件的文本:

clang main.cpp -E|remove_included_code
Run Code Online (Sandbox Code Playgroud)

remove_included_code可以很容易地用python、bash、C/C++等实现。下面是一个C++实现(选择C++是为了在Windows下最容易使用):

删除_included_code.cpp

#include <iostream>
#include <cstdlib>

using namespace std;
typedef std::string Str;

bool isLineDirective(const Str& line)
{
    return line.size() >= 3
        && line[0] == '#'
        && line[1] == ' '
        && isdigit(line[2]);
}

Str getFile(const Str& line)
{
    const Str::size_type start = line.find_first_of('"') + 1;
    const Str::size_type end = line.find_first_of('"', start);
    return line.substr(start, end - start);
}

int main()
{
    Str line;
    getline(cin, line);
    if ( !isLineDirective(line) ) {
        cerr << "Error: Input must start with a '# line \"file\"' directive\n";
        exit(1);
    }

    const Str startFile = getFile(line);
    Str currentFile = startFile;
    while ( getline(cin, line) ) {
        if ( isLineDirective(line) )
            currentFile = getFile(line);
        else if (currentFile == startFile )
            cout << line << endl;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该解决方案的优点是它适用于所有编译器。