มีใครประสบความสำเร็จบ้างในการรับส่วนหัวที่คอมไพล์ไว้ล่วงหน้าที่ทำงานกับ GCC บ้าง? ฉันไม่มีโชคในความพยายามของฉันและฉันยังไม่เห็นตัวอย่างที่ดีมากมายสำหรับวิธีการตั้งค่า ฉันได้ลองใช้ cygwin gcc 3.4.4 และใช้ 4.0 บน Ubuntu
มีใครประสบความสำเร็จบ้างในการรับส่วนหัวที่คอมไพล์ไว้ล่วงหน้าที่ทำงานกับ GCC บ้าง? ฉันไม่มีโชคในความพยายามของฉันและฉันยังไม่เห็นตัวอย่างที่ดีมากมายสำหรับวิธีการตั้งค่า ฉันได้ลองใช้ cygwin gcc 3.4.4 และใช้ 4.0 บน Ubuntu
คำตอบ:
ฉันประสบความสำเร็จอย่างแน่นอน ก่อนอื่นฉันใช้รหัสต่อไปนี้:
#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 ของฉัน (รหัส :: บล็อก) กำลังสร้างและเห็นสิ่งนี้:
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
เดอะ! หมายความว่าคอมไพเลอร์สามารถใช้ส่วนหัวที่คอมไพล์ไว้ล่วงหน้าได้ 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
-Winvalid-pch
เพื่อให้แน่ใจว่าส่วนหัวที่คอมไพล์ไว้ล่วงหน้าถูกใช้อย่างถูกต้องหรือไม่? เราสังเกตเห็นการปรับปรุงครั้งใหญ่โดยใช้ pch สำหรับรุ่น debug ของเราดังนั้นฉันจึงสงสัยว่ามีปัญหากับการตั้งค่าของคุณหรือไม่
คุณรวบรวมส่วนหัวเช่นเดียวกับไฟล์อื่น ๆ แต่คุณใส่ผลลัพธ์ไว้ในไฟล์ที่มีส่วนต่อท้ายเป็น.gch
.
ตัวอย่างเช่นหากคุณคอมไพล์ stdafx.h ล่วงหน้าคุณจะมีส่วนหัวที่คอมไพล์ไว้ล่วงหน้าซึ่งจะถูกค้นหาโดยอัตโนมัติstdafx.h.gch
เมื่อใดก็ตามที่คุณรวมstdafx.h
ตัวอย่าง:
stdafx.h:
#include <string>
#include <stdio.h>
ก. 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
-x
ระบุสำหรับ C ++ precompiled ส่วนหัวเป็นไม่ได้-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
เป็น
-c pch.h
ไม่ใช่-c pch.cpp
เหรอ?
ฉันได้จัดการเพื่อรับส่วนหัวที่คอมไพล์ไว้แล้วซึ่งทำงานภายใต้ gcc ครั้งหนึ่งในอดีตและฉันจำได้ว่ามีปัญหาเช่นกัน สิ่งที่ต้องจำไว้คือ GCC จะไม่สนใจแฟ้ม (header.h.gch หรือคล้ายกัน) ถ้าเงื่อนไขบางอย่างจะไม่พบรายการที่สามารถพบได้ในGCC precompiled หน้าเอกสารของส่วนหัว
โดยทั่วไปจะปลอดภัยที่สุดที่จะให้ระบบบิวด์ของคุณคอมไพล์ไฟล์. gch เป็นขั้นตอนแรกโดยมีตัวเลือกบรรทัดคำสั่งเดียวกันและสามารถเรียกใช้งานได้เหมือนกับแหล่งที่มาของคุณ เพื่อให้แน่ใจว่าไฟล์เป็นข้อมูลล่าสุดและไม่มีความแตกต่างเล็กน้อย
อาจเป็นความคิดที่ดีที่จะทำให้มันใช้งานได้กับตัวอย่างที่สร้างไว้ก่อนเพื่อลบความเป็นไปได้ที่ปัญหาของคุณจะเกิดขึ้นเฉพาะกับซอร์สโค้ดในโครงการของคุณ
เรียก gcc แบบเดียวกับที่คุณเรียกสำหรับไฟล์ต้นฉบับ แต่ใช้ไฟล์ส่วนหัว
เช่น
g++ $(CPPFLAGS) test.h
สิ่งนี้จะสร้างไฟล์ชื่อ test.h.gch
ทุกครั้งที่ gcc ค้นหา test ต้องมองหา test.h.gch ก่อนและหากพบว่าจะใช้โดยอัตโนมัติ
ดูข้อมูลเพิ่มเติมได้ในส่วนหัวที่คอมไพล์ของ GCC
ตรวจสอบให้แน่ใจว่า -include your_header.h
นี่คือวิธีที่ฉันbits/stdc++.h
รวบรวมและใช้คอลเลคชันล่วงหน้า
รหัส
#include <bits/stdc++.h>
จากนั้นฉันก็หา lib โดยการคอมไพล์ไฟล์ด้วย -H และดูที่เอาต์พุต
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
....