【问题标题】:cmake c++11 flag not included when makefile is generated生成makefile时不包含cmake c++11标志
【发布时间】:2017-05-02 11:25:54
【问题描述】:

我有以下 CMakeLists 文件:

#################
# Com   Project # 
#################
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
SET(CMAKE_MODULE_PATH /home/loay/Desktop/V5)
SET(CMAKE_CXX_FLAGS "-std=c++11")
PROJECT (Sync)

FIND_PACKAGE (OpenSplice REQUIRED)

#####################
# Modele de donnees #
#####################

SET (idls 
 Communication.idl
)

# Extraction des fichiers a partir du .idl
execute_process(COMMAND idlpp -S -l cpp ./Communication.idl)

FOREACH(idl ${idls})
    OpenSplice_IDLGEN (${idl})
    STRING (REGEX REPLACE "\(.*\).idl" "\\1.cpp" VARS_1 ${idl})
    STRING (REGEX REPLACE "\(.*\).idl" "\\1.h" VARS_2 ${idl})
    STRING (REGEX REPLACE "\(.*\).idl" "\\1Dcps.cpp" VARS_3 ${idl})
    STRING (REGEX REPLACE "\(.*\).idl" "\\1Dcps.h" VARS_4 ${idl})
    STRING (REGEX REPLACE "\(.*\).idl" "\\1Dcps_impl.cpp" VARS_5 ${idl})
    STRING (REGEX REPLACE "\(.*\).idl" "\\1Dcps_impl.h" VARS_6 ${idl})
    STRING (REGEX REPLACE "\(.*\).idl" "\\1SplDcps.cpp" VARS_7 ${idl})
    STRING (REGEX REPLACE "\(.*\).idl" "\\1SplDcps.h" VARS_8 ${idl})
    STRING (REGEX REPLACE "\(.*\).idl" "ccpp_\\1.h" VARS_9 ${idl})
    SET(OpenSplice_SYNC ${OpenSplice_SYNC} ${VARS_1} ${VARS_2} ${VARS_3} ${VARS_4} ${VARS_5} ${VARS_6} ${VARS_7} ${VARS_8} ${VARS_9})
ENDFOREACH(idl)

###########################
# Fichiers de code source #
###########################
SET (APP_SOURCES
 arduino.cpp
 Controller.cpp
 CheckStatus.cpp
 Controller.cpp
 ListenerReader.cpp
 main.cpp
 Publisher.cpp
 Subscriber.cpp
 rs232.c
)

# Inclure dossier des sources des librairies a linker
INCLUDE_DIRECTORIES(
 ${OpenSplice_INCLUDE_DIRS}
)

# Inclure dossier des binaires des librairies a linker
link_directories (
 ${LIBRARY_OUTPUT_PATH}
)


#############################
# Construction des binaires #
#############################
SET (APP_EXE start)
SET (SYNC Sync)

ADD_EXECUTABLE (${APP_EXE} ${APP_SOURCES})
ADD_LIBRARY (${SYNC} SHARED ${OpenSplice_SYNC})

ADD_DEFINITIONS (
 ${OpenSplice_DEFINITIONS}
 ${DEFINITIONS}
)

TARGET_LINK_LIBRARIES (${SYNC} 
 ${OpenSplice_LIBRARIES}
)

TARGET_LINK_LIBRARIES (${APP_EXE}
 ${OpenSplice_LIBRARIES}
 ${SYNC} 
)

如您所见,我添加了这一行 SET(CMAKE_CXX_FLAGS "-std=c++11") 以启用对 ISO c++ 2011 的支持。我运行这个命令cmake . -G "Unix Makefiles" 来生成我需要的文件并生成makefile。

问题是当我运行make 命令时它失败并出现以下错误:

错误:#error 此文件需要对 ISO C++ 2011 标准的编译器和库支持。此支持目前处于试验阶段,必须使用 -std=c++11 或 -std=gnu++11 编译器选项启用。

这很奇怪,因为我确实包含了标志。更奇怪的是,当我重新运行cmake . -G "Unix Makefiles" 时,这个问题得到了解决,我能够毫无错误地构建我的文件!

这个问题的原因可能是什么?

【问题讨论】:

  • 你使用的是哪个编译器(有版本)?
  • @PaulFloyd gcc 4.8.5
  • 好的,以后的g++版本默认为C++ 14。4.8.5默认为C++ 03。
  • @PaulFloyd 感谢您提供的信息
  • 2.6这样古老的CMake你要支持吗?从 3.1 版开始,CMake 具有变量CMAKE_CXX_STANDARD(加上相关的CMAKE_CXX_STANDARD_REQUIRED 和CMAKE_CXX_EXTENSIONS),它们在本机CMake 级别控制它。有了这些,您就不必手动检查标志了。

标签: c++ c++11 makefile cmake


【解决方案1】:

可能它在其他地方被覆盖,因为这个 CMake 文件不是来自 PrismTech 的官方文件。将该命令更改为:

set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")

并将其放在 cmake 文件的末尾。

【讨论】:

  • 成功了,谢谢!为什么我必须把它放在文件的末尾?一开始我试着把它放在乞讨的地方,但它没有用,为什么?
  • @LoayAshmawy 首先,请注意您的set 命令会覆盖所有以前的CMAKE_CXX_FLAGS,这与我提供的附加到它的命令不同。就像我说的,这不是 PrismTech 的官方 CMake 文件。有人创造了它。可能他在某处确实像您一样并覆盖了CMAKE_CXX_FLAGS,这将有效地导致删除您在开头放置的c++11 标志。当您将此添加到文件末尾时,您将附加到他之前所做的任何事情。
【解决方案2】:

在project() 调用之前或之后设置编译器标志存在差异。

  1. 当设置标志之前 project() 通常会调用你重新定义默认标志:

    set(CMAKE_CXX_FLAGS_INIT "<new-value>" CACHE STRING
       "Flags used by the compiler during all build types.")
    # ... some other assignments may be here ...
    project(<project-name>)
    

    注意 _INIT 变量的后缀:实际上标志是在project() 调用的那一刻初始化的,CMAKE_CXX_FLAGS_INIT 提供默认值他们的价值。

  2. 当设置标志之后 project() 通常会追加到默认或用户提供的标志:

    project(<project-name>)
    # ...
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} <additional-value>")
    

【讨论】:

  • 感谢您的信息!!
猜你喜欢
  • 2015-11-14
  • 1970-01-01
  • 2016-07-08
  • 2012-10-02
  • 2014-07-12
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多