我的情况

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

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



当前的项目

该项目只是一个示例,简化为一个应用程序和一个库项目。目标是
有多个客户端和一个以上的库(某些依赖于彼此)。

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

该图显示了项目结构(Visual Studio Code Explorer的屏幕截图)



在include文件夹中有一个类似于项目的文件夹,用于更改Core.h中的includes
Core/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();
}


Core\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


Core\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")


Core\include\CMakeLists.txt

ADD_SUBDIRECTORY("Core")


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.标有A的CMakeLists为空。他们只是添加,以便每个目录
有一个CMakeLists文件。我应该删除它们吗?

2.我想在我的项目中使用google-test / mock,并为每个项目使用测试
project/test文件夹。我足以在顶级CMakeList中包含google test来做到这一点
工作还是我必须将其包含在每个子项目中?

3.列出源文件或自动加载它们是一种好习惯吗?我认为清单
即使需要更多工作,它们也会更好。我认为这在重新加载时对于cmake也具有优势
该项目。测试也是如此吗?我正在考虑为每个来源制作一个测试文件
文件。

最佳答案

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

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

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

恕我直言,最优雅的解决方案是使用
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/

10-11 23:07
查看更多