Предварительно скомпилированные заголовки с GCC

Кто-нибудь успел получить предварительно скомпилированные заголовки, работающие с GCC? Мне не повезло в моих попытках, и я не видел много хороших примеров того, как настроить его. Я пробовал на cygwin gcc 3.4.4 и использовал 4.0 на Ubuntu.

Ответ 1

У меня определенно был успех. Во-первых, я использовал следующий код:


#include <boost/xpressive/xpressive.hpp>
#include <iostream>

using namespace std;
using namespace boost::xpressive;

//A simple regex test
int main()
{
    std::string hello( "hello world!" );

    sregex rex = sregex::compile( "(\\w+) (\\w+)!" );
    smatch what;

    if( regex_match( hello, what, rex ) )
    {
        std::cout << what[0] << '\n'; // whole match
        std::cout << what[1] << '\n'; // first capture
        std::cout << what[2] << '\n'; // second capture
    }
    return 0;
}

Это был просто мир привет от Boost Xpressive (см. ниже ссылку). Во-первых, я скомпилирован с опцией -H в gcc. Он показал огромный список заголовков, которые он использовал. Затем я взглянул на флаговые компиляции, которые создала моя IDE (code:: blocks), и увидела что-то вроде этого:

g++ -Wall -fexceptions -g -c main.cpp -o obj/Debug/main.o

Итак, я написал команду для компиляции файла Xpressive.hpp с теми же самыми флагами:

sudo g++ -Wall -fexceptions -g /usr/local/include/boost/xpressive/xpressive.hpp

Я скомпилировал исходный код с помощью -H и получил этот вывод:

g++ -Wall -fexceptions -H  -g     -c main.cpp -o obj/Debug/main.o
! /usr/local/include/boost/xpressive/xpressive.hpp.gch
main.cpp
. /usr/include/c++/4.4/iostream
.. /usr/include/c++/4.4/x86_64-linux-gnu/bits/c++config.h
.. /usr/include/c++/4.4/ostream
.. /usr/include/c++/4.4/istream
main.cpp

The! означает, что компилятор смог использовать предварительно скомпилированный заголовок. Х означает, что он не смог его использовать. Использование соответствующих флагов компилятора имеет решающее значение. Я снял -H и провел некоторые тесты скорости. Прекомпилированный заголовок имел улучшение с 14 секунд до 11 секунд. Неплохо, но не очень.

Примечание: здесь ссылка на пример: http://www.boost.org/doc/libs/1_43_0/doc/html/xpressive/user_s_guide.html#boost_xpressive.user_s_guide.examples Я не мог заставить его работать в сообщении.

BTW: Я использую следующий g++

g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

Ответ 2

Во-первых, см. документацию здесь.

Вы компилируете заголовки, как и любой другой файл, но вы помещаете вывод в файл с суффиксом .gch.

Так, например, если вы прекомпилируете stdafx.h, у вас будет предварительно скомпилированный заголовок, который будет автоматически искать вызванный stdafx.h.gch в любое время, когда вы включаете stdafx.h

Пример:

stdafx.h:

#include <string>
#include <stdio.h>

a.cpp:

#include "stdafx.h"
int main(int argc, char**argv)
{
  std::string s = "Hi";
  return 0;
}

Затем скомпилируйте как:

> g++ -c stdafx.h -o stdafx.h.gch
> g++ a.cpp
> ./a.out

Ваша компиляция будет работать, даже если вы удалите stdafx.h после шага 1.

Ответ 3

Спецификатор -x для предварительно скомпилированных заголовков C++ - это -x c++-header, а не -x c++. Пример использования PCH приведен ниже.

pch.h:

// Put your common include files here: Boost, STL as well as your project headers.

main.cpp:

#include "pch.h"
// Use the PCH here.

Создайте PCH так:

$ g++ -x c++-header -o pch.h.gch -c pch.h

pch.h.gch должен находиться в том же каталоге, что и pch.h, чтобы его можно было использовать, поэтому убедитесь, что вы выполнили приведенную выше команду из каталога, где находится pch.h.

Ответ 4

Мне удалось получить предварительно скомпилированные заголовки, работающие под управлением gcc один раз в прошлом, и я также помню, что у меня были проблемы. Следует помнить, что gcc будет игнорировать файл (header.h.gch или аналогичный), если определенные условия не выполняются, список которых можно найти на страница документации gcc precompiled.

Как правило, безопаснее всего, чтобы ваша система сборки скомпилировала файл .gch в качестве первого шага, с теми же параметрами командной строки и исполняемыми файлами, что и остальная часть вашего источника. Это гарантирует, что файл обновлен и что нет никаких тонких различий.

Вероятно, также неплохо заставить его работать с надуманным примером во-первых, просто чтобы исключить, что ваши проблемы специфичны для исходного кода в вашем проекте.

Ответ 5

Вызовите gcc так же, как вы называете его для исходного файла, но с файлом заголовка.

например,

g++ $(CPPFLAGS) test.h

это создает файл с именем test.h.gch

Каждый раз, когда gcc ищет файл test.h, он сначала ищет файл test.h.gch и, если он находит его, он использует его автоматически.

Дополнительную информацию можно найти в разделе предварительно скомпилированных заголовков GCC.