Saya telah melihat beberapa posting (lama) di 'net tentang meretas bersama beberapa dukungan untuk header yang telah dikompilasi sebelumnya di CMake. Mereka semua tampak agak di mana-mana dan setiap orang memiliki cara mereka sendiri untuk melakukannya. Apa cara terbaik untuk melakukannya saat ini?
c++
visual-studio
gcc
cmake
precompiled-headers
Lengket
sumber
sumber
Saya menggunakan makro berikut untuk menghasilkan dan menggunakan header yang telah dikompilasi sebelumnya:
Katakanlah Anda memiliki variabel $ {MySources} dengan semua file sumber Anda, kode yang ingin Anda gunakan hanyalah
Kode tersebut masih akan berfungsi dengan baik pada platform non-MSVC juga. Cukup rapi :)
sumber
list( APPEND ... )
luar penutupanendif()
. Lihat kode lengkap di sini: pastebin.com/84dm5rXZ/Yu
dan/FI
, mereka harus${PrecompiledHeader}
dan tidak${PrecompiledBinary}
./YuC:/foo/bar.h
akan memaksa Anda untuk mengoper/FpC:/foo/bar.h
bendera atau meletakkan#include <C:/foo/bar.h>
di bagian atas semua file .cpp Anda sebagai pernyataan include pertama. MSVC melakukan perbandingan string dari#include
argumen, tidak memeriksa apakah itu menunjuk ke file yang sama seperti yang diberikan/Yu
. Ergo,#include <bar.h>
tidak akan berfungsi dan mengeluarkan error C2857.CMake baru saja mendapatkan dukungan untuk PCH, itu akan tersedia dalam rilis 3.16 mendatang, karena 2019-10-01:
https://gitlab.kitware.com/cmake/cmake/merge_requests/3553
Ada diskusi yang sedang berlangsung untuk mendukung berbagi PCH antar target: https://gitlab.kitware.com/cmake/cmake/issues/19659
Ada beberapa konteks tambahan (motivasi, angka) yang tersedia di https://blog.qt.io/blog/2019/08/01/precompiled-headers-and-unity-jumbo-builds-in-upcoming-cmake/
sumber
Berikut adalah potongan kode untuk memungkinkan Anda menggunakan header yang telah dikompilasi untuk proyek Anda. Tambahkan berikut ini ke CMakeLists.txt Anda yang menggantikan
myprecompiledheaders
dan yangmyproject_SOURCE_FILES
sesuai:sumber
with set( CMAKE_AUTOMOC ON )
.myprecompiledheader.cpp
dikompilasi terlebih dahulu? Dari cuplikan ini, sepertinya cuplikan tersebut akan dikompilasi terakhir kali, jadi mungkin itulah yang mungkin menyebabkan keterlambatan.myprecompiledheader.h
hanya berisi header STL paling umum yang digunakan kode saya.Saya akhirnya menggunakan versi makro larsm yang diadaptasi. Menggunakan $ (IntDir) untuk jalur pch membuat header yang telah dikompilasi untuk debug dan rilis rilis tetap terpisah.
sumber
Diadaptasi dari Dave, tetapi lebih efisien (menetapkan properti target, bukan untuk setiap file):
sumber
abc
contoh Anda?jika Anda tidak ingin menemukan kembali roda, cukup gunakan Cotire sebagai jawaban atas menyarankan atau yang lebih sederhana - cmake-precompiled-header di sini . Untuk menggunakannya cukup sertakan modul dan panggil:
sumber
CMake 3.16 memperkenalkan dukungan untuk header yang telah dikompilasi sebelumnya. Ada perintah CMake baru
target_precompile_headers
yang melakukan semua yang Anda butuhkan di bawah tenda. Lihat dokumentasinya untuk detail lebih lanjut: https://cmake.org/cmake/help/latest/command/target_precompile_headers.htmlsumber
Contoh penggunaan header dikompilasi dengan cmake dan Visual Studio 2015
"stdafx.h", "stdafx.cpp" - nama header yang telah dikompilasi sebelumnya.
Letakkan yang berikut di bawah ini di file root cmake.
Letakkan yang berikut di bawah ini di file cmake proyek.
"src" - folder dengan file sumber.
sumber
IMHO cara terbaik adalah mengatur PCH untuk keseluruhan proyek, seperti yang disarankan martjno, dikombinasikan dengan kemampuan mengabaikan PCH untuk beberapa sumber jika diperlukan (misalnya sumber yang dihasilkan):
Jadi, jika Anda memiliki beberapa target MY_TARGET, dan daftar sumber yang dihasilkan IGNORE_PCH_SRC_LIST Anda cukup melakukan:
Pendekatan ini diuji dan bekerja dengan sempurna.
sumber
Nah, ketika build membutuhkan waktu 10+ menit pada mesin quad core setiap kali Anda mengubah satu baris di salah satu file proyek, ia memberi tahu Anda waktunya untuk menambahkan header yang telah dikompilasi untuk windows. Di * nux saya hanya akan menggunakan ccache dan tidak khawatir tentang itu.
Saya telah menerapkannya di aplikasi utama saya dan beberapa pustaka yang digunakannya. Ini bekerja dengan baik untuk saat ini. Satu hal yang juga diperlukan adalah Anda harus membuat file sumber dan header pch dan di file sumber menyertakan semua header yang ingin Anda prakompilasi. Saya melakukan ini selama 12 tahun dengan MFC tetapi butuh beberapa menit untuk mengingatnya ..
sumber
Cara terbersih adalah dengan menambahkan opsi prakompilasi sebagai opsi global. Dalam file vcxproj ini akan muncul sebagai
<PrecompiledHeader>Use</PrecompiledHeader>
dan tidak melakukan ini untuk setiap file individu.Kemudian Anda perlu menambahkan
Create
opsi ke StdAfx.cpp. Berikut cara saya menggunakannya:Ini diuji dan berfungsi untuk MSVC 2010 dan akan membuat file MyDll.pch, saya tidak peduli nama file apa yang digunakan jadi saya tidak berusaha untuk menentukannya.
sumber
Karena opsi header yang telah dikompilasi tidak berfungsi untuk file rc, saya perlu menyesuaikan makro yang disediakan oleh jari.
Sunting: Penggunaan tajuk yang telah dikompilasi ini mengurangi waktu pembuatan Keseluruhan Proyek utama saya dari 4 menit 30-an menjadi 1 menit 40-an. Bagi saya ini hal yang sangat bagus. Dalam header precompile hanya ada header seperti boost / stl / Windows / mfc.
sumber
Jangan pergi kesana. Header yang telah dikompilasi berarti bahwa setiap kali salah satu header berubah, Anda harus membangun kembali semuanya . Anda beruntung jika memiliki sistem build yang menyadari hal ini. Lebih sering daripada tidak sama sekali, build Anda hanya akan gagal sampai Anda menyadari bahwa Anda mengubah sesuatu yang sedang dikompilasi sebelumnya, dan oleh karena itu Anda perlu melakukan pembangunan kembali sepenuhnya. Anda dapat menghindari hal ini sebagian besar dengan mengkompilasi header yang Anda benar-benar positif tidak akan berubah, tetapi kemudian Anda juga melepaskan sebagian besar dari penambahan kecepatan.
Masalah lainnya adalah ruang nama Anda tercemar dengan semua jenis simbol yang tidak Anda ketahui atau pedulikan di banyak tempat di mana Anda akan menggunakan header yang telah dikompilasi sebelumnya.
sumber