ฉันจะเพิ่มตัวเชื่อมโยงหรือการตั้งค่าสถานะการคอมไพล์ในไฟล์ CMake ได้อย่างไร


220

ฉันใช้arm-linux-androideabi-g++คอมไพเลอร์ เมื่อฉันพยายามรวบรวม "Hello, World!" โปรแกรมมันคอมไพล์ดี เมื่อฉันทดสอบโดยการเพิ่มการจัดการข้อยกเว้นแบบง่ายในโค้ดนั้นมันก็ทำงานได้เช่นกัน (หลังจากเพิ่ม-fexceptions.. ฉันคิดว่ามันถูกปิดใช้งานโดยค่าเริ่มต้น)

นี้สำหรับอุปกรณ์ Android, และฉันเพียงต้องการที่จะใช้ CMake ndk-buildไม่

ตัวอย่างเช่น - first.cpp

#include <iostream>

using namespace std;

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

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

มันทำงานได้โดยไม่มีปัญหา ...

ปัญหา ... ฉันพยายามรวบรวมไฟล์ด้วยไฟล์ CMake

ฉันต้องการที่จะเพิ่ม-fexceptionsเป็นธง ฉันลองด้วย

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

และ

set ( CMAKE_C_FLAGS "fexceptions")

มันยังคงแสดงข้อผิดพลาด


ตอนนี้ฉันมีปัญหาเดียวกันและฉันพยายามทำสิ่งที่แตกต่าง แขวนเล็กน้อยและฉันโพสต์คำตอบ สำหรับการคอมไพล์ธงมีวิธีที่ไม่สะอาด แต่ง่าย ๆ : add_definitions ("- truc")
Offirmo

สำหรับการสนทนาที่ทันสมัยมากขึ้นสำหรับคำถามนี้ (โดยเฉพาะถ้าคุณใช้ CMake 3.x หรือใหม่กว่า): วิธีการที่ทันสมัยสำหรับการตั้งค่าสถานะการคอมไพล์ทั่วไปใน CMake คืออะไร .
ComicSansMS

ถ้าธงลิงค์ที่คุณต้องการมีจุดมุ่งหมายที่กำหนดค่าRPATHแล้วมีลักษณะที่เฉพาะเจาะจง CMake RPATH คำสั่งgitlab.kitware.com/cmake/community/wikis/doc/cmake/...
กาเบรียล Devillers

คำตอบ:


243

สมมติว่าคุณต้องการเพิ่มธงเหล่านั้น (ดีกว่าที่จะประกาศในค่าคงที่):

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

มีหลายวิธีในการเพิ่ม:

  1. สิ่งที่ง่ายที่สุด (ไม่สะอาด แต่ง่ายและสะดวกและใช้ได้กับการรวบรวมธง C & C ++ พร้อมกัน):

    add_definitions(${GCC_COVERAGE_COMPILE_FLAGS})
  2. ต่อท้ายตัวแปร CMake ที่สอดคล้องกัน:

    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. การใช้คุณสมบัติเป้าหมาย cf doc CMake รวบรวมคุณสมบัติเป้าหมายการตั้งค่าสถานะและจำเป็นต้องรู้ชื่อเป้าหมาย

    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} )

ตอนนี้ฉันใช้วิธีที่ 2


4
ทำไม add_definitions () ไม่สะอาด?
leinaD_natipaC

14
@leinaD_natipaC: ในเอกสารอย่างเป็นทางการกล่าวว่าคำสั่งนี้สามารถนำมาใช้เพื่อเพิ่มธงใด ๆ แต่ก็มีจุดมุ่งหมายเพื่อเพิ่มคำนิยาม ฉันคิดว่านั่นเป็นเหตุผล
เบอนัวต์บลอนชอน

ในขณะที่นี่เป็นคำตอบที่ได้รับการยอมรับซึ่งแสดงให้เห็นจริง ๆ ว่าเป็นแบบเก่าของ CMAKE โปรดอ้างถึงคำตอบของ @vitaut สำหรับวิธีการสร้างรหัส CMAKE ใหม่ใด ๆ เกี่ยวกับพารามิเตอร์เวลารวบรวม
Harald Scheirich

1
string(APPEND CMAKE_EXE_LINKER_FLAGS "new_value")สั้นและสะอาดกว่าset(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} new_value")
เลือด

165

