【问题标题】:I want to compile with clang/clang++ by detecting clang with the correct procedure with cmake我想通过使用 cmake 使用正确的程序检测 clang 来使用 clang/clang++ 进行编译
【发布时间】:2018-06-19 16:59:44
【问题描述】:

下面是我想做的。

我想通过使用 cmake 以正确的程序检测 clang 来使用 clang/clang++ 进行编译。

请告诉我可以解决我将描述的问题的正确程序。

test environment:
OS   : Ubuntu 16.10 64bit
gcc  : gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005
clang: 6.0.0 (self build)
cmake: 3.11.3

我做了以下步骤,但无法正确检测到。

我刚刚描述了检测到的 CMakeLists.txt 部分。

CMakeLists.txt

function(display_vars vars prefix)
  message("${prefix}")
  foreach(IT ${vars})
    message("${prefix}${IT} = ${${IT}}")
  endforeach()
endfunction()


include(CheckCXXCompilerFlag)

set(project_name clang-test)

project(${project_name})

find_package(LLVM REQUIRED CONFIG)

include_directories( ${LLVM_INCLUDE_DIRS} )
add_definitions ( ${LLVM_DEFINITIONS} )

enable_language(CXX)

# setup compile & link flags
check_cxx_compiler_flag(-std=c++17 COMPILER_SUPPORTS_CXX17)
check_cxx_compiler_flag(-std=c++1z COMPILER_SUPPORTS_CXX1Z)
check_cxx_compiler_flag(-std=c++14 COMPILER_SUPPORTS_CXX14)
check_cxx_compiler_flag(-std=c++1y COMPILER_SUPPORTS_CXX1Y)
check_cxx_compiler_flag(-std=c++11 COMPILER_SUPPORTS_CXX11)
check_cxx_compiler_flag(-std=c++0x COMPILER_SUPPORTS_CXX0X)

# setup compile & link flags
if(COMPILER_SUPPORTS_CXX17)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
elseif(COMPILER_SUPPORTS_CXX1Z)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z")
elseif(COMPILER_SUPPORTS_CXX14)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
elseif(COMPILER_SUPPORTS_CXX1Y)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y")
elseif(COMPILER_SUPPORTS_CXX11)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
  message(FATAL_ERROR "The compiler has no C++11 support.")
endif()


set(echo_vars)
# result by find_package(LLVM REQUIRED CONFIG) 
list(APPEND echo_vars LLVM_DIR LLVM_PACKAGE_VERSION LLVM_INCLUDE_DIRS LLVM_DEFINITIONS)
# detect environment
list(APPEND echo_vars 
  CMAKE_C_COMPILER_ID 
  CMAKE_C_STANDARD 
  CMAKE_CXX_COMPILER_ID 
  CMAKE_CXX_STANDARD
  CMAKE_CXX_FLAGS
  CMAKE_GNUtoMS 
  CMAKE_SYSTEM_NAME 
  CMAKE_COMPILER_IS_GNUC 
  CMAKE_COMPILER_IS_GNUCXX 
  CMAKE_COMPILER_IS_CLANG
  CMAKE_COMPILER_IS_MINGW 
  CMAKE_COMPILER_IS_CYGWIN
  CMAKE_GNU_COMPILER_ID 
  CMAKE_CLANG_COMPILER_ID)

display_vars("${echo_vars}" "env: ")


set(project_sources test.cpp)

add_executable(${project_name} ${project_sources})

test.cpp

#include <string_view>

int main(int argc, char** argv)
{
    return 0;
}


cmake -G "Unix Makefiles" ./

执行该命令时,只检测到gcc,完全没有检测到clang。

which clang
> /usr/local/bin

这将被检测到。

自建的clang安装路径默认为/usr/local/。

检测日志如下,只检测到GCC。

日志

CMake suite maintained and supported by Kitware (kitware.com/cmake).
-- The C compiler identification is GNU 6.2.0
-- The CXX compiler identification is GNU 6.2.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
env: 
env: LLVM_DIR = /usr/local/lib/cmake/llvm
env: LLVM_PACKAGE_VERSION = 6.0.0
env: LLVM_INCLUDE_DIRS = /usr/local/include
env: LLVM_DEFINITIONS = -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
env: CMAKE_C_COMPILER_ID = GNU
env: CMAKE_C_STANDARD = 
env: CMAKE_CXX_COMPILER_ID = GNU
env: CMAKE_CXX_STANDARD = 
env: CMAKE_CXX_FLAGS = -std=c++17
env: CMAKE_GNUtoMS = 
env: CMAKE_SYSTEM_NAME = Linux
env: CMAKE_COMPILER_IS_GNUC = 
env: CMAKE_COMPILER_IS_GNUCXX = 1
env: CMAKE_COMPILER_IS_CLANG = 
env: CMAKE_COMPILER_IS_MINGW = 
env: CMAKE_COMPILER_IS_CYGWIN = 
env: CMAKE_GNU_COMPILER_ID = 
env: CMAKE_CLANG_COMPILER_ID = 
-- Performing Test COMPILER_SUPPORTS_CXX17
-- Performing Test COMPILER_SUPPORTS_CXX17 - Success
-- Performing Test COMPILER_SUPPORTS_CXX1Z
-- Performing Test COMPILER_SUPPORTS_CXX1Z - Success
-- Performing Test COMPILER_SUPPORTS_CXX14
-- Performing Test COMPILER_SUPPORTS_CXX14 - Success
-- Performing Test COMPILER_SUPPORTS_CXX1Y
-- Performing Test COMPILER_SUPPORTS_CXX1Y - Success
-- Performing Test COMPILER_SUPPORTS_CXX11
-- Performing Test COMPILER_SUPPORTS_CXX11 - Success
-- Performing Test COMPILER_SUPPORTS_CXX0X
-- Performing Test COMPILER_SUPPORTS_CXX0X - Success

