Saya ingin menggunakan serangkaian tanda global untuk menyusun proyek, yang berarti bahwa pada file CMakeLists.txt tingkat atas saya, saya telah menentukan:
ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )
Namun, untuk file tertentu (katakanlah "foo.cpp") di subdirektori, saya ingin mengganti flag kompilasi untuk tidak menerapkan -Weffc ++ (termasuk pustaka komersial yang tidak dapat saya ubah). Untuk menyederhanakan situasi agar hanya menggunakan -Wall, saya mencoba:
SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
, yang tidak berhasil. Saya juga mencoba
SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )
dan
ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )
, yang tidak berhasil.
Akhirnya, saya mencoba menghapus definisi ini:
REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )
, yang juga tidak berfungsi (artinya, saya mendapat banyak peringatan gaya tentang pustaka komersial). (** Catatan: Peringatan akan disembunyikan jika saya TIDAK menyertakan kembali direktif -Weffc ++ setelah executable dibuat.)
Saya juga mencoba menghapus sementara bendera kompilasi: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , tetapi itu tidak membantu.
Apakah tidak ada solusi elegan untuk ini?
sumber
Jawaban:
Upaya Anda di atas menambahkan flag lebih lanjut ke file / target Anda daripada menimpa seperti yang Anda harapkan. Misalnya, dari dokumen untuk Properti di File Sumber - COMPILE_FLAGS :
Anda harus dapat
-Weffc++
mengimbangi flag untuk foo.cpp dengan melakukanIni seharusnya memiliki efek menambahkan
-Wno-effc++
setelah-Weffc++
dalam perintah kompilator, dan pengaturan terakhir menang. Untuk melihat perintah lengkap dan memeriksa apakah memang demikian, Anda dapat melakukannyaSelain itu, salah satu pengelola Perpustakaan Standar GNU C ++ memberikan pendapat yang cukup negatif
-Weffc++
dalam jawaban ini .Poin lainnya adalah Anda menyalahgunakan
add_definitions
dalam artian Anda menggunakan ini untuk flag compiler daripada definisi preprocessor yang dimaksudkan.Akan lebih baik jika digunakan
add_compile_options
atau untuk CMake versi <3.0 untuk melakukan sesuatu yang lebih seperti:
Menanggapi pertanyaan lebih lanjut di komentar di bawah, saya yakin tidak mungkin untuk menghapus bendera dengan andal pada satu file. Alasannya adalah karena untuk file sumber tertentu, ia memiliki target
COMPILE_OPTIONS
dan 1 yang diterapkan, tetapi ini tidak muncul di properti mana pun untuk file sumber tersebut.COMPILE_FLAGS
Anda dapat melihat
COMPILE_OPTIONS
menghapus tanda masalah dari target , lalu menerapkannya ke setiap sumber target secara individual, menghilangkannya dari file sumber spesifik sesuai kebutuhan.Namun, meskipun ini bisa berhasil di banyak skenario, ini memiliki beberapa masalah.
Properti file sumber pertama tidak termasuk
COMPILE_OPTIONS
, hanyaCOMPILE_FLAGS
. Ini menjadi masalah karenaCOMPILE_OPTIONS
target dapat menyertakan ekspresi generator , tetapiCOMPILE_FLAGS
tidak mendukungnya. Jadi, Anda harus mengakomodasi ekspresi generator saat mencari flag Anda, dan bahkan Anda mungkin harus "mengurai" ekspresi generator jika flag Anda ada di satu atau lebih untuk melihat apakah harus diterapkan kembali ke yang tersisa file sumber.Kedua - sejak CMake v3.0, target dapat ditentukan
INTERFACE_COMPILE_OPTIONS
. Ini berarti bahwa ketergantungan target Anda dapat menambah atau mengganti target AndaCOMPILE_OPTIONS
melalui ituINTERFACE_COMPILE_OPTIONS
. Jadi Anda selanjutnya harus mengulang secara rekursif melalui semua dependensi target Anda (bukan tugas yang sangat mudah karena daftarLINK_LIBRARIES
untuk target juga dapat berisi ekspresi generator) untuk menemukan yang menerapkan flag masalah, dan mencoba dan menghapusnya dari itu. target 'INTERFACE_COMPILE_OPTIONS
juga.Pada tahap kompleksitas ini, saya akan mencari untuk mengirimkan tambalan ke CMake untuk menyediakan fungsionalitas untuk menghapus bendera tertentu tanpa syarat dari file sumber.
1: Perhatikan bahwa tidak seperti
COMPILE_FLAGS
properti pada file sumber,COMPILE_FLAGS
properti pada target tidak digunakan lagi.sumber
Hanya menambahkan jawaban benar @ Fraser.
Jika Anda ingin menambahkan bendera khusus ke folder tertentu, Anda dapat melakukan:
atau
Perhatikan bahwa tidak disarankan menggunakan GLOB seperti yang dibahas di sini
sumber
Menggunakan jawaban @Fraser, saya membuat yang berikut ini untuk menangani termasuk Qt karena variabel mencakup beberapa jalur yang dipisahkan oleh titik koma. Ini berarti saya harus terlebih dahulu menambahkan
foreach()
loop dan membuat flag include dengan tangan . Tetapi itu memungkinkan saya memiliki satu pengecualian: foo.cpp (satu file itu menggunakan Qt untuk saat ini tetapi untuk jangka panjang saya ingin menghapus ketergantungan itu dan saya ingin memastikan Qt tidak merayap di tempat lain).Perhatikan juga bahwa saya menggunakan
-isystem
alih - alih-I
untuk menghindari beberapa peringatan yang dihasilkan oleh header Qt (Saya memiliki banyak peringatan yang dihidupkan).sumber