c++ - 多项目 cmake 不工作

标签 c++ cmake directory-structure

我的情况

我正在尝试使用 cmake 设置项目结构和构建脚本,但出现错误 我的应用程序无法找到我尝试包含的头文件。

我希望有人能指导我解决这个问题。


当前项目

该项目只是一个示例,简化为一个应用程序和一个库项目。目标是 有多个客户端和多个库(有些相互依赖)。

clients/Desktop 例如是一个使用 core/ 库的应用程序。

图像显示了项目结构(来自 Visual Studio Code 资源管理器的屏幕截图)

d

在包含文件夹中有一个像项目一样命名的文件夹是将包含从 Core.hCore/Core.h。或者至少这是计划。也许这就是问题所在?

好的,现在是代码:

clients\Desktop\src\main.cpp:

#include "Core/Core.h"

#include <iostream>

int main(int argc, char* argv[]) {
    ProjectStructure::Core::Example ex;
    ex.sayHello();
}

核心\include\Core\Core.h:

#ifndef PROJECTSTRUCTURE_CORE_CORE_H
#define PROJECTSTRUCTURE_CORE_CORE_H

#include <iostream>

namespace ProjectStructure {
namespace Core {

class Example {
public:
    void sayHello();
};

} // namespace Core
} // namespace ProjectStructure 

#endif

核心\src\Core.cpp:

#include "Core/Core.h"

namespace ProjectStructure {
namespace Core {

void Example::sayHello() {
    std::cout << "Hello world.";
}

} // namespace Core
} // namespace ProjectStructure

clients\Desktop\include\CMakeLists.txt:

ADD_SUBDIRECTORY("Desktop")

clients\Desktop\src\CMakeLists.txt:

SET(APP_HEADERS
)

SET(APP_SOURCES
"main.cpp"
)

# Make executable
ADD_EXECUTABLE("${PROJECT_NAME}" "${APP_SOURCES}")
TARGET_LINK_LIBRARIES("${PROJECT_NAME}" "Core")

clients\Desktop\CMakeLists.txt:

# Version check
cmake_minimum_required(VERSION 3.5)

# Project
PROJECT("Desktop" CXX)

INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include")

ADD_SUBDIRECTORY("include")
ADD_SUBDIRECTORY("src")
ADD_SUBDIRECTORY("test")

clients\CMakeLists.txt:

# Executables
ADD_SUBDIRECTORY("${PROJECTSTRUCTURE_CLIENTS_DIR}/Desktop")

核心\include\CMakeLists.txt:

ADD_SUBDIRECTORY("Core")

核心\src\CMakeLists.txt:

SET(LIB_HEADERS
"../include/Core/Core.h"
)

SET(LIB_SOURCES
"Core.cpp"
)

# Make library
ADD_LIBRARY("${PROJECT_NAME}" STATIC "${LIB_SOURCES}")

SET_TARGET_PROPERTIES("${PROJECT_NAME}" PROPERTIES
FRAMEWORK FALSE
PUBLIC_HEADER "${LIB_HEADERS}"
)

INSTALL(TARGETS "${PROJECT_NAME}"
EXPORT "${PROJECT_NAME}Targets"
ARCHIVE DESTINATION lib COMPONENT libs
RUNTIME DESTINATION bin COMPONENT libs
LIBRARY DESTINATION lib COMPONENT libs
PUBLIC_HEADER DESTINATION include/${PROJECT_NAME} COMPONENT devel
INCLUDES DESTINATION include
)

Core\CMakeLists.txt:

# Version check
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)

# Project
PROJECT("Core" CXX)

INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include")

ADD_SUBDIRECTORY("include")
ADD_SUBDIRECTORY("src")
ADD_SUBDIRECTORY("test")

最后但同样重要的是顶级 CMakeLists.txt:

# Version check
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)

# Project
PROJECT("ProjectStructure" CXX)

# Status
MESSAGE(STATUS "Cmake running...")
MESSAGE(STATUS "System: ${CMAKE_SYSTEM}")
MESSAGE(STATUS "System: ${CMAKE_SYSTEM_PROCESSOR}") 
MESSAGE(STATUS "Cmake-Version: ${CMAKE_VERSION}")
MESSAGE(STATUS "C++ compiler: ${CMAKE_CXX_COMPILER}")

# Project structure
SET(CMAKE_INCLUDE_PATH "${CMAKE_SOURCE_DIR}/include")

SET(CMAKE_BINARY_DIR "${CMAKE_SOURCE_DIR}/build")
SET(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}")
SET(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}")

SET(PROJECTSTRUCTURE_CLIENTS_DIR "${CMAKE_SOURCE_DIR}/clients")

