Tek dosyalar için derleme bayraklarını geçersiz kıl


110

Bir projeyi derlemek için genel bir bayrak kümesi kullanmak istiyorum, yani üst düzey CMakeLists.txt dosyamda şunu belirtmiştim:

ADD_DEFINITIONS ( -Wall -Weffc++ -pedantic -std=c++0x )

Bununla birlikte, bir alt dizindeki belirli bir dosya için ("foo.cpp" diyelim), derleme bayraklarını -Weffc ++ (ticari kitaplık dahil, değiştiremem) olarak değiştirmek istiyorum. Durumu basitleştirmek için yalnızca -Wall'u kullanmayı denedim:

 SET_SOURCE_FILES_PROPERTIES( foo.cpp PROPERTIES COMPILE_FLAGS -Wall )
 ADD_EXECUTABLE( foo foo.cpp )

işe yaramadı. Ben de denedim

SET_PROPERTY( SOURCE foo.cpp PROPERTY COMPILE_FLAGS -Wall )
ADD_EXECUTABLE( foo foo.cpp )

ve

ADD_EXECUTABLE( foo foo.cpp )
SET_TARGET_PROPERTIES( foo PROPERTIES COMPILE_FLAGS -Wall )

, hiçbiri işe yaramadı.

Son olarak, şu tanımı kaldırmayı denedim:

REMOVE_DEFINITIONS( -Weffc++ )
ADD_EXECUTABLE( foo foo.cpp )
ADD_DEFINITIONS( -Weffc++ )

, ki bu da işe yaramadı (yani, ticari kütüphane hakkında birçok stil uyarısı alıyorum). (** Not: Yürütülebilir dosya oluşturulduktan sonra -Weffc ++ yönergesini yeniden İÇERMEZSEM, uyarılar bastırılır.)

Ayrıca derleme bayraklarını geçici olarak kaldırmayı denedim: http://www.cmake.org/pipermail/cmake/2007-June/014614.html , ancak bu yardımcı olmadı.

Bunun zarif bir çözümü yok mu?


1
Bekle, son denemeniz işe yararsa, ancak yalnızca oluşturulduktan sonra, bu bir önbelleğe alma sorunu olmayabilir mi? Değişikliklerinizi yaptıktan sonra CMakeCache'yi silmeyi deneyin.
Cameron

İlgili, CMake'de tek bir yürütülebilir dosya için bir derleyici bayrağı nasıl değiştirilir? Andre'nin cevabı, mevcut seçenekleri yeni seçeneklerle değiştirmenin bir yolu gibi görünen şeyi gösteriyor.
jww

Yanıtlar:


126

Yukarıdaki girişimleriniz, beklediğiniz gibi üzerine yazmak yerine dosyanıza / hedefinize daha fazla bayrak ekliyor. Örneğin, Kaynak Dosyalardaki Mülkler - COMPILE_FLAGS dokümanlarından :

Bu bayraklar, bu kaynak dosya oluşturulduğunda derleme bayrakları listesine eklenecektir.

Bunu -Weffc++yaparak foo.cpp bayrağına karşı koyabilmelisiniz

set_source_files_properties(foo.cpp PROPERTIES COMPILE_FLAGS -Wno-effc++)

Bu , derleyici komutunda -Wno-effc++sonrasını ekleme etkisine sahip olmalıdır -Weffc++ve ikinci ayar kazanır. Tam komutu görmek ve durumun gerçekten böyle olup olmadığını kontrol etmek için şunları yapabilirsiniz:

make VERBOSE=1

Bir kenara, GNU C ++ Standart Kitaplığı'nın geliştiricilerinden -Weffc++biri bu cevapta oldukça olumsuz bir görüş sunuyor .

Bir başka nokta da, bunu add_definitionsamaçlanan önişlemci tanımları yerine derleyici bayrakları için kullandığınız anlamında kötüye kullandığınızdır .

Kullanılması tercih edilir add_compile_options

add_compile_options(-Wall -Weffc++ -pedantic -std=c++0x)

veya CMake <3.0 sürümleri için daha fazlasını yapmak için:

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Weffc++ -pedantic -std=c++0x")

Aşağıdaki yorumlarda yer alan başka sorulara yanıt olarak, tek bir dosyadaki bir bayrağı güvenilir bir şekilde kaldırmanın imkansız olduğuna inanıyorum . Nedeni herhangi bir kaynak dosyası için, bu olmasıdır COMPILE_OPTIONSve 1 hedefinin uygulanan, ancak bu o kaynak dosyasının özelliklerinde herhangi görünmüyor.COMPILE_FLAGS

Sorun bayrağını hedeften çıkarabilir COMPILE_OPTIONS, ardından bunu hedefin kaynaklarının her birine ayrı ayrı uygulayabilir ve gerektiğinde belirli kaynak dosyadan çıkarabilirsiniz.

Bununla birlikte, bu birçok senaryoda işe yarayabilirken, birkaç sorunu vardır.