日志中有如下消息,尽管它与主题不同。

执行测试 COMPILER_SUPPORTS_CXX17 - 成功

这个 gcc (6.2.0) 只支持 c++ 1z。

在 gcc 中,如下是正确的。

CXX_FLAGS = -std=c++1z

我会回到主题。

强制指定用于检测 clang 的编译器。

cmake -G "Unix Makefiles" ./ -DCMAKE_C_COMPILER=/usr/local/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/bin/clang++

新日志

CMake suite maintained and supported by Kitware (kitware.com/cmake).
-- The C compiler identification is Clang 6.0.0
-- The CXX compiler identification is Clang 6.0.0
-- Check for working C compiler: /usr/local/bin/clang
-- Check for working C compiler: /usr/local/bin/clang -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/local/bin/clang++
-- Check for working CXX compiler: /usr/local/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
env: 
env: LLVM_DIR = /usr/local/lib/cmake/llvm
env: LLVM_PACKAGE_VERSION = 6.0.0
env: LLVM_INCLUDE_DIRS = /usr/local/include
env: LLVM_DEFINITIONS = -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
env: CMAKE_C_COMPILER_ID = Clang
env: CMAKE_C_STANDARD = 
env: CMAKE_CXX_COMPILER_ID = Clang
env: CMAKE_CXX_STANDARD = 
env: CMAKE_CXX_FLAGS = -std=c++17
env: CMAKE_GNUtoMS = 
env: CMAKE_SYSTEM_NAME = Linux
env: CMAKE_COMPILER_IS_GNUC = 
env: CMAKE_COMPILER_IS_GNUCXX = 
env: CMAKE_COMPILER_IS_CLANG = 
env: CMAKE_COMPILER_IS_MINGW = 
env: CMAKE_COMPILER_IS_CYGWIN = 
env: CMAKE_GNU_COMPILER_ID = 
env: CMAKE_CLANG_COMPILER_ID = 
-- Performing Test COMPILER_SUPPORTS_CXX17
-- Performing Test COMPILER_SUPPORTS_CXX17 - Success
-- Performing Test COMPILER_SUPPORTS_CXX1Z
-- Performing Test COMPILER_SUPPORTS_CXX1Z - Success
-- Performing Test COMPILER_SUPPORTS_CXX14
-- Performing Test COMPILER_SUPPORTS_CXX14 - Success
-- Performing Test COMPILER_SUPPORTS_CXX1Y
-- Performing Test COMPILER_SUPPORTS_CXX1Y - Success
-- Performing Test COMPILER_SUPPORTS_CXX11
-- Performing Test COMPILER_SUPPORTS_CXX11 - Success
-- Performing Test COMPILER_SUPPORTS_CXX0X
-- Performing Test COMPILER_SUPPORTS_CXX0X - Success

现在检测到了。

CMAKE_COMPILER_IS_CLANG
CMAKE_CLANG_COMPILER_ID

但是,上述变量仍然为空。

我们暂时编译一个简单的文件。

将以下内容放在源文件的开头。

#include <string_view>

然后出现以下错误。

fatal error: 'string_view' file not found
#include <string_view>
         ^~~~~~~~~~~~~
1 error generated.

clang 6.0 支持 c++17 并且应该是可编译的。

尝试将 include 更改为以下内容。

这是c++1z中string_view的路径

#include <experimental/string_view>

如上描述将成功编译。

我想过这意味着什么。

编译器是clang,但是系统包含路径被gcc使用。

只能认为/usr/include/c++/6.2.0/experimental是在系统包含路径中使用/usr/include引用的。

根据我的推理,

-DCMAKE_C_COMPILER=/usr/local/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/bin/clang++

虽然编译器是用上面的选项强制指定的,但是没有正确检测到其他环境并没有改变。

如果检测正确,系统包含路径应​​该使用LLVM_INCLUDE_DIRS = /usr/local/include。

另外,我认为 CMAKE 变量将如下所示。

env: CMAKE_CLANG_COMPILER_ID = 1
env: CMAKE_COMPILER_IS_CLANG = 1

仅仅通过强制设置这个环境设置似乎有麻烦。

我认为除非cmake正确识别clang,否则影响编译的环境变量不会被正确更改。

这怎么可能?

顺便说一下,当我们在以下环境中测试时,

OS   : Ubuntu 18.04 64bit
gcc  : gcc (Ubuntu 7.3.0-16ubuntu3) 7.3.0
clang: 6.0.0 (self build)
cmake: 3.11.3
#include <string_view>

本次编译成功。

但是,可能使用的系统包含路径是/usr/include/

编译成功,因为gcc已经正式对应c++17,experimental没了。

我试过另一个。

sudo update-alternatives --config c++

它只识别 g++

如果使用 apt install clang 等安装软件包,系统数据库中的某些内容会更新吗?

因为是自建,可能无法识别。

请帮帮我。

【问题讨论】:

    标签: linux ubuntu cmake clang llvm


    【解决方案1】:

    如果你想要所有这些花哨的 c++1z 特性,你不仅需要支持它的编译器,还需要一个标准的 C++ 库。 Clang 选择它找到的任何库,并且恰好是 GCC 的库。

    尝试安装libc++ 并将-stdlib=libc++ 标志添加到CMAKE_CXX_FLAGS

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-14
      • 2014-07-28
      • 2016-05-11
      相关资源
      最近更新 更多