# Prohibit in source builds
IF("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
MESSAGE(SEND_ERROR "In-source builds are not allowed. Remove generated files.")
ENDIF()

# Output settings
SET(CMAKE_VERBOSE_MAKEFILE ON)
SET(CMAKE_COLOR_MAKEFILE   ON)

# Build mode
SET(CMAKE_BUILD_TYPE Debug)                      # Dev
#SET(CMAKE_BUILD_TYPE RelWithDebInfo)            # Test
#SET(CMAKE_BUILD_TYPE Release)                   # Release

# Used features
SET(CMAKE_CXX_STANDARD 14) # -std=c++14
SET(CMAKE_CXX_STANDARD_REQUIRED ON)

# Compiler flags
SET(CMAKE_CXX_FLAGS "-Wall -Wextra")
SET(CMAKE_CXX_FLAGS_DEBUG "-g3 -O0")             # Dev
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3")        # Test
SET(CMAKE_CXX_FLAGS_RELEASE "-O3")               # Release

# Libraries
ADD_SUBDIRECTORY("${CMAKE_SOURCE_DIR}/core")

# Executables
ADD_SUBDIRECTORY("${PROJECTSTRUCTURE_CLIENTS_DIR}")

我正在使用以下命令使用源代码构建:

cd build
cmake .. -G "MSYS Makefiles"

然后运行使用:

make

注意:真正的项目还包含文档和其他一些东西的目录。 还有像 .gitignore.travis.yml 这样的文件(但那是我接下来要做的事情)。


问题:

cmake 命令正在运行,但 make 命令告诉我包含的文件 (Core.h) 可以 找不到。
我认为问题出在安装库的部分。但我无法找到 正确的方法。我在此处发布的解决方案只是我尝试过的众多解决方案中的一个。


其他问题:

1. 标有ACMakeLists 是空的。他们刚刚添加的地方,以便每个目录 有一个 CMakeLists 文件。我应该删除它们吗?

2. 我想在我的项目中使用 google-test/mock 来测试 project/test 文件夹。我足以在顶级 CMakeLists 中包含 google test 来完成这个 工作还是我必须将它包含在每个子项目中?

3. 列出源文件或自动加载它们是好的做法吗?我觉得上市 即使工作更多,它们也会更好。我认为这对 cmake 在重新加载时也有好处 该项目。测试也是如此吗?我正在考虑为每个来源制作一个测试文件 文件。

最佳答案

这似乎不是安装部分的问题。我认为您添加包含目录的方式有问题。 :)

当您使用 INCLUDE_DIRECTORIES 时,您说 cmake 应该为这个 CMakeLists 中的文件的编译器添加适当的标志。但不在父 CMakeLists 中添加的文件中。我认为堆栈是这种情况的一个很好的类比。 ( https://cmake.org/cmake/help/v3.5/command/include_directories.html )

请注意,您在 ./CMakeLists.txt 中添加了 ./Core/CMakeLists.txt:ADD_SUBDIRECTORY("${CMAKE_SOURCE_DIR}/core"), ./Core/include 稍后添加 clients 子目录时不再使用。

恕我直言,最优雅的解决方案是使用 TARGET_INCLUDE_DIRECTORIES(Core PUBLIC pathToCoresHeaders) 代替。如果您决定使用它,TARGET_LINK_LIBRARIES("${PROJECT_NAME}""Core") 行将为桌面可执行文件添加正确的包含路径。

AD1。是的,我认为你应该删除它们。您可以将 CMakeLists.txt 留在 test 的目录中,因为它通常需要一个更多的 UT 目标。

AD2。我建议在您开始定义自己的目标之前将它添加到顶级目录中,并将您的测试执行程序与 gtestgtest_main 链接,这应该注册 gtest 的包含路径。

AD3。我在 cmake 中列出了我所有的文件。我宁愿在构建结束时看到有关丢失文件的错误,也不愿看到未解析的外部符号。但它不是黑白的(Specify source files globally with GLOB?)。您应该做出自己的决定并承担后果。

PS1。我建议在一些类似 unix 的系统上额外测试您的构建,因为 Windows 在不区分大小写方面过于宽松。

我会做一些更改来改进您的构建系统。

./Core/CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.5)

PROJECT(Core CXX)

SET(INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include)
SET(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)

SET(LIB_HEADERS
    ${INCLUDE_DIRS}/Core/Core.h
)

SET(LIB_SOURCES
    ${SOURCE_DIR}/Core.cpp
)

# Make library
ADD_LIBRARY("${PROJECT_NAME}" STATIC ${LIB_SOURCES} ${LIB_HEADERS})

TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME}
    PUBLIC ${INCLUDE_DIRS}
)

SET_TARGET_PROPERTIES("${PROJECT_NAME}" PROPERTIES
FRAMEWORK FALSE
PUBLIC_HEADER "${LIB_HEADERS}"
)

INSTALL(TARGETS "${PROJECT_NAME}"
EXPORT "${PROJECT_NAME}Targets"
ARCHIVE DESTINATION lib COMPONENT libs
RUNTIME DESTINATION bin COMPONENT libs
LIBRARY DESTINATION lib COMPONENT libs
PUBLIC_HEADER DESTINATION include/${PROJECT_NAME} COMPONENT devel
INCLUDES DESTINATION include
)

ADD_SUBDIRECTORY(test)

./clients/Desktop/CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project("Desktop" CXX)

SET(SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src)
SET(INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)

SET(APP_HEADERS
)

SET(APP_SOURCES
    ${SOURCE_DIR}/main.cpp
)

# Make executable
ADD_EXECUTABLE(${PROJECT_NAME} ${APP_SOURCES} ${APP_HEADERS})
TARGET_INCLUDE_DIRECTORIES(${PROJECT_NAME} PRIVATE ${INCLUDE_DIR})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} Core)

add_subdirectory(test)

关于c++ - 多项目 cmake 不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36816839/

相关文章:

c# - 在 .NET 中移动不同卷上的文件

python - 使用客户端和服务器部分构建 Python 应用程序

c++ - Conan + CMake + C++ : Linking against Boost. 记录静态库失败

c++ - 连接 Leap Motion SDK 和 Cmake

c++ - 使用Tracker-API从网络摄像头跟踪对象,但未定义error:cap

c++ - 将结构数组作为参数传递给函数

android - 将 OpenBR 编译为 ArmV7 - Android 工具链问题

mysql - 不同品类的数据库结构设计

c++ - 如何彻底改变 QAbstractTableModel 的底层数据?

c++ - 什么在 CUDA : global memory write + __threadfence() or atomicExch() to global memory? 中更快