【问题标题】:CMake build problems under Visual StudioVisual Studio下的CMake构建问题
【发布时间】:2017-07-29 11:57:06
【问题描述】:

首先,我是 CMake 新手。

文件夹结构

root_project
  |─── CMakeLists.txt
  |─── build
  |─── Project 1
  |      |─── build
  |      |      |─── Debug
  |      |      └─── Release
  |      |─── CMakeLists.txt
  |      |─── source
  |      |      └─── include
  |      |─── resource
  |      └─── header
  └─── Project 2
         |─── build
         |      |─── Debug
         |      └─── Release
         |─── source
         |      |─── CMakeLists.txt
         |      └─── include
         |─── resource
         └─── header

CMake 文件

root_project 的 CMakeLists.txt:

# Specify the minimum version for CMake
cmake_minimum_required(VERSION 3.8.2 FATAL_ERROR)

# Project's name
project("RootProject X")

IF(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
    message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt.")
ENDIF()

OPTION(BUILD_TESTS "Decides whether the unit tests will be built." ON)

# C/C++ languages required.
enable_language(C)
enable_language(CXX)

set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Only allow 64bit architecture
IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
    # 64bit
    message(STATUS "Compiling for x86-64 platform. Proceeding...")
ELSEIF(CMAKE_SIZEOF_VOID_P EQUAL 4)
    # 32bit
    message(FATAL_ERROR "Compiling for x86 platform. This is not supported. Aborting...")
ELSE()
    # unidentified architecture
    message(FATAL_ERROR "Running on unidentified architecture. This is not supported. Aborting...")
ENDIF()

# Abort when OpenGL is not found
FIND_PACKAGE(OpenGL 4.5 REQUIRED)

IF(NOT VULKAN_FOUND)
    message(WARNING "Could not find Vulkan library.")
ENDIF()

# Add the modules
add_subdirectory("Project 1")
add_subdirectory("Project 2")

项目 1 的 CMakeLists:

# Specify the minimum version for CMake
cmake_minimum_required(VERSION 3.8.2 FATAL_ERROR)

project("Project 1")

# Set the version number of the project here
set(VERSION_MAJOR "0")
set(VERSION_MINOR "1")
set(VERSION_PATCH "0")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})

find_package(OpenGL 4.5 REQUIRED)

include_directories(${OPENGL_INCLUDE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/sources/third-party-include/)
link_libraries(${OPENGL_gl_LIBRARY})
add_definitions(${OpenGL_DEFINITIONS})

#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/sources/include/)

# ToDo: Testing
set(HEADERS
    ${CMAKE_CURRENT_SOURCE_DIR}/sources/include/Engine.h
)

set(SOURCES
    ${CMAKE_CURRENT_SOURCE_DIR}/source/Engine.cpp
)

source_group(headers FILES ${HEADERS})
source_group(sources FILES ${SOURCES})

if(WIN32)
# currently add_executable for testing purpose
add_executable("Project 1" WIN32
    #${HEADERS}
    ${SOURCES}
)
ELSEIF(UNIX AND NOT APPLE)
add_library("Project 1"
    ${HEADERS}
    ${SOURCES}
)
ELSE()
# The system is not supported
message(FATAL_ERROR "System not supported.")
ENDIF()

target_link_libraries(DarkEngine ${OPENGL_gl_LIBRARY})

项目 2 的 CMakeLists:

# Specify the minimum version for CMake
cmake_minimum_required(VERSION 3.8.2 FATAL_ERROR)

project("Project 2")

# Set the version number of the project here
set(VERSION_MAJOR "0")
set(VERSION_MINOR "1")
set(VERSION_PATCH "0")
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})

set(HEADERS

)

set(SOURCES

)

source_group(headers FILES ${HEADERS})
source_group(sources FILES ${SOURCES})

add_executable("Project 2" WIN32
    ${HEADERS}
    ${SOURCES}
)