İlk - kaynak dosyalarının özellikleriCOMPILE_OPTIONS yalnızca içermez COMPILE_FLAGS. Bu bir sorundur çünkü COMPILE_OPTIONSbir hedefin oluşturucu ifadeleri olabilir , ancak COMPILE_FLAGSbunları desteklemez. Bu nedenle, bayrağınızı ararken üretici ifadelerine yer vermeniz gerekir ve hatta belki de bayrağınız bir veya daha fazlasında yer alıyorsa, kalan kısma yeniden uygulanıp uygulanmayacağını görmek için oluşturucu ifadelerini "ayrıştırmanız" gerekebilir. kaynak dosyaları.

İkinci olarak - CMake v3.0'dan beri hedefler belirleyebilir INTERFACE_COMPILE_OPTIONS. Bu, hedefinizin bağımlılığının, hedeflerinize COMPILE_OPTIONSonun aracılığıyla ekleyebileceği veya geçersiz kılabileceği anlamına gelir INTERFACE_COMPILE_OPTIONS. Bu nedenle LINK_LIBRARIES, sorun bayrağını uygulayanları bulmak için hedefinizin tüm bağımlılıklarını yinelemeli olarak yinelemeniz gerekir (hedefin listesi aynı zamanda üreteç ifadeleri de içerebilir, çünkü özellikle kolay bir görev değildir ) ve bunu bunlardan kaldırmaya çalışın. hedefler INTERFACE_COMPILE_OPTIONSde.

Karmaşıklığın bu aşamasında, belirli bir bayrağı bir kaynak dosyadan koşulsuz olarak kaldırma işlevselliğini sağlamak için CMake'ye bir yama göndermek istiyorum.


1: COMPILE_FLAGSKaynak dosyalardaki özelliğin aksine, COMPILE_FLAGShedeflerdeki özelliğin kullanımdan kaldırıldığını unutmayın.


6
Ancak dosyalar için derleme bayraklarını eklemeden ayrı ayrı nasıl ayarlarsınız? Örneğin, sonuçta elde edilen hedef için dosyalardan farklı derleme bayrakları kullanmak istiyorum, ancak bunlar eklendiğinden bunları manuel olarak kaldırmam gerekir. Eklenmeyen ancak gerçekte onları yalnızca belirtilen dosya / hedef için ayarlayan bir özellik yok mu?
Baradé

2
-Fno-flag mevcut olmadığında (ve -fflag ayarlandığında) ne yapabiliriz?
gnzlbg

@ Baradé Yapamazsınız - bir kaynak dosyası için değil.
Fraser

@gnzlbg Yine, oldukça sıkışıp kaldık. Cevabımı biraz daha fazla bilgi verecek şekilde güncelledim (ve muhtemelen bazı senaryolarda işe yarayacak olası bir geçici çözüm ).
Fraser

Tek dosya derleme seçenekleri ayarının gerçekten bir çözümü yok mu? Gcov'un çökmesine neden olan bazı dosyalar için gcc kapsam oluşturmayı devre dışı bırakmam gerekiyor.
Lothar

5

@ Fraser'ın doğru cevabına ekliyoruz.

Özel bayrağı belirli klasörlere eklemek isterseniz şunları yapabilirsiniz:

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_property(SOURCE ${SPECIAL_SRC_FILES} PROPERTY COMPILE_FLAGS -Wno-effc++)

veya

file(GLOB SPECIAL_SRC_FILES
        "path/one/src/*.cpp"
        "path/two/src/*.cpp")
set_source_files_properties(${SPECIAL_SRC_FILES} PROPERTIES COMPILE_FLAGS -Wno-effc++)

Burada tartışıldığı gibi GLOB'un kullanılması tavsiye edilmediğini unutmayın.


0

@Fraser yanıtını kullanarak, değişken noktalı virgülle ayrılmış birden çok yol içerdiğinden, Qt kapsamını işlemek için aşağıdakileri oluşturdum. Bu, önce bir foreach()döngü eklemem ve dahil etme bayraklarını elle oluşturmam gerektiği anlamına geliyor . Ama bu benim bir istisnaya sahip olmama izin veriyor: foo.cpp (bir dosya şimdilik Qt kullanıyor ancak uzun vadede bu bağımlılığı kaldırmak istiyorum ve Qt'nin başka hiçbir yerde sürünmediğinden emin olmak istiyorum).

find_package(Qt5Core REQUIRED)
set(QT_INCLUDE_PROPERTIES "")
foreach(DIR ${Qt5Core_INCLUDE_DIRS})
    set(QT_INCLUDE_PROPERTIES "${QT_INCLUDE_PROPERTIES} -isystem ${DIR}")
endforeach()
set_source_files_properties(foo.cpp PROPERTIES
    COMPILE_FLAGS
        ${QT_INCLUDE_PROPERTIES}
)

Ayrıca Qt başlıklarının başka türlü oluşturduğu bazı uyarılardan kaçınmak için -isystemyerine ' -Iyi kullandığıma da dikkat edin (açık bir ton uyarı var).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.