GCC로 미리 컴파일 된 헤더


91

누구든지 GCC로 작업하는 미리 컴파일 된 헤더를 얻는 데 성공 했습니까? 나는 내 시도에 운이 없었고 그것을 설정하는 방법에 대한 많은 좋은 예를 보지 못했습니다. cygwin gcc 3.4.4에서 시도하고 Ubuntu에서 4.0을 사용했습니다.


나는 그것을 시도했고 내 C 소스는 컴파일러가 생성하고 사용자가 작성하지 않았기 때문에 미리 컴파일 된 헤더에 대한 최적의 사용 사례를 가졌습니다. Sun Studio, 특히 Visual Studio는 빌드 시간을 크게 향상 시켰습니다. gcc에서는 미리 컴파일 된 헤더 없이는 더욱 악화되었습니다. 이것은 3.4에서 4.x로 테스트하지는 않았지만 속도와 gcc는 상호 배타적입니다.
Lothar

@Lothar 코드는 무엇입니까? 템플릿이 많은 코드에서 g ++는 최근 Visual Studio 컴파일러보다 약 10 배 빠릅니다.
돼지는 2014 년

내 C ++ 코드에서 템플릿을 사용하지 않습니다. C + 예외 처리 + 멋진 C ++ 확장입니다. 이 질문이 있은 지 6 년이 지난 지금도 VS2010은 훨씬 더 빠릅니다. 하지만 그동안 16 개의 코어가있어서 함께 살 수 있습니다.
Lothar 2014

답변:


58

나는 확실히 성공했습니다. 먼저 다음 코드를 사용했습니다.


#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의 안녕하세요 세계였습니다 (링크는 아래 참조). 먼저 -Hgcc 의 옵션으로 컴파일했습니다 . 그것은 그것이 사용한 엄청난 헤더 목록을 보여주었습니다. 그런 다음 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 ++-벽 -f 예외 -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

! 컴파일러가 미리 컴파일 된 헤더를 사용할 수 있음을 의미합니다. x는 사용할 수 없음을 의미합니다. 적절한 컴파일러 플래그를 사용하는 것이 중요합니다. -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


20
-Winvalid-pch를 추가하면 PCH 사용에 문제가있는 경우 디버깅하는 데 도움이됩니다.
lefticus

"나쁘지는 않지만 훌륭하지 않은"미리 컴파일 된 헤더는 서로 다시 연결되는 많은 헤더가있을 때 유용하므로 큰 라이브러리 나 많은 라이브러리를 사용하는 매우 큰 프로젝트에서 컴파일 시간을 줄일 수 있습니다.
jokoon