ในเวอร์ชันที่ใหม่กว่าของ CMake คุณสามารถตั้งค่าตัวคอมไพเลอร์และตัวเชื่อมโยงสำหรับเป้าหมายเดี่ยวด้วยtarget_compile_optionsและtarget_link_librariesตามลำดับ (ใช่ตัวหลังจะตั้งค่าตัวเลือกตัวเชื่อมโยงด้วย):

target_compile_options(first-test PRIVATE -fexceptions)

ข้อดีของวิธีนี้คือการที่คุณสามารถควบคุมการแพร่กระจายของตัวเลือกเพื่อเป้าหมายอื่น ๆ ที่ขึ้นอยู่กับคนนี้ผ่านทางและPUBLICPRIVATE

ตั้งแต่ CMake 3.13 คุณสามารถใช้target_link_optionsเพื่อเพิ่มตัวเลือกลิงเกอร์ซึ่งทำให้เจตนาชัดเจนยิ่งขึ้น


2
ฉันพยายามใช้มันtarget_compile_options(main_static PRIVATE --static)แต่ดูเหมือนจะไม่ทำงานความคิดใด ๆ ว่าทำไม?
Paweł Szczur

2
-staticอาจเป็นตัวเชื่อมโยงไม่ใช่ตัวเลือกคอมไพเลอร์ target_link_librariesลองผ่านไป
vitaut

9
โอ้target_link_librariesฉันพลาดส่วนหนึ่งของ doc นั่น: "ระบุไลบรารีหรือแฟล็กที่จะใช้เมื่อเชื่อมโยงเป้าหมายที่กำหนด" ขอบคุณ
Paweł Szczur

3
การเพิ่มล่าสุด: CMake 3.13 แนะนำtarget_link_optionsเป็นวิธีที่สะอาดกว่าในการระบุแฟล็กลิงเกอร์ คุณควรหลีกเลี่ยงการใช้target_link_librariesธงลิงเกอร์ในอนาคตและใช้target_link_optionsแทน
ComicSansMS

1
นอกจากนี้ยังมีadd_compile_options - ดูstackoverflow.com/questions/39501481/…และอีกไม่นานadd_link_options
Bruce Adams

46

ลองตั้งค่าตัวแปรCMAKE_CXX_FLAGSแทนCMAKE_C_FLAGS:

set (CMAKE_CXX_FLAGS "-fexceptions")

ตัวแปรCMAKE_C_FLAGSมีผลกับตัวแปลภาษา C เท่านั้น แต่คุณกำลังรวบรวมรหัส C ++

การเพิ่มการตั้งค่าสถานะCMAKE_EXE_LINKER_FLAGSเป็นซ้ำซ้อน


ฉันลองมัน แต่ก็ยังให้ข้อผิดพลาด ถูกตั้งค่า (CMAKE_CXX_FLAGS "-fexceptions") วิธีเดียวที่จะระบุการตั้งค่าสถานะคอมไพเลอร์
solti

3
ฉันแก้ไขปัญหา แต่ไม่ใช่ในวิธีที่ดีมันเป็นวิธีแก้ปัญหาที่ไม่ดี .. ฉันทำ -DCMAKE_CXX_FLAGS = "-fexceptions" ในบรรทัดคำสั่ง ด้วยเหตุผลบางประการ cmake ไม่ได้อ่านค่าสถานะจากไฟล์. cmake :( .. ขอบคุณ sakra สำหรับคำตอบของคุณ ..
solti

8
-DCMAKE_CXX_FLAGS = "-fexceptions" ไม่ควรมีช่องว่างระหว่าง = และ "
evandrix

เกี่ยวกับสิ่งที่คุณพูด: "ด้วยเหตุผลบางอย่าง cmake ไม่ได้อ่านค่าสถานะจากไฟล์. cmake" ตรวจสอบให้แน่ใจว่าคุณล้างแคชที่มีอยู่ ซึ่งสามารถทำได้โดยการลบทุกอย่างออกจากไดเรกทอรีการสร้างก่อนที่จะกลับมาอีกครั้ง
zaizen

1

คุณยังสามารถเพิ่มธงลิงเกอร์ไปยังเป้าหมายที่ต้องการได้โดยใช้LINK_FLAGSคุณสมบัติ:

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

หากคุณต้องการเผยแพร่การเปลี่ยนแปลงนี้ไปยังเป้าหมายอื่นคุณสามารถสร้างเป้าหมายจำลองเพื่อเชื่อมโยง


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.