Ответ 1
Вряд ли такой способ существует или будет встроен в clang (или любой другой компилятор С++) в будущем. Проблема заключается в том, что прекомпилированные заголовки используются для ускорения этапа компиляции, который обычно значительно дороже, чем шаг предварительной обработки. В результате, если вы собираетесь только предварительно обработать ваш источник, предварительно скомпилированный заголовок просто не будет использоваться. Один из способов, который имеет пренебрежимо малую вероятность создать то, что вам нужно, - использовать параметр -include
вместо параметра -include-pch
(обратите внимание, что вы должны указать ему *.h
, а не файл *.pch
):
clang main.cpp -include PrecompiledHeader.h -E
Гарантированный способ решения вашей проблемы состоит в том, чтобы передать предварительно обработанный вывод через простую программу фильтра, которая смотрит на директивы # line "file"
и удаляет текст из #include
ed файлов:
clang main.cpp -E|remove_included_code
remove_included_code
может быть легко реализован в python, bash, C/С++ и т.д. Вот реализация С++ (С++ был выбран так, чтобы его можно было легко использовать в Windows):
remove_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;
}
Преимущество этого решения в том, что он будет работать со всеми компиляторами.