【问题标题】:How do you write a makefile for both clang and gcc?你如何为 clang 和 gcc 编写一个 makefile?
【发布时间】:2018-11-29 04:08:27
【问题描述】:

我想在我的代码中使用 std::experimental::filesystem,这需要我使用带有 GCC 的 -lstdc++fs 和带有 Clang 的 -lc++experimental 进行编译。目前我有一个 makefilemakefile.clang 反映编译的差异,或者我考虑过使用 clang 构建目标,以便我可以运行 build clang

是否有一些规范的方法可以在 makefile 中设置特定于编译器的标志?

【问题讨论】:

  • 无关:您应该可以通过升级到支持 C++17 的编译器来避免这种情况
  • 你能发布你当前使用的makefile吗?
  • 假设您使用 GNU Make(或一些兼容的 make 程序),您可以使用 conditions 设置某些标志。或者您可以使用另一个构建系统来为您生成正确的 makefile。
  • edit您的问题提供有用的附加文本信息(作为文本)。
  • 我知道这是旧的,但这个网站对任何寻找答案的人都有帮助:hiltmon.com/blog/2015/09/28/… ...我已经使用这种方法很长时间没有问题

标签: c++ makefile gnu-make


【解决方案1】:

您可以使用 CMake 来实现。如果您想拥有可移植的代码,最好使用它。

CMake 允许生成适合您系统的 Makefile(例如您的系统默认编译器)。 CMake 有很多功能对于检查实际系统配置非常有用。

在这个答案中,您有示例:In cmake, how can I test if the compiler is Clang?

一个可靠的检查是使用 CMAKE__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()

如果你仍然想使用 Makefile,你应该检查这个答案:https://stackoverflow.com/a/2826178/7042963

【讨论】:

    【解决方案2】:

    正如用户“一些程序员老兄”所提到的,GNU make 中有conditionals。您可以通过这种方式轻松检查编译器版本:

    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
    

    给定以下源文件test.cpp,您可以使用make CXX=g++ testmake CXX=clang test 对其进行编译,它应该将适当的标志传递给每个编译器。

    #include <iostream>
    
    int main() {
      std::cout << "Hello World " << MESSAGE << std::endl;
      return 0;
    }
    

    【讨论】:

    • 我会接受这个作为答案,因为它可能是你只使用 make 时能得到的最接近的东西。它存在别名问题,例如 MacOS 将 g++ 别名为 clang,而像 g++-7 这样的版本化编译器可能无法正常工作。
    【解决方案3】:

    为了处理版本化编译器,就像您在接受答案的评论中提到的那样,您需要使用 $(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
    

    这里需要注意的是,您不能使用$(findstring g++,$(CXX)),因为它会无意中匹配clang++

    更精确地处理事情的更深入的替代方法是:

    # 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
    

    【讨论】:

      猜你喜欢
      • 2015-10-02
      • 1970-01-01
      • 2013-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-25
      • 1970-01-01
      • 2012-07-08
      相关资源
      最近更新 更多