ใน CMake ฉันจะทดสอบได้อย่างไรว่าคอมไพเลอร์เป็นเสียงดังกราว


151

เรามีชุดสคริปต์สร้างข้ามแพลตฟอร์ม CMakeและเราสนับสนุนการสร้างด้วยVisual C ++และ GCC

เรากำลังลองเสียงดังกราวแต่ฉันไม่สามารถหาวิธีทดสอบได้ว่า Compiler นั้นเป็น Clang กับสคริปต์ CMake ของเราหรือไม่

สิ่งที่ฉันควรทดสอบเพื่อดูว่าคอมไพเลอร์เป็นเสียงดังกราวหรือไม่? ขณะนี้เรากำลังใช้MSVCและCMAKE_COMPILER_IS_GNU<LANG>ทดสอบ Visual C ++ และ GCC ตามลำดับ


คุณสามารถตั้งค่าคอมไพเลอร์โดยการตั้งค่า CMAKE_C_COMPILER และ CMAKE_CXX_COMPILER ไปยังเส้นทางไปยังเสียงดังกราวหรือเสียงดังกังวาน ++ +1 สำหรับเสียงดังกราว
Zaffy

ทำไมคุณต้องแคร์ เสียงดังกราวเป็น GCC ชอบมากในแง่ของการได้รับการยอมรับตัวเลือกคอมไพเลอร์ ...
Basile Starynkevitch

2
@BasileStarynkevitch เนื่องจากเรารองรับ MSVC เราจำเป็นต้องตรวจสอบ Clang ดังนั้นเราจึงรู้ว่าจะเปิดตัวเลือก GCC หรือตัวเลือกที่เหมือน MSVC มันนานเกินกว่าที่ฉันจะจำได้ แต่ก็เป็นไปได้อย่างแน่นอนว่าเรากำลังใช้ตัวเลือกที่ไม่ได้รับการสนับสนุนจาก Clang เช่นกัน
leedm777

1
@BasileStarynkevitch - เสียงดังแสร้งทำเป็นว่าทั้งคู่__GNUC__และ_MSC_VERแต่มันไม่สามารถใช้โปรแกรมเดียวกันกับคอมไพเลอร์ตัวใดตัวหนึ่งได้ การตรวจจับ LLVM Clang และ Apple Clang นั้นมีความสำคัญอย่างยิ่งในการตรวจสอบให้แน่ใจว่าโค้ดรวบรวมและดำเนินการตามที่คาดไว้ ฉันเหนื่อยมากในการจัดการกับเสียงดังกราวของ BS เราก็ทำลายรวบรวมบนวินโดวส์ เราได้นำนโยบายการอนุญาตให้ผู้ใช้ร้องเรียนไปยัง LLVM ดังนั้น Clang devs จึงเปลี่ยนพฤติกรรมของพวกเขา ดูวิธีการบอก Clang ให้หยุดแกล้งทำเป็นคอมไพเลอร์คนอื่น ๆ ด้วย?
jww

คำตอบ:


242

การตรวจสอบที่เชื่อถือได้คือการใช้CMAKE_<LANG>_COMPILER_IDตัวแปร เช่นเพื่อตรวจสอบคอมไพเลอร์ C ++:

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  # using Clang
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  # using GCC
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
  # using Intel C++
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  # using Visual Studio C++
endif()

เหล่านี้ทำงานได้อย่างถูกต้องนอกจากนี้ยังมีการห่อหุ้มคอมไพเลอร์เช่นccacheถูกนำมาใช้

ในฐานะของ CMake 3.0.0 ค่าสำหรับแอปเปิ้ลที่ให้เสียงดังกราวอยู่ในขณะนี้CMAKE_<LANG>_COMPILER_ID AppleClangในการทดสอบทั้งเสียงดังกราวที่ Apple จัดให้และเสียงแตรปกติใช้เงื่อนไขดังต่อไปนี้:

if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  # using regular Clang or AppleClang
endif()

ดูคำอธิบายนโยบายของ AppleClangด้วย

