Widziałem kilka (starych) postów w sieci na temat zhakowania wsparcia dla wstępnie skompilowanych nagłówków w CMake. Wszyscy wydają się być trochę wszędzie i każdy ma na to swój własny sposób. Jak najlepiej to zrobić obecnie?
c++
visual-studio
gcc
cmake
precompiled-headers
Kleisty
źródło
źródło
Używam następującego makra do generowania i używania prekompilowanych nagłówków:
Powiedzmy, że masz zmienną $ {Moje źródła} ze wszystkimi plikami źródłowymi, kod, którego chciałbyś użyć, wyglądałby po prostu
Kod nadal działałby dobrze na platformach innych niż MSVC. Całkiem schludnie :)
źródło
list( APPEND ... )
zewnątrz zamknięcieendif()
. Zobacz pełny kod tutaj: pastebin.com/84dm5rXZ/Yu
i/FI
, powinny być,${PrecompiledHeader}
a nie${PrecompiledBinary}
./YuC:/foo/bar.h
cię do przekazania/FpC:/foo/bar.h
flagi lub umieszczenia#include <C:/foo/bar.h>
na górze wszystkich twoich plików .cpp jako pierwsza instrukcja dołączania. MSVC porównuje#include
argumenty za pomocą ciągów , nie sprawdza, czy wskazuje na ten sam plik, do którego został podany/Yu
. Ergo,#include <bar.h>
nie zadziała i wyemituje błąd C2857.CMake właśnie zyskał wsparcie dla PCH, powinno być dostępne w nadchodzącej wersji 3.16, która ma się pojawić 01.10.2019:
https://gitlab.kitware.com/cmake/cmake/merge_requests/3553
Trwa dyskusja na temat wspierania udostępniania PCH między celami: https://gitlab.kitware.com/cmake/cmake/issues/19659
Istnieje dodatkowy kontekst (motywacja, liczby) dostępny pod adresem https://blog.qt.io/blog/2019/08/01/precompiled-headers-and-unity-jumbo-builds-in-upcoming-cmake/
źródło
Oto fragment kodu, który umożliwia użycie wstępnie skompilowanego nagłówka w projekcie. Dodaj następujące elementy do zastępowania CMakeLists.txt
myprecompiledheaders
imyproject_SOURCE_FILES
odpowiednio:źródło
with set( CMAKE_AUTOMOC ON )
.myprecompiledheader.cpp
jest skompilowany jako pierwszy? Z tego fragmentu wygląda na to, że zostanie skompilowany jako ostatni, więc może to może być przyczyną opóźnienia.myprecompiledheader.h
zawiera tylko najpopularniejsze nagłówki STL, których używa mój kod.Skończyło się na tym, że użyłem zaadaptowanej wersji makra larsm. Użycie $ (IntDir) dla ścieżki pch powoduje oddzielenie prekompilowanych nagłówków do debugowania i kompilacji wydania.
źródło
Zaadaptowane od Dave, ale bardziej wydajne (ustawia właściwości docelowe, nie dla każdego pliku):
źródło
abc
w twoim przykładzie?jeśli nie chce wyważać otwartych drzwi, wystarczy użyć Cotire jako górna odpowiedź sugeruje lub prostsze - cmake-prekompilowana-header tutaj . Aby z niego skorzystać, wystarczy dołączyć moduł i zadzwonić:
źródło
CMake 3.16 wprowadził obsługę prekompilowanych nagłówków. Jest nowe polecenie CMake,
target_precompile_headers
które robi wszystko, czego potrzebujesz pod maską. Więcej informacji można znaleźć w dokumentacji: https://cmake.org/cmake/help/latest/command/target_precompile_headers.htmlźródło
Przykład użycia prekompilowanego nagłówka z cmake i Visual Studio 2015
„stdafx.h”, „stdafx.cpp” - nazwa prekompilowanego nagłówka.
Umieść poniższy plik w głównym pliku cmake.
Umieść poniższy kod w pliku cmake projektu.
„src” - folder z plikami źródłowymi.
źródło
IMHO najlepszym sposobem jest ustawienie PCH dla całego projektu, jak sugerował martjno, w połączeniu z możliwością ignorowania PCH dla niektórych źródeł w razie potrzeby (np. Wygenerowane źródła):
Tak więc, jeśli masz jakiś cel MY_TARGET i listę wygenerowanych źródeł IGNORE_PCH_SRC_LIST, po prostu zrobisz:
To podejście zostało przetestowane i działa doskonale.
źródło
Cóż, jeśli kompilacje trwają ponad 10 minut na czterordzeniowym komputerze, za każdym razem, gdy zmienisz jedną linię w dowolnym pliku projektu, pojawi się informacja, że należy dodać wstępnie skompilowane nagłówki dla systemu Windows. Na * nux po prostu użyłbym ccache i nie martwiłem się o to.
Zaimplementowałem w swojej głównej aplikacji i kilku bibliotekach, z których ona korzysta. Do tego momentu działa świetnie. Jedną rzeczą, która jest również potrzebna, jest utworzenie źródła pch i pliku nagłówkowego, aw pliku źródłowym uwzględnij wszystkie nagłówki, które chcesz prekompilować. Robiłem to przez 12 lat z MFC, ale zajęło mi kilka minut, aby to sobie przypomnieć.
źródło
Najprostszym sposobem jest dodanie opcji prekompilowanej jako opcji globalnej. W pliku vcxproj pojawi się jako
<PrecompiledHeader>Use</PrecompiledHeader>
i nie będzie tego robić dla każdego pojedynczego pliku.Następnie musisz dodać
Create
opcję do StdAfx.cpp. Oto jak go używam:Jest to testowane i działa dla MSVC 2010 i utworzy plik MyDll.pch, nie przejmuję się nazwą pliku, więc nie starałem się go określić.
źródło
Ponieważ opcja prekompilowanego nagłówka nie działa dla plików rc, musiałem dostosować makro dostarczone przez jari.
Edycja: Użycie tych wstępnie skompilowanych nagłówków skróciło ogólny czas kompilacji mojego głównego projektu z 4 min 30 s do 1 min 40 s. To dla mnie naprawdę dobra rzecz. W nagłówku prekompilacji znajdują się tylko nagłówki, takie jak boost / stl / Windows / mfc.
źródło
Nawet tam nie idź. Wstępnie skompilowane nagłówki oznaczają, że za każdym razem, gdy zmieni się jeden z nagłówków, musisz wszystko odbudować . Masz szczęście, jeśli masz system kompilacji, który to rozumie. Najczęściej kompilacja kończy się niepowodzeniem, dopóki nie zdasz sobie sprawy, że zmieniłeś coś, co jest prekompilowane, i dlatego musisz przeprowadzić pełną przebudowę. Możesz tego uniknąć głównie poprzez prekompilowanie nagłówków, które nie zmienią się, co do której jesteś absolutnie pewny, ale wtedy również rezygnujesz z dużej części przyrostu szybkości.
Innym problemem jest to, że twoja przestrzeń nazw jest zanieczyszczona wszelkiego rodzaju symbolami, których nie znasz lub na których nie zależy ci w wielu miejscach, w których używałbyś prekompilowanych nagłówków.
źródło