我想要一些关于我为编译我的项目而创建的CMakeLists.txt文件的反馈。我已经粘贴了CMakeLists以及下面的源代码。有一件事,我会特别感谢对我启用的消毒选项的反馈。是否还有更多的我应该启用和/或应该减少?我知道-fsanitize=address, -fsanitize=thread, and -fsanitize=memory组不能与其他人一起使用(根据clang文档)。与我选择的(address)组相比,其他组中的一组是否更愿意在第一次通过时使用?
还有--我正在使用的blob特性,我基于我读到的一个StackOverflow答案--我知道这不会检测到新的C源文件,我对此也没意见,但是除了这个微妙的细节之外,这是一个可以遵循的好方法吗?
CMakeLists.txt
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();
发布于 2019-01-02 22:13:48
我不熟悉Clang命令行选项,所以我不能给出任何反馈,但是关于CMake代码,我建议使用下面的CMakeLists.txt文件
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),而是通过以下方法显式地指定源代码文件
add_executable(${CMAKE_PROJECT_NAME} main.c)或
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_compile_features()target_compile_options()target_include_directories()target_link_libraries()target_link_options()到目前为止,FindCurses模块还不支持导入目标(2019年1月2日,CMake 3.13.2),因此需要按旧风格使用
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CURSES_INCLUDE_DIR})
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${CURSES_LIBRARIES})将来(当对CMake添加了对FindCurses中导入的目标的支持时),这两行应该替换为该行:
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE Curses::Curses)而不是设置CMake变量CMAKE_C_STANDARD
set(CMAKE_C_STANDARD 99)是使用target_compile_features()代替的良好实践
target_compile_features(${CMAKE_PROJECT_NAME} PRIVATE c_std_99)在这种情况下,这并没有什么实际的区别,但是对于只使用C++头的库,可以在接口中指定这样的编译特性。
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 生成器表达式
$<$:-Weverything -fsanitize=undefined,integer,implicit-conversion,nullability,address,leak,cfi -flto -fvisibility=default>被扩展到
-Weverything -fsanitize=undefined,integer,implicit-conversion,nullability,address,leak,cfi -flto -fvisibility=default当使用Clang编译器时,但对于其他编译器,则扩展为零。
当使用不受支持的C编译器时,不要设置CMake变量CMAKE_C_COMPILER,而是提供一个WARNING或FATAL_ERROR。
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编译器
mkdir /tmp/build
cd /tmp/build
CC=clang cmake -G Ninja ~/FirstProject
ninja -v如果希望看到正在运行的实际命令,请使用忍者命令行标志-v。
https://codereview.stackexchange.com/questions/210342
复制相似问题