CMake 3.15ได้เพิ่มการรองรับทั้งclang-clและ clang front end คุณสามารถกำหนดตัวแปรส่วนหน้าโดยตรวจสอบตัวแปรCMAKE_CXX_COMPILER_FRONTEND_VARIANT:

if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  if (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
    # using clang with clang-cl front end
  elseif (CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
    # using clang with regular front end
  endif()
endif()

เอกสาร CMakeฯ "นี้จะใช้ในการพิจารณาคอมไพเลอร์และอาจมีการเปลี่ยนแปลง" มิฉะนั้นจะสมบูรณ์แบบ :-(
leedm777

17
ตั้งแต่ CMake 2.8.10 ตัวแปรนี้เป็นเอกสาร (ในที่สุด!) ดู: cmake.org/cmake/help/v2.8.10/…
นิคฮัทชินสัน

9
โปรดทราบว่าCMAKE_CXX_COMPILER_IDตัวแปรมีให้ใช้งานหลังจากคำสั่งเท่านั้นproject(Foo CXX)เท่านั้น
waldyrious

5
และสำหรับธงที่ gcc และ clang ยอมรับฉันใช้ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang|GNU") ... endif()
Fred Schoen

4
หากคุณสับสนว่าทำไมคุณไม่สามารถตรวจจับได้AppleClangโดยเฉพาะ @sakra แสดงว่ามีการcmake 3.0.0เปิดตัวAppleClangการปล่อยตัวอย่างไรก็ตามเพียงเพราะcmake --versionรายงานที่เท่ากับหรือสูงกว่านั้นไม่เพียงพอคุณต้องทำcmake_minimum_required(VERSION 3.0.0)ตาม3.0.0มาตรฐานที่จะใช้!
svenevs

2

รหัสแหล่งโปรแกรม OGRE 3D ใช้การตรวจสอบต่อไปนี้:

if (CMAKE_CXX_COMPILER MATCHES ".*clang")
    set(CMAKE_COMPILER_IS_CLANGXX 1)
endif ()

3
อยู่ใกล้ แต่ไม่สามารถใช้งานได้เมื่อคุณใช้ccache (เช่นexport CXX="ccache clang++")
leedm777

4
ใกล้พอฉันจะมอบให้คุณ ฉันใช้if ("${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang")เพื่อจัดการกรณี ccache
leedm777

1
${CMAKE_CXX_COMPILER} == /Library/Developer/CommandLineTools/usr/bin/c++นี้ไม่ทำงานสำหรับฉันเป็น คำตอบที่ได้รับการยอมรับใช้งานได้
Fred Schoen

1

เพียงเพื่อหลีกเลี่ยงปัญหาการสะกดผิดฉันใช้การเปรียบเทียบแบบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่เช่น:

string( TOLOWER "${CMAKE_CXX_COMPILER_ID}" COMPILER_ID )
if (COMPILER_ID STREQUAL "clang")
    set(IS_CLANG_BUILD true)
else ()
    set(IS_CLANG_BUILD false)
endif ()

สำหรับการสร้าง regex ของMATCHEScase-insensitive ฉันลองทุกอย่างที่นี่โดยไม่ประสบความสำเร็จ (ดูเหมือนจะไม่ได้รับการสนับสนุนใน CMake)


แท้จริงแล้วในวันนี้การจับคู่ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่นั้นเป็นไปไม่ได้ที่cmake.org/pipermail/cmake/2017-May/065432.html
fferri

-2

นี่เป็นคำตอบที่ละเอียดมากขึ้นเล็กน้อยสำหรับมือใหม่ cmake แก้ไขจากคำตอบของ sakra เพียงต่อท้ายบรรทัดต่อไปนี้CMakeLists.txt:

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  MESSAGE("Clang")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  MESSAGE("GNU")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
  MESSAGE("Intel")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
  MESSAGE("MSVC")
endif()

จากนั้นเรียกใช้cmake .ในโฟลเดอร์ที่ CMakeLists.txt อยู่ จากนั้นคุณจะเห็นผลลัพธ์จำนวนมากพร้อมกับคำตอบของคุณ

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