我正在使用arm-linux-androideabi-g++编译器.当我尝试编译一个简单的"你好,世界!" 程序编译好.当我通过在该代码中添加一个简单的异常处理来测试它时它也可以工作(添加之后-fexceptions..我猜它默认是禁用的).
这适用于Android设备,我只想使用CMake,而不是ndk-build.
例如 - first.cpp
#include <iostream>
using namespace std;
int main()
{
try
{
}
catch (...)
{
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
./arm-linux-androideadi-g++ -o first-test first.cpp -fexceptions
它没有问题......
问题 ...我试图用CMake文件编译文件.
我想添加-fexceptions标志.我试过了
set (CMAKE_EXE_LINKER_FLAGS -fexceptions ) or set (CMAKE_EXE_LINKER_FLAGS "fexceptions" )
Run Code Online (Sandbox Code Playgroud)
和
set ( CMAKE_C_FLAGS "fexceptions")
Run Code Online (Sandbox Code Playgroud)
它仍然显示错误.
我知道如何使用cmake命令传递编译器选项
set(CMAKE_CXX_FLAGS "-Wall -Wno-dev -Wl,-rpath=/home/abcd/libs/")
Run Code Online (Sandbox Code Playgroud)
是否还有任何方法可以从命令行传递选项,这将覆盖CMakeList.txt选项,类似于 -
cmake -Wl,-rpath=/home/abcd/newlibs/ path/to/CMakeLists.txt
Run Code Online (Sandbox Code Playgroud)
要么
cmake -D CMAKE_CXX_FLAGS="-Wno-dev -Wl,-rpath=/home/abcd/libs/" path/to/CMakeLists.txt
Run Code Online (Sandbox Code Playgroud)
我的主要问题是我想知道如何追加标志以及如何从命令行覆盖现有的编译器标志.
我CMake用来生成unix makefile.之后,我使用make实用程序编译项目.问题是我看不到任何警告!例如,这会导致干净的构建而不会发出警告:
#include <iostream>
class Foo
{
int first;
int second;
public:
Foo(int a, int b)
: second(a) // invalid initialization order
, first(b)
{
}
};
int main(int argc, char** argv)
{
int unused; // unused variable
int x;
double y = 3.14159;
x = y; // invalid cast
Foo foo(1,2);
std::cout << y << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
未使用的变量和有损变量 - 没有警告!我的CMakeLists.txt档案很简约:
cmake_minimum_required(VERSION 2.8)
add_executable(main main.cpp)
Run Code Online (Sandbox Code Playgroud)
当我运行cmake然后make我的输出看起来像这样:
[100%] Building …Run Code Online (Sandbox Code Playgroud) Visual Studio 2017提供完整的CMake集成.要了解这个组合,我从这个基本样本开始:
# CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(foo)
add_executable(foo foo.cpp)
Run Code Online (Sandbox Code Playgroud)
和
// foo.cpp
int main() {}
Run Code Online (Sandbox Code Playgroud)
这正确地生成了构建脚本,并且编译和链接没有任何问题.那很简单.
另一方面,试图设置编译器选项,结果却是微不足道的.在我的情况下,我试图将警告级别设置为4.
明显的解决方案
add_compile_options("/W4")
Run Code Online (Sandbox Code Playgroud)
没有像预期的那样平息.传递给编译器的命令行现在既包含/W4(按预期),也包含/W3(从其他地方获取),产生以下警告:
Run Code Online (Sandbox Code Playgroud)cl : Command line warning D9025: overriding '/W3' with '/W4'
要解决这个问题,我需要替换任何不兼容的编译器选项,而不是只添加一个.CMake没有为此提供任何直接支持,标准解决方案(正如此问答所示)似乎是:
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
Run Code Online (Sandbox Code Playgroud)
然而,这有两个问题:
CMAKE_CXX_FLAGS,适用于所有C++目标.这可能不是有意的(现在对我来说不是问题).我的问题是双重的:
/Wall选项,这也是不兼容的/W4. 我在我的项目中使用 GLAD,并使用 cmake 构建所有内容。
由于这是一个外部库而不是我的代码,我想在构建时完全抑制它的警告,因为我得到了很多这些:
warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
glad_glCullFace = ( PFNGLCULLFACEPROC ) load ( "glCullFace" );
^
Run Code Online (Sandbox Code Playgroud)
我该怎么做?我可以将它包含在我的源代码中,或者使用 GLAD 的源代码做一个 add_library,不管哪种方式。
谢谢
我正在尝试在 CMake 项目中启用警告。使用target_compile_options类似于此答案中建议的方法效果很好:
target_compile_options(mytarget PRIVATE $<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -pedantic>)
Run Code Online (Sandbox Code Playgroud)
我有很多目标,我想将这些设置应用于所有目标。所以,我尝试使用add_compile_options:
add_compile_options($<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -pedantic>)
Run Code Online (Sandbox Code Playgroud)
但是,当我使用它时,我看到编译器已通过"\$<1:-Wall" -Wextra "-pedantic>",就好像在扩展生成器表达式之前发生了空间分割一样。这会使编译器感到困惑并且构建失败。
我尝试引用以下论点add_compile_commands:
add_compile_options("$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -pedantic>")
Run Code Online (Sandbox Code Playgroud)
但是当我这样做时,编译器会传递一个"-Wall -Wextra -pedantic"参数,这也会使编译器感到困惑并导致构建失败。
我可以像这样“分发”生成器表达式:
add_compile_options(
$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall>
$<$<CXX_COMPILER_ID:GNU,Clang>:-Wextra>
$<$<CXX_COMPILER_ID:GNU,Clang>:-pedantic>
)
Run Code Online (Sandbox Code Playgroud)
这工作正常,解决了我眼前的问题......
……但是,问题仍然存在:是什么导致add_compile_options工作方式与target_compile_options这里不同?它们的字符串分割语义不应该是相同的吗?
我正在使用 boost、Qt 和其他库来开发一些应用程序并使用 cmake 作为我的 make 工具。为了更早地消除问题,我决定打开最强的警告标志(感谢mloskot)
if(MSVC)
# Force to always compile with W4
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR
"${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# Update if necessary
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic")
endif()
Run Code Online (Sandbox Code Playgroud)
到目前为止一切顺利,但这也会触发很多关于我正在使用的库的警告,是否可以通过 cmake 禁用特定文件夹、文件或库的警告?
编辑:我在谈论 3rd 方库的用法。示例是
G:\qt5\T-i386-ntvc\include\QtCore/qhash.h(81) : warning C4127: conditional expression is constant
G:\qt5\T-i386-ntvc\include\QtCore/qlist.h(521) : warning C4127: conditional expression is constant
G:\qt5\T-i386-ntvc\include\QtCore/qlist.h(511) : while compiling class template member function 'void QList<T>::append(const …Run Code Online (Sandbox Code Playgroud)