[英]How do you write a makefile for both clang and gcc?
I would like to use std::experimental::filesystem
in my code, this requires me to compile using -lstdc++fs
with GCC and -lc++experimental
with Clang.我想在我的代码中使用
std::experimental::filesystem
,这需要我使用带有 GCC 的-lstdc++fs
和带有 Clang 的-lc++experimental
进行编译。 At the moment I have a makefile
and makefile.clang
reflecting the difference in compilation, alternatively I've thought about using a clang build target so I can run build clang
.目前我有一个
makefile
和makefile.clang
反映了编译的差异,或者我考虑过使用 clang 构建目标,这样我就可以运行build clang
。
Is there some canonical way to set compiler-specific flags in a makefile?是否有一些规范的方法可以在生成文件中设置特定于编译器的标志?
As the user "Some programmer dude" mentioned, there areconditionals in GNU make.正如用户“一些程序员老兄”所提到的,GNU make 中有条件。 You could easily check for the compiler version this way:
您可以通过这种方式轻松检查编译器版本:
CXXFLAGS = -Og -Wall -Wextra
GCC_CXXFLAGS = -DMESSAGE='"Compiled with GCC"'
CLANG_CXXFLAGS = -DMESSAGE='"Compiled with Clang"'
UNKNOWN_CXXFLAGS = -DMESSAGE='"Compiled with an unknown compiler"'
ifeq ($(CXX),g++)
CXXFLAGS += $(GCC_CXXFLAGS)
else ifeq ($(CXX),clang)
CXXFLAGS += $(CLANG_CXXFLAGS)
else
CXXFLAGS += $(UNKNOWN_CXXFLAGS)
endif
Given the following source file test.cpp
you can compile it with make CXX=g++ test
or make CXX=clang test
and it should pass the appropriate flags to each compiler.给定以下源文件
test.cpp
,您可以使用make CXX=g++ test
或make CXX=clang test
编译它,它应该将适当的标志传递给每个编译器。
#include <iostream>
int main() {
std::cout << "Hello World " << MESSAGE << std::endl;
return 0;
}
You can use CMake to achieve that.您可以使用 CMake 来实现这一点。 It is a better to use if you want to have portable code.
如果您想拥有可移植的代码,最好使用它。
CMake allows to generate Makefile that is appropriate for your system(eg your system default compiler). CMake 允许生成适合您系统的 Makefile(例如您的系统默认编译器)。 CMake has a lot of features that can be very useful to check actual system configuration.
CMake 有很多功能对于检查实际系统配置非常有用。
In this answer, you have example how do that: In cmake, how can I test if the compiler is Clang?在这个答案中,您有示例如何做到这一点: 在 cmake 中,我如何测试编译器是否是 Clang?
A reliable check is to use the CMAKE__COMPILER_ID variables.
一个可靠的检查是使用 CMAKE__COMPILER_ID 变量。 Eg, to check the C++ compiler:
例如,检查 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()
If you still want to use Makefile you should check this answer: https://stackoverflow.com/a/2826178/7042963如果您仍想使用 Makefile,您应该检查此答案: https ://stackoverflow.com/a/2826178/7042963
In order to handle versioned compilers, like you mentioned in the comment to the accepted answer, you need to use $(findstring find,in)
as such:为了处理版本化编译器,就像您在接受答案的评论中提到的那样,您需要使用
$(findstring find,in)
:
# Detect if CXX is g++ or clang++, in this order.
ifeq '' '$(findstring clang++,$(CXX))'
LDLIBS = -lstdc++fs
else
LDLIBS = -lc++experimental
endif
The caveat here is that you cannot use $(findstring g++,$(CXX))
since it'll match clang++
unintentionally.这里需要注意的是,您不能使用
$(findstring g++,$(CXX))
因为它会无意中匹配clang++
。
A more in-depth alternative to handle things more precisely would be:更精确地处理事情的更深入的替代方法是:
# Detect if CXX is clang++ or g++, in this order.
ifneq '' '$(findstring clang++,$(CXX))'
LDLIBS = -lc++experimental
else ifneq '' '$(findstring g++,$(CXX))'
LDLIBS = -lstdc++fs
endif
This approach parses the compiler's version string looking for clang
.这种方法解析编译器的版本字符串以寻找
clang
。 If it doesn't find clang
then it looks for g++
in order to resolve an issue with macOS, where g++
is aliased to clang
.如果它没有找到
clang
,那么它会寻找g++
以解决 macOS 的问题,其中g++
别名为clang
。
# Set compiler-specific flags
GCC_CXXFLAGS = -DMESSAGE='"Compiled with GCC"'
CLANG_CXXFLAGS = -DMESSAGE='"Compiled with Clang"'
UNKNOWN_CXXFLAGS = -DMESSAGE='"Compiled with an unknown compiler"'
# Detect if CXX is clang++ or g++, in this order.
COMPILER_VERSION := $(shell $(CXX) --version)
ifneq '' '$(findstring clang,$(COMPILER_VERSION))'
CFLAGS += $(CLANG_CXXFLAGS)
else ifneq '' '$(findstring g++,$(COMPILER_VERSION))'
CFLAGS += $(GCC_CXXFLAGS)
else
$(warning Unknown compiler)
CFLAGS += $(UNKNOWN_CXXFLAGS)
endif
Credit to @bit2shift's answer, which inspired this one.感谢@bit2shift 的回答,它启发了这个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.