如何在CMake项目中包括IntelliSense的外部库的源代码?

时间:2019-10-15 21:27:22

标签: c++ visual-studio cmake intellisense

我正在使用Visual Studio的CMake项目模板在Visual Studio中处理C ++应用程序。 要构建我的应用程序,我只需要标题和外部库,就可以像这样链接它:

# CMakeList.txt : CMake project for myapp, include source and define project specific logic here.

cmake_minimum_required (VERSION 3.8)

# Add source to this project's executable.
add_executable (myapp "myapp.cpp" "myapp.h")

# Add TIFF library
set(TIFF_INCLUDE_DIR "C:\\libs\\tiff\\out\\install\\x64-Debug\\include")
set(TIFF_LIBRARY "C:\\libs\\tiff\\out\\install\\x64-Debug\\lib\\tiffd.lib")
find_package(TIFF REQUIRED)
target_link_libraries(myapp PRIVATE TIFF::TIFF)

到目前为止,太好了。我可以使用tiff库打开,读取,写入tiff文件等,并且IntelliSense可以赶上头文件中的声明。但是,我希望IntelliSense也了解TIFF库的完整源代码。例如,如果我在myapp.cpp中,而我在ctrl+click上是TIFFOpen,则会打开对应于TIFFOpen的标题,但是当我ctrl+click TIFFOpen在头文件,它不会转到相应的源文件,这是myapp中源文件的正常行为。这是可以理解的,因为我从未告诉过Visual Studio在哪里可以找到外部库的源文件。

CMake不需要知道外部库的源文件在哪里,因为它不会构建外部库,因此我想我不/应该不更改CMakeLists.txt

一个选项(我还没有尝试过,但是我很确定它会起作用),就是将整个tiff库作为myapp的子项目包含在内。但是,此解决方案确实存在一些问题:

  1. 从概念上讲,外部库不是项目的组成部分,我也不打算修改外部库。这更多是一个原则性问题。
  2. 在项目中仅将其作为子文件夹会使其有更改我不打算更改的内容的风险。
  3. 当我全部重建时,我不想重建外部库。我知道Visual Studio / CMake足够聪明,可以发现没有任何更改并且不会重建,但是我宁愿Visual Studio / CMake甚至都不要尝试。

我看到的方式是,必须在Visual Studio设置中的某个位置设置源文件目录,但仍与项目相关。我最好的猜测是.vs/ProjectSettings.json是我需要以某种方式编辑的文件,但说实话,我没有任何线索。

或者,也许我可以在CMakeLists.txt中写一些命令,该命令什么也不做,但是会触发IntelliSense在包含源文件的文件夹中查找。同样,我不知道该如何处理。

简而言之,我希望IntelliSense能够查看外部库的所有源文件,就像查看myapp的源文件一样,而不将外部库的所有源文件都包括为myapp的子项目。如果可能的话,我该怎么办?

如果相关,我将使用Visual Studio 2019社区及其随附的CMake(3.15)。

2 个答案:

答案 0 :(得分:2)

关于您的最后一条评论,在评论部分编写代码很不方便,因此尽管没有答案,我还是将其张贴在这里。

libtiff-4.pc用于pkg-config,而不是cmake,find_package()不能直接在Windows上处理,如果您确实需要,它将需要一些工作。手动编写所有内容可能会更容易。请记住,根据您的配置设置tiff.libtiffd.lib。您可以使用CMAKE_BUILD_TYPE变量和if()命令,例如:

# set build type to release if not specified
if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
    set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE)
endif()
# switch lib to link according to build type
if(CMAKE_BUILD_TYPE STREQUAL "Release")
    # for release
    set(TIFF_LIBRARY "<your_path_to_installed_lib>/tiff.lib")
else()
    # for debug. If you have other configs like relwithdebinfo you can add more
    set(TIFF_LIBRARY "<your_path_to_installed_lib>/tiffd.lib")
endif()

此外,删除find_package()并使用target_link_libraries()target_inlude_directories()

set(TIFF_INCLUDE_DIR "<your_path_to_installed_headers>/include")
target_link_libraries(myapp PRIVATE ${TIFF_LIBRARY})
target_include_directories(myapp PRIVATE ${TIFF_INCLUDE_DIR})

如果您愿意,也可以跳过设置TIFF_LIBRARYTIFF_INCLUDE_DIR并直接传递字符串。

我经常使用Visual Studio,这是我最喜欢的IDE。但是,在Windows上使用cmake进行软件包管理不如在Linux上那么顺利。始终记得在编译和安装外部库之后设置环境变量。

通常,find_package()将查找名为<libname>_DIR的系统环境变量(例如TIFF_DIR,在您的情况下找不到),该变量用于存储安装的lib的路径,然后查找<libname>Config.cmake<libname>ConfigVersion.cmake放在该文件夹中(并且TIFF失败,因为它没有它们)。

它还会搜索其他地方,请查看https://cmake.org/cmake/help/v3.15/command/find_package.html?highlight=find_package以获取详细信息。

因此,对于那些具有cmake导出文件的库,请添加具有正确名称和值的变量。那只是为了编译。

如果希望应用程序在编译后运行,则还需要将已安装的lib二进制文件(通常为* .dll)的路径添加到系统的Path变量中。在您的情况下,编译和安装后应该会找到tiff.dlltiffd.dll之类的东西,将该文件夹添加到Path即可。

答案 1 :(得分:0)

实际上,在IDE中显示源很容易。

只需使用add_library(tiff_for_ide EXCLUDE_FROM_ALL ${SOURCES})添加源,但不要在主程序中将其链接。您需要为库使用其他目标名称。为此,您需要直接将项目中的源或作为子模块(如果使用Git,如果您的VCS可用,则需要其他源)作为项目中的源。

其他选项正在使用ExternalModule_Add;或与FetchContent_MakeAvailable一起使用add_library,以避免将第三方部门直接添加到存储库中。

现在,只要动动手指,希望IDE不够智能,就不能限制搜索与编译当前文件的目标链接的源。或者它足够智能,可以检测到这种情况,但是当它链接到二进制文件时,无论如何都会回退搜索整个项目文件。