Скажите 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++.