4
"나쁘지는 않지만 훌륭하지는 않음": gcc 4.4.7 사용, 136 .cpp 파일 35.5 Mb 총 크기, 148 .h 파일 5.5 Mb 총 크기, .gch 파일은 48 Mb, 디버그 빌드에 2'20 소요 "(vs 2 '14 "non-pch), -O2 최적화 빌드는 4'30"소요 (vs 5'33 "non-pch) 효과는 디버그 빌드 근처에서 예상되지만 사전 컴파일로 이익을 얻는 최적화 된 빌드 일뿐입니다 .... 이유가 확실하지 않습니다. 사전 컴파일은 Windows에서 훨씬 더 극적입니다!
Andreas Vergison 2014

1
(계속) 해당 pch / non-pch 출력 파일은 정확히 동일한 크기의 바이트 크기를 가지고 있습니다. 위의 타이밍은 빌드를 반복 할 때 달라지는 것 같습니다. 예를 들어 -O2 non-pch는 3'45 "에서 5'33"사이에 차이가 있으므로 VMware에서 실행하기 때문에 정확한 과학이 아닙니다. 어쨌든 gcc pch는 제 경우에는 전혀 유익하지 않습니다. Windows VS2012 (x64, 단일 스레드 컴파일)의 동일한 코드 기반과 비교합니다. debug 46 "pch, 2'50"non-pch, release 2'13 "pch, 5'02"non-pch. 그리고 물론 심지어 훨씬 더 빨리 ... 멀티 프로세서를 사용할 때의
안드레아스 Vergison을

@AndreasVergison- -Winvalid-pch미리 컴파일 된 헤더가 제대로 사용되고 있는지 확인하기 위해를 사용해 보셨습니까 ? 우리는 디버그 빌드에 pch를 사용하여 큰 개선을 보았습니다. 그래서 설정에 문제가 있는지 궁금합니다.
Josh Kelley 2014 년

52

먼저 여기에서 문서를 참조하십시오 .

다른 파일과 마찬가지로 헤더를 컴파일하지만 접미사가 .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

1 단계 후에 stdafx.h를 제거해도 컴파일이 작동합니다.


8

-xC ++에 대한 지정 헤더가 미리 컴파일 -x c++-header하지 -x c++. PCH 사용 예는 다음과 같습니다.

pch.h:

// Put your common include files here: Boost, STL as well as your project's 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.


3
이것은해야 -c pch.h하지 -c pch.cpp?
MM

7

나는 과거에 한 번 gcc에서 작동하는 미리 컴파일 된 헤더를 얻을 수 있었고 그때도 문제가 있었던 것을 기억합니다. 기억해야 할 점은 특정 조건이 충족되지 않으면 gcc가 파일 (header.h.gch 또는 이와 유사한)을 무시한다는 것입니다.이 목록은 gcc 사전 컴파일 된 헤더 문서 페이지 에서 찾을 수 있습니다 .

일반적으로 빌드 시스템에서 나머지 소스와 동일한 명령 줄 옵션 및 실행 파일을 사용하여 .gch 파일을 첫 번째 단계로 컴파일하는 것이 가장 안전합니다. 이렇게하면 파일이 최신 상태이며 미묘한 차이가 없습니다.

문제가 프로젝트의 소스 코드와 관련 될 가능성을 제거하기 위해 먼저 인위적인 예제로 작업하는 것도 좋은 생각입니다.


7

소스 파일에 대해 호출하는 것과 동일한 방식으로 헤더 파일을 사용하여 gcc를 호출하십시오.

예 :

g++ $(CPPFLAGS) test.h

그러면 test.h.gch라는 파일이 생성됩니다.

gcc가 test.h를 검색 할 때마다 먼저 test.h.gch를 찾고 발견하면 자동으로 사용합니다.

자세한 정보는 GCC 사전 컴파일 된 헤더 에서 찾을 수 있습니다.


gcc 3.4를 사용하고 있으며 g ++ stdafx.h 줄이 컴파일되지 않고 "g ++ : 컴파일 요청 된 헤더 파일"오류가 발생하지만 이것이 내가 원하는 것인지 확실하지 않은 경우 컴파일됩니다. "g ++ -c -x c ++ stdafx.h -o stdafx.h.pch "
stefanB

1

확인하십시오 -include your_header.h

이것이 내가 bits/stdc++.h컬렉션을 미리 컴파일하고 사용하는 방법 입니다.

암호

#include <bits/stdc++.h>

그런 다음 -H로 내 파일을 컴파일하고 출력을 확인하여 lib를 찾았습니다.

g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable

내가 본 곳

. /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h

그래서 나는 bits현재 디렉토리 안에 새 디렉토리를 만들고 stdc++.h거기에서 복사 했습니다.

그리고 나는 달렸다

g++ bits/stdc++.h -O3 -std=c++14  -pthread

생성 한 bits/stdc++.gch

일반적으로 다음을 통해 코드를 컴파일했습니다.

g++ sol.cpp -O3 -pthread -lm -std=c++14 -o executable

,하지만 수정해야했습니다.

g++ sol.cpp -include bits/stdc++.h -O3 -pthread -lm -std=c++14 -o executable

그것은 단지에 해결로 .gch대신 파일 .h-include bits/stdc++.h 그 날의 핵심이었다. 명심해야 할 다른 것은 당신이 컴파일해야한다는 것입니다 *.h당신이 당신의 컴파일과 거의 동일한 매개 변수와 헤더 파일을 *.cpp. 내가 포함하지 않았 -O3거나 미리 컴파일 된 헤더를 -pthread무시 했을 때 *.gch.

모든 것이 올바른지 확인하려면 비교 결과를 통해 시차를 측정 할 수 있습니다.

time g++ sol.cpp ...

또는 실행

g++ sol.cpp -H -O3 -pthread -lm -std=c++14 -o executable

다시 헤더 경로를 찾고 !라이브러리 경로 이전에 예를 들어

! ./bits/stdc++.h.gch
....
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.