如何让CMake FetchContent拉取的C++第三方库不显示编译警告?
解决wxWidgets依赖编译警告混杂问题
问题背景
使用CMake的FetchContent模块拉取wxWidgets(v3.1.4)开发C++20项目,静态链接依赖可正常编译运行,但编译时wxWidgets自身的警告与项目代码警告混杂(VS Code中超过一千条),难以排查自有代码的问题。
当前CMake脚本
cmake_minimum_required(VERSION 3.11 FATAL_ERROR) project(my_project LANGUAGES CXX) # Using C++20 set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Use wxWidgets static libraries set(wxWidgets_USE_STATIC 1) set(wxBUILD_SHARED OFF) # Include FetchContent module include(FetchContent) # Fetch wxWidgets dependency statement declaration FetchContent_Declare( wxWidgets GIT_REPOSITORY https://github.com/wxWidgets/wxWidgets.git GIT_TAG v3.1.4 ) # Message to inform user that script is not bugged, just busy resolving dependecy message(STATUS "Baixando wxWidgets e incluindo-o no projeto") # Effectively fetch wxWidgets dependency FetchContent_GetProperties(wxWidgets) if(NOT wxWidgets_POPULATED) FetchContent_Populate(wxWidgets) add_subdirectory(${wxwidgets_SOURCE_DIR} ${wxwidgets_BUILD_DIR}) endif() # Include all of the program's header and source files file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_LIST_DIR}/include/*.h) file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_LIST_DIR}/source/*.cpp) # Create program executable and link against all of the program's header and source files add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS}) # Link wxWidgets libraries against program executable target_include_directories(${PROJECT_NAME} PRIVATE ${wxwidgets_SOURCE_DIR}/include) target_link_libraries(${PROJECT_NAME} PRIVATE wx::base wx::core) # Copy all assets to build directory to make them available to the program add_custom_target(copy_assets COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/assets ${CMAKE_CURRENT_BINARY_DIR}/assets ) add_dependencies(${PROJECT_NAME} copy_assets)
解决方案
1. 修正FetchContent变量大小写错误
FetchContent_Declare指定的名称是wxWidgets,因此生成的变量名应为大写开头:wxWidgets_SOURCE_DIR(源目录)和wxWidgets_BINARY_DIR(构建目录)。原脚本中的小写变量名在大小写敏感的系统(如Linux)会导致路径错误,需修正:
if(NOT wxWidgets_POPULATED) FetchContent_Populate(wxWidgets) add_subdirectory(${wxWidgets_SOURCE_DIR} ${wxWidgets_BINARY_DIR}) endif()
2. 隔离警告:仅对自有代码启用警告
通过以下三步实现警告隔离:
- 编译wxWidgets时临时关闭所有警告
- 将wxWidgets头文件标记为系统头文件,避免编译器触发包含警告
- 为自有代码明确设置警告规则
修改后的完整CMake脚本
cmake_minimum_required(VERSION 3.11 FATAL_ERROR) project(my_project LANGUAGES CXX) # Using C++20 set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Use wxWidgets static libraries set(wxWidgets_USE_STATIC 1) set(wxBUILD_SHARED OFF) # Include FetchContent module include(FetchContent) # Fetch wxWidgets dependency statement declaration FetchContent_Declare( wxWidgets GIT_REPOSITORY https://github.com/wxWidgets/wxWidgets.git GIT_TAG v3.1.4 ) # Message to inform user that script is not bugged, just busy resolving dependecy message(STATUS "Baixando wxWidgets e incluindo-o no projeto") # Effectively fetch wxWidgets dependency FetchContent_GetProperties(wxWidgets) if(NOT wxWidgets_POPULATED) FetchContent_Populate(wxWidgets) # 保存当前警告设置,临时关闭wxWidgets编译警告 set(OLD_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) set(OLD_CMAKE_CXX_WARNING_LEVEL ${CMAKE_CXX_WARNING_LEVEL}) if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") # MSVC: 关闭警告 string(REPLACE "/W4" "/W0" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") else() # GCC/Clang: 关闭所有警告 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w") endif() set(CMAKE_CXX_WARNING_LEVEL 0) add_subdirectory(${wxWidgets_SOURCE_DIR} ${wxWidgets_BINARY_DIR}) # 恢复原有警告设置 set(CMAKE_CXX_FLAGS ${OLD_CMAKE_CXX_FLAGS}) set(CMAKE_CXX_WARNING_LEVEL ${OLD_CMAKE_CXX_WARNING_LEVEL}) endif() # Include all of the program's header and source files file(GLOB_RECURSE HEADERS ${CMAKE_CURRENT_LIST_DIR}/include/*.h) file(GLOB_RECURSE SOURCES ${CMAKE_CURRENT_LIST_DIR}/source/*.cpp) # Create program executable and link against all of the program's header and source files add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS}) # 为自有代码启用严格警告 target_compile_options(${PROJECT_NAME} PRIVATE $<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wpedantic> $<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Wpedantic> $<$<CXX_COMPILER_ID:MSVC>:/W4> ) # Link wxWidgets libraries against program executable # 将wxWidgets头文件标记为系统头文件,忽略包含时的警告 target_include_directories(${PROJECT_NAME} PRIVATE SYSTEM ${wxWidgets_SOURCE_DIR}/include) target_link_libraries(${PROJECT_NAME} PRIVATE wx::base wx::core) # Copy all assets to build directory to make them available to the program add_custom_target(copy_assets COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/assets ${CMAKE_CURRENT_BINARY_DIR}/assets ) add_dependencies(${PROJECT_NAME} copy_assets)
3. 确认静态链接设置的正确性
你当前的静态链接配置是正确的:
set(wxWidgets_USE_STATIC 1)和set(wxBUILD_SHARED OFF)会告诉wxWidgets的CMake脚本构建静态库- 链接
wx::base和wx::core目标时,CMake会自动使用静态库版本
内容的提问来源于stack exchange,提问作者Lucas Yotsui
相关产品推荐
相关产品推荐

