Скажите CMake использовать компилятор C++ для файлов C, поступающих из CMake?

Это похоже на Force CMake для использования компилятора C++ для файлов C с Visual Studio, но это не совсем то же самое. Это не то же самое, потому что его файл CMake вызывает сбой; и я работаю почти на каждой современной платформе, от BSD и OS X до Solaris и Unix.

Я пытался избежать бесполезных проверок, выполняемых CMake:

project(cryptopp, CXX)

Вот что происходит, когда я пытаюсь сгенерировать make-файл:

$ cmake .
-- Check if the system is big endian
-- Searching 16 bit integer
-- Check size of unsigned short
CMake Error at /usr/share/cmake-2.8/Modules/CheckTypeSize.cmake:82 (try_compile):
  Unknown extension ".c" for file

    /home/jeffrey/cryptopp/CMakeFiles/CheckTypeSize/CMAKE_SIZEOF_UNSIGNED_SHORT.c

  try_compile() works only for enabled languages.  Currently these are:

    CXX

  See project() command to enable other languages.
Call Stack (most recent call first):
  /usr/share/cmake-2.8/Modules/CheckTypeSize.cmake:167 (__check_type_size_impl)
  /usr/share/cmake-2.8/Modules/TestBigEndian.cmake:27 (CHECK_TYPE_SIZE)
  CMakeLists.txt:49 (TEST_BIG_ENDIAN)

У нас нет C-файлов в нашем проекте, поэтому мы должны быть в безопасности с project(cryptopp, CXX) (если я читаю cmake --help-command project правильно).

Цитируемый вопрос говорит о файлах проекта, но не о файлах CMake.

Как мне сказать CMake использовать компилятор C++ для всех файлов, включая его собственные файлы CMake?


Я на Ubuntu 12 LTS, и это обеспечивает:

$ cmake --version
cmake version 2.8.7

3 ответа

Решение

Есть способы добавить .c как действительное расширение файла для CXX компилятор. Даже если это очень продвинутый материал CMake, вам может понадобиться - если вы обязаны поддерживать более старые версии CMake - в любом случае "скрипт перезаписи правил".

Итак, я успешно протестировал следующее:

CryptoppMakeRulesOverwrite.cmake

list(APPEND CMAKE_CXX_SOURCE_FILE_EXTENSIONS c)

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.7 FATAL_ERROR)

set(CMAKE_USER_MAKE_RULES_OVERRIDE "CryptoppMakeRulesOverwrite.cmake")

project(cryptopp CXX)

include(CheckTypeSize)
CHECK_TYPE_SIZE("unsigned short" CMAKE_SIZEOF_UNSIGNED_SHORT)

Как прокомментировал @ Цыварев check_type_size() поддерживает LANGUAGE параметр, но, к сожалению, не для CMake версии 2.8.7. Но эта старая версия уже поддерживает CMAKE_USER_MAKE_RULES_OVERRIDE,

Так что мне все еще интересно, не будет ли лучшим решением перейти на более новую версию CMake (что заставляет некоторых пользователей старых версий CMake обновляться). Или писать свой собственный try_compile() сниппеты.

Рекомендации

Настройка CMake (мой) выбор здесь будет set_source_files_propertiesкоманда. https://cmake.org/cmake/help/latest/command/set_source_files_properties.html

      set(qpid_dispatch_SOURCES
  alloc.c
  alloc_pool.c
  aprintf.c
  amqp.c
  atomic.c
# [...]
)
set_source_files_properties(${qpid_dispatch_SOURCES} PROPERTIES LANGUAGE CXX)
add_library(qpid-dispatch OBJECT ${qpid_dispatch_SOURCES})

Как описано в связанных документах, CMake 3.18 изменил область действия set_source_files_properties. См. DIRECTORYа также TARGET_DIRECTORYопции. Поэтому, чтобы рекурсивно применить свойство исходного файла ко всем файлам в вашем проекте, вы должны выглядеть примерно так:

      cmake_minimum_required(VERSION 3.20)
project(qpid-dispatch LANGUAGES C CXX)

# [...]

add_subdirectory(src)
add_subdirectory(tests)
add_subdirectory(router)

# [...]

file(GLOB_RECURSE CFILES "*.c")
set_source_files_properties(${CFILES}
        DIRECTORY src tests router
        PROPERTIES LANGUAGE CXX)

Скопируйте мир

Есть еще один подход, который, как я слышал, можно заставить работать: в вашем CMakeLists.txt, рекурсивно скопировать все *.cфайлы в *.cppфайлы и объявить отдельные цели CMake для компиляции копий. Преимущество этого заключается в том, что вы можете одновременно создавать артефакты, скомпилированные на C и CXX, если вам что-то подобное понадобится.

Другой безмозглый способ сделать это (я только что попробовал set_source_files_properties()route, и он просто даже не пытался скомпилировать файлы).

Вместо того, чтобы разбираться в крысином гнезде материалов cmake, которыми я обременен, я просто добавил файл C++, который #includes файл .c, и добавил файл C++ в исходники CMakeLists.txt.

Безмозглый и глупый, но мне приходится иметь дело с ужасным кодом, который я импортирую. Файлы заголовков C без внешней буквы «C» в них, используемые файлами C++.

Другие вопросы по тегам