target_link_libraries("Project 2" "Project 1")

问题/问题

注意:我正在尝试实现源外构建,其中项目 1 是项目 2 中使用的引擎。

我在 root_project 构建下运行的命令:cmake .. -G "Visual Studio 15 2017 Win64"

  • 项目 2 未链接到项目 1
  • 项目 2 未出现在 VS 2017 中
  • 我自己在项目 1 的 /include 下的头文件将显示在 VS 2017 中的外部依赖项中,而不是源中

【问题讨论】:

  • 在 CMake 中VS 术语 project=solution 和 target=project
  • 虽然我想提一下,我喜欢这个问题的质量。保持良好的工作! :)
  • 我总是尝试组织我的帖子以获得更高的质量。那么根据您的评论,我应该怎么做才能解决我的问题?
  • 只看它:你将如何链接(项目 2)与可执行文件(项目 1)? CMake 应该给你一个警告或错误项目 2 不包含任何源(这可能是它不会出现的原因)。
  • 这就是我在上面写评论的原因。通常项目 1 不是可执行文件,将像在 Linux 下一样使用 add_library 创建。是的,它给了我这个警告,但是当使用 CMake 为 IDE 创建一个新项目时,你将如何创建文件?在 IDE 之外手动操作,这听起来有点奇怪。

标签: c++ visual-studio compilation cmake visual-studio-2017


【解决方案1】:

把我的评论变成答案

您只需为您的Project 2 目标指定来源。

我给你一个例子,CMake 给你一个配置错误(这可能是为什么它不会显示/不重写解决方案/项目文件,如果你添加第二个项目):

CMake Error at CMakeLists.txt:23 (add_executable):
   add_executable called with incorrect number of arguments, no sources provided

是的,如果您添加例如一个尚不存在的src/main.cppSOURCES 你会得到:

CMake Error at CMakeLists.txt:23 (add_executable):
  Cannot find source file:

    src/main.cpp

  Tried extensions .c .C .c++ .cc .cpp .cxx .m .M .mm .h .hh .h++ .hm .hpp .hxx .in .txx

因此,CMake 中的工作流程始终是首先创建源文件,然后添加到您的CMakeLists.txt。使用 VS 之类的 IDE,您只需将一个新项目添加到您的项目中(就像您对非生成项目所做的那样),然后将其添加到您的 CMakeLists.txt 文件中。

对于我的一些项目,我创建了一个在覆盖的add_executable() 调用内部调用的check_and_create_source() 函数,但是使用了几年我现在可以说这种方法没有真正的好处。您仍然需要运行 ZERO_CHECK 构建来创建空文件/在您开始之前(并且当您错误地键入现有源文件的包含时,您会感到困惑)。

我个人不喜欢 globbing 替代方案(请参阅 Why is cmake file GLOB evil?CMake/Ninja attempting to compile deleted `.cpp` file

【讨论】:

  • @ShadowDragon 您能否更具体地了解您遇到的问题,当我使用“项目 2”的源/标题对其进行测试时,它似乎有效?我刚刚遇到 CMake 不接受“项目 2”作为“保留名称”。所以我不得不重命名为例如“项目 2”。最后一点,你必须把你想在IDE项目中的所有头文件作为源,否则它们只会显示为“外部依赖项”。
  • 至第 3 点: 所以我必须将它们显式添加到 add_executable 命令中?如何在不将完整相对路径放入 CMakeLists.txt 文件的情况下列出这些标头。例如,我只需要写Engine.h 而不是sources/include/Engine.h。通常也很高兴知道源文件的这一点。 至第 1 点: 例如,VS 不能在项目 2 中包含来自项目 1 的任何文件。注意:项目 2 只有一个 main.cpp,其中没有代码,因此它显示在 VS 中。
猜你喜欢
  • 2021-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 2013-03-18
  • 2017-10-03
  • 2011-03-25
相关资源
最近更新 更多