CMake dosyasına nasıl bağlayıcı veya derleme bayrağı ekleyebilirim?


220

arm-linux-androideabi-g++Derleyiciyi kullanıyorum . Basit bir "Merhaba Dünya!" program iyi derler. Ben bu kod basit bir istisna işleme ekleyerek test zaman da çalışır (ekledikten sonra -fexceptions.. Sanırım varsayılan olarak devre dışı).

Bu bir Android cihaz için ve sadece CMake kullanmak istiyorum, değil ndk-build.

Örneğin - first.cpp

#include <iostream>

using namespace std;

int main()
{
   try
   {
   }
   catch (...)
   {
   }
   return 0;
}

./arm-linux-androideadi-g++ -o first-test first.cpp -fexceptions

Sorunsuz çalışıyor ...

Sorun ... Bir CMake dosyası ile dosyayı derlemeye çalışıyorum.

-fexceptionsbayrak olarak eklemek istiyorum . İle denedim

set (CMAKE_EXE_LINKER_FLAGS -fexceptions ) or set (CMAKE_EXE_LINKER_FLAGS "fexceptions" )

ve

set ( CMAKE_C_FLAGS "fexceptions")

Hala bir hata gösteriyor.


şu anda aynı problemi yaşıyorum ve farklı şeyler deniyorum. Biraz bekle ve ben bir cevap gönderirim. Derleme bayrakları için kirli ama kolay bir yol vardır: add_definitions ("
truc

Bu soru hakkında daha güncel bir tartışma için (özellikle CMake 3.x veya daha yenisini kullanıyorsanız): CMake'de genel derleme bayrakları ayarlamak için modern yöntem nedir? .
ComicSansMS

İstediğiniz bağlantı bayrakları rpath'i yapılandırmayı hedefliyorsa , belirli CMake rpath komutlarına bakın gitlab.kitware.com/cmake/community/wikis/doc/cmake/…
Gabriel Devillers

Yanıtlar:


243

Bu bayrakları eklemek istediğinizi varsayalım (sabit olarak beyan etmek daha iyidir):

SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
SET(GCC_COVERAGE_LINK_FLAGS    "-lgcov")

Bunları eklemenin birkaç yolu vardır:

  1. En kolay olanı (temiz değil, kolay ve kullanışlı ve sadece derleme bayrakları için çalışır, C & C ++ bir kerede):

    add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
  2. Karşılık gelen CMake değişkenlerine ekleme:

    SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}")
    SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
    
  3. Hedef özellikleri kullanma, bkz. doc CMake flag hedef özelliğini derleyin ve hedef adını bilmeniz gerekir.

    get_target_property(TEMP ${THE_TARGET} COMPILE_FLAGS)
    if(TEMP STREQUAL "TEMP-NOTFOUND")
      SET(TEMP "") # Set to empty string
    else()
      SET(TEMP "${TEMP} ") # A space to cleanly separate from existing content
    endif()
    # Append our values
    SET(TEMP "${TEMP}${GCC_COVERAGE_COMPILE_FLAGS}" )
    set_target_properties(${THE_TARGET} PROPERTIES COMPILE_FLAGS ${TEMP} )
    

Şu anda yöntem 2 kullanıyorum.


4
add_definitions () neden kirli?
leinaD_natipaC

14
@leinaD_natipaC: Resmi belgeler diyor ki: Bu komut herhangi bayrakları eklemek için kullanılabilir, ancak önişlemci tanımları eklemek için tasarlanmıştır . Bence bu yüzden.
Benoit Blanchon

Bu gerçekten çok eski bir stil CMAKE gösteren kabul edilen cevap olsa da, derleme zamanı parametreleriyle ilgili yeni CMAKE kodlarının nasıl yapılandırılması gerektiğine dair @vitaut tarafından verilen cevaba bakınız
Harald Scheirich

1
string(APPEND CMAKE_EXE_LINKER_FLAGS "new_value")daha kısa ve daha temizset(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} new_value")
kanlı

165

CMake'in daha yeni sürümlerinde, sırasıyla target_compile_optionsve ile tek bir hedef için derleyici ve bağlayıcı bayrakları ayarlayabilirsiniz target_link_libraries(evet, ikincisi bağlayıcı seçeneklerini de ayarlar):

target_compile_options(first-test PRIVATE -fexceptions)

Bu yöntemin avantajı, bu aracılığıyla birine bağlı diğer hedeflere seçeneklerin yayılmasını kontrol edebilmesidir PUBLICve PRIVATE.

CMake 3.13'ten itibaren target_link_options, amacı daha net hale getiren bağlayıcı seçenekleri eklemek için de kullanabilirsiniz .


2
Kullanmaya çalıştım: target_compile_options(main_static PRIVATE --static)ama işe yaramıyor gibi görünüyor, neden?
Paweł Szczur

2
-staticmuhtemelen bir bağlayıcıdır, derleyici seçeneği değildir. Şuraya aktarmayı deneyin target_link_libraries.
vitaut

9
Oh, target_link_librariesdokümanın şu bölümünü kaçırdım: " Belirli bir hedefi bağlarken kullanılacak kitaplıkları veya bayrakları belirtin .". Teşekkürler.
Paweł Szczur

3
Son eklenen: CMake 3.13, target_link_optionsbağlayıcı bayraklarını belirtmenin daha temiz bir yolu olarak tanıtıldı . target_link_librariesGelecekte bağlayıcı bayrakları için kullanmaktan kaçınmalı ve target_link_optionsbunun yerine kullanmalısınız .
ComicSansMS


46

Değişkeni aşağıdakiler CMAKE_CXX_FLAGSyerine ayarlamayı deneyin CMAKE_C_FLAGS:

set (CMAKE_CXX_FLAGS "-fexceptions")

Değişken CMAKE_C_FLAGSyalnızca C derleyicisini etkiler, ancak C ++ kodunu derliyorsunuz.

Bayrağını eklemek CMAKE_EXE_LINKER_FLAGSgereksizdir.


Bunu denedim ama yine de hata veriyor. Derleyici bayrağını belirtmenin tek yolu (CMAKE_CXX_FLAGS "-fexceptions") olarak ayarlanmıştır.
solti

3
sorunu çözdüm ama iyi bir şekilde onun kötü bir çözüm .. i -DCMAKE_CXX_FLAGS = "-fexceptions" komut satırında yaptı. nedense cmake .cmake dosyasındaki bayrakları okumuyor. :( .. Cevabınız için teşekkür ederim sakra ..
solti

8
-DCMAKE_CXX_FLAGS = "-fexceptions" = ve "arasında boşluk olmamalı
evandrix

Söylediklerinizle ilgili olarak: "cmake .cmake dosyasındaki bayrakları okumuyor." Mevcut önbelleği temizlediğinizden emin olun. Bu, tekrar cmake yapmadan önce derleme dizininden her şeyi silerek yapılabilir.
zaizen

1

LINK_FLAGSÖzelliği kullanarak belirli bir hedefe bağlayıcı bayrakları da ekleyebilirsiniz :

set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${flag}")

Bu değişikliği diğer hedeflere yaymak istiyorsanız, bağlanmak için sahte bir hedef oluşturabilirsiniz.


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.