如何用CMake构建含同级client与common目录的可执行文件?编译报错求助
Fixing CMake Build Error: No rule to make target '../common'
Let's break down what's causing your build error and fix the CMakeLists.txt step by step.
Root Cause of the Error
The main issues in your current script are:
- You tried to link a directory path (
${common_dir}) intarget_link_libraries, which CMake interprets as a target it needs to build—hence the "No rule to make target '../common'" error. - The
add_library(common_src)line is incomplete: you didn't provide the source files for the common library. - You're mixing two approaches for common sources (adding them directly to the executable and creating a library for them) which creates confusion.
Corrected CMakeLists.txt
Here's the fixed version that builds your executable properly, using a clean library-based approach for common code:
cmake_minimum_required(VERSION 3.1.0) project(Client) set(common_dir ${PROJECT_SOURCE_DIR}/common) include_directories(${common_dir}) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Enforce the C++17 standard set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) # Remove redundant -std=c++17 flag (CMAKE_CXX_STANDARD already handles this) # set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") if (CMAKE_BUILD_TYPE STREQUAL "RELEASE") add_definitions(-DQT_NO_DEBUG_OUTPUT) endif() if(CMAKE_VERSION VERSION_LESS "3.7.0") set(CMAKE_INCLUDE_CURRENT_DIR ON) endif() IF(WIN32) SET(OS_SPECIFIC_LIBS netapi32 wsock32) ENDIF() # Group Qt component lookup for readability find_package(Qt5 COMPONENTS Core Widgets Gui Network Svg PrintSupport WebSockets REQUIRED) # Gather source files file(GLOB client_src "*.h" "*.cpp" "Resources.qrc") file(GLOB common_src "${common_dir}/*.h" "${common_dir}/*.cpp") # Create a static library for common code (fixes the incomplete add_library call) add_library(common_lib STATIC ${common_src}) # Link common library against Qt dependencies it may use target_link_libraries(common_lib Qt5::Core Qt5::Network) # Build the client executable, link against common library and Qt components add_executable(Client ${client_src}) target_link_libraries(Client common_lib Qt5::Core Qt5::Widgets Qt5::Gui Qt5::Network Qt5::Svg Qt5::PrintSupport Qt5::WebSockets ${OS_SPECIFIC_LIBS} )
Key Modifications Explained
- Fixed common library setup: Changed
add_library(common_src)toadd_library(common_lib STATIC ${common_src})—this properly creates a static library from your common directory sources with a clear, usable target name. - Removed invalid directory link: Took
${common_dir}out oftarget_link_libraries—we now link against thecommon_libtarget instead of a directory path. - Linked common library to Qt: Added
target_link_libraries(common_lib Qt5::Core Qt5::Network)to ensure any Qt-dependent code in your common sources has access to required libraries. - Cleaned up C++ standard: Removed the redundant
-std=c++17flag (handled byCMAKE_CXX_STANDARD) and addedCMAKE_CXX_STANDARD_REQUIRED ONto enforce compliance. - Simplified Qt lookup: Grouped all Qt components into a single
find_packagecall for better readability.
Alternative: Compile All Sources Directly
If you don't want a separate library for common code, you can simplify the script to compile all sources directly into the executable:
# ... keep all setup code above ... # Gather all sources in one go file(GLOB all_sources "*.h" "*.cpp" "Resources.qrc" "${common_dir}/*.h" "${common_dir}/*.cpp" ) add_executable(Client ${all_sources}) target_link_libraries(Client Qt5::Core Qt5::Widgets Qt5::Gui Qt5::Network Qt5::Svg Qt5::PrintSupport Qt5::WebSockets ${OS_SPECIFIC_LIBS} )
Note: Using file(GLOB) can miss new files added later—for more robust builds, consider listing sources explicitly instead of relying on glob patterns.
内容的提问来源于stack exchange,提问作者Antonio Santoro
相关产品推荐
相关产品推荐

