首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ncurses程序的CMakeLists和Clang消毒选项

ncurses程序的CMakeLists和Clang消毒选项
EN

Code Review用户
提问于 2018-12-26 06:23:33
回答 1查看 271关注 0票数 0

我想要一些关于我为编译我的项目而创建的CMakeLists.txt文件的反馈。我已经粘贴了CMakeLists以及下面的源代码。有一件事,我会特别感谢对我启用的消毒选项的反馈。是否还有更多的我应该启用和/或应该减少?我知道-fsanitize=address, -fsanitize=thread, and -fsanitize=memory组不能与其他人一起使用(根据clang文档)。与我选择的(address)组相比,其他组中的一组是否更愿意在第一次通过时使用?

还有--我正在使用的blob特性,我基于我读到的一个StackOverflow答案--我知道这不会检测到新的C源文件,我对此也没意见,但是除了这个微妙的细节之外,这是一个可以遵循的好方法吗?

CMakeLists.txt

代码语言:javascript
复制
cmake_minimum_required(VERSION 3.13)
project(FirstProject C)

find_package(Curses REQUIRED)
include_directories(${CURSES_INCLUDE_DIR})

set(CMAKE_C_COMPILER clang)
set(CMAKE_C_STANDARD 99)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Weverything -fsanitize=undefined,integer,implicit-conversion,nullability,address,leak,cfi -flto -fvisibility=default")

FILE(GLOB Sources *.c)
add_executable(${CMAKE_PROJECT_NAME} ${Sources})
target_link_libraries(${CMAKE_PROJECT_NAME} ${CURSES_LIBRARIES})

main.c (代码来自这里)

# #include #include #include #include #include #include #include #include // https://stackoverflow.com/a/10536254 #define ULL_DIGITS (3 *sizeof of (无符号的long)) #define ERR_MSG_MAX_LENGTH 32 #define NUL '\0‘#define NUL_SIZE 1 int ask_ull(无符号的long *result,const char *提示符);/** *打印提示符,然后使用ncurses读取未签名的long long。*在成功时返回0。在失败时返回errno,设置为* ERANGE、EDOM或EIO。*/ int ask_ull(无符号长*结果,const *提示){ char;char *endptr;printw("%s",提示);getnstr(buf,ULL_DIGITS);* == =strtoull(==ERANGE,10);if (errno == ERANGE) { // ==溢出或欠流返回错误;}如果(endptr == buf \ strchr(buf,'-')) { //不成功的转换errno = EDOM;返回errno;} while (isspace (*endptr) endptr++;if (*endptr){ //尾垃圾errno = EIO;返回errno;} errno = 0;返回errno;} int main(void) {无符号长的长高度、宽度、长度;高度=宽度=长度= 0;char errmsg;errmsg = NUL;initscr();printw(“-体积计算器-\n”);if (!ask_ull(& length,“输入长度:")) { sscanf(errmsg,"%s",”无法扫描长度“);} if (!ask_ull(&ask_ull,“输入宽度:")) { sscanf (errmsg,"%s",”无法扫描宽度“);} if (!ask_ull(&ask_ull,”输入高度:")) { sscanf(errmsg,"%s",“无法扫描高度”);} if (errmsg != NUL) {刷新();endwin();perror(errmsg);返回errno;}无符号长卷=长度*宽度*高度;printw(卷:%llu,卷);refresh();getch();endwin();

EN

回答 1

Code Review用户

回答已采纳

发布于 2019-01-02 22:13:48

我不熟悉Clang命令行选项,所以我不能给出任何反馈,但是关于CMake代码,我建议使用下面的CMakeLists.txt文件

代码语言:javascript
复制
cmake_minimum_required(VERSION 3.13)
project(FirstProject C)

find_package(Curses REQUIRED)

add_executable(${CMAKE_PROJECT_NAME} main.c)

target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CURSES_INCLUDE_DIR})
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${CURSES_LIBRARIES})

if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
  message(WARNING "Use the Clang compiler instead. "
                  "FirstProject officially supports Clang "
                  "(although other compilers might work).") 
endif()       

target_compile_features(${CMAKE_PROJECT_NAME} PRIVATE c_std_99)
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE
  $<$:
    -Weverything
    -fsanitize=undefined,integer,implicit-conversion,nullability,address,leak,cfi
    -flto
    -fvisibility=default>)
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
  $<$:
    -fsanitize=undefined,integer,implicit-conversion,nullability,address,leak,cfi
    -flto>)

关于

的一些评论

避免使用文件指定源代码文件

避免使用FILE(GLOB),而是通过以下方法显式地指定源代码文件

代码语言:javascript
复制
add_executable(${CMAKE_PROJECT_NAME} main.c)

代码语言:javascript
复制
add_executable(${CMAKE_PROJECT_NAME})
target_sources(${CMAKE_PROJECT_NAME} PRIVATE main.c)

https://stackoverflow.com/questions/32411963/why-is-cmake-file-glob-evil也是Śee

使用target_*命令

避免

相反,使用

到目前为止,FindCurses模块还不支持导入目标(2019年1月2日,CMake 3.13.2),因此需要按旧风格使用

代码语言:javascript
复制
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CURSES_INCLUDE_DIR})
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${CURSES_LIBRARIES})

将来(当对CMake添加了对FindCurses中导入的目标的支持时),这两行应该替换为该行:

代码语言:javascript
复制
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Curses::Curses)

而不是设置CMake变量CMAKE_C_STANDARD

代码语言:javascript
复制
set(CMAKE_C_STANDARD 99)

是使用target_compile_features()代替的良好实践

代码语言:javascript
复制
 target_compile_features(${CMAKE_PROJECT_NAME} PRIVATE c_std_99)

在这种情况下,这并没有什么实际的区别,但是对于只使用C++头的库,可以在接口中指定这样的编译特性。

代码语言:javascript
复制
 add_library(myheaderonly INTERFACE)
 target_compile_features(headeronlylib INTERFACE cxx_std_11)

为库的使用者提供使用要求(也请参阅https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html)

添加target_link_options()行是为了能够构建可执行文件。(我不确定这是正确的)。

使用生成器表达式

The 生成器表达式

代码语言:javascript
复制
$<$:-Weverything -fsanitize=undefined,integer,implicit-conversion,nullability,address,leak,cfi -flto -fvisibility=default>

被扩展到

代码语言:javascript
复制
-Weverything -fsanitize=undefined,integer,implicit-conversion,nullability,address,leak,cfi -flto -fvisibility=default

当使用Clang编译器时,但对于其他编译器,则扩展为零。

避免设置CMAKE_C_COMPILER

当使用不受支持的C编译器时,不要设置CMake变量CMAKE_C_COMPILER,而是提供一个WARNINGFATAL_ERROR

代码语言:javascript
复制
if(NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
  message(WARNING "Use the Clang compiler instead. FirstProject officially supports Clang (although other compilers might work).") 
endif()       

(WARNING可由FATAL_ERROR取代,以防止使用除Clang之外的任何其他C编译器)

要编译该项目,请使用环境变量CC指定C编译器

代码语言:javascript
复制
mkdir /tmp/build
cd /tmp/build
CC=clang cmake -G Ninja ~/FirstProject
ninja -v

如果希望看到正在运行的实际命令,请使用忍者命令行标志-v

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/210342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档