CMake可以使用g++编译C文件吗?

25

我曾在一个项目中使用g++编译以.c结尾的C代码文件。原因是有人告诉我g++具有更好的警告信息。

现在我正在将该项目的构建过程切换到使用CMake。我发现最初CMake想要使用gcc来编译C文件,但由于像在使用时声明变量之类的原因而失败。因此,我尝试使用g++编译C文件,通过以下设置:

set(CMAKE_C_COMPILER_INIT g++)

在CMakeLists.txt文件中添加了代码,但是导致了以下错误信息:

#error "The CMAKE_C_COMPILER is set to a C++ compiler"

我一直在将我的.c文件重命名为.cpp文件来解决这个问题,因为这似乎是让事情正常工作的最简单的方法,也可能是最好的方法。但我想知道是否有可能强制CMake使用g++编译C文件。


2
原因是我听说 g++ 有更好的警告信息。这是否属实我无法确认,因为据我所知,两者都只是使用不同参数(语言、包含路径、链接的标准库等)调用相同的编译器而已。除此之外,g++ 并不是一个 C 编译器,因此你最终会写出非常差劲的 C++。 - user395760
如果你在写C语言,那么就要用C编译器进行编译。C和C++是不同的东西。 - Kusalananda
1
你说 'This failed because of things like declaring variables at use time'; 这听起来像是你在使用C89模式的GCC,而不是C99模式。尝试在C编译器中添加-std=c99选项 - 无论如何。 - Jonathan Leffler
谢谢您的评论,我一定会考虑这些建议。 - Gabriel Southern
4个回答

51

不应该为了这个目的而覆盖编译器。如果你确实需要将C文件编译为C ++,那么你应该教CMake让它知道你的文件属于C ++语言:

set_source_files_properties(filename.c PROPERTIES LANGUAGE CXX )

听起来我想要做的不是最好的选择,我应该将文件重命名为.cpp。但感谢您提供了正确的答案,如果真的有必要做我想做的事情,知道如何做是很有用的。 - Gabriel Southern
你有没有想过为什么将这个应用于项目中的单个文件会使项目中的所有文件都被编译为C++?我有一堆.c文件,我只想将其中一个编译为C++。 - Scorpio
1
@Scorpio,我确实想要那个症状,但是以一种明确定义的方式...为什么CMake没有一种将所有.c文件编译为C++的方法呢? - kchoi
这并没有解决C++项目中在通过编译器驱动程序来驱动链接过程时出现的后续链接问题。CMake不知道在链接过程中要使用C++库,这会导致Solaris和一些旧版本的Linux出现问题。 - jww
3
以下是处理所有C文件和C++文件的方法:file(GLOB_RECURSE CFILES "${CMAKE_SOURCE_DIR}/*.c") SET_SOURCE_FILES_PROPERTIES(${CFILES} PROPERTIES LANGUAGE CXX ) - jwmay
2
Clang打印了一个已弃用的消息:clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated [-Wdeprecated] - Salva Corts

3

要让cmake将所有C文件视为C++文件,请使用以下内容:

file(GLOB_RECURSE CFILES "${CMAKE_SOURCE_DIR}/*.c")
SET_SOURCE_FILES_PROPERTIES(${CFILES} PROPERTIES LANGUAGE CXX )

1
如果您需要切换整个项目,请在project指令中设置。
project(derproject LANGUAGES CXX)

如果正在使用它们,这将破坏一些功能测试。 - jww

0

set_source_files_properties

在这里,我选择使用 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 的作用域。请参见 DIRECTORYTARGET_DIRECTORY 选项。因此,为了将源文件属性递归地应用于项目中的所有文件,您的 CMakeLists.txt 应该类似于以下内容:

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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接