1

我有一个具体问题,可以作为更一般问题的背景。

有一个名为 LAMMPS 的科学包,它通常用作可执行文件。但是,它支持用作“库”。为了尝试做正确的事情,我把它放在 /usr/local/lib/lammps 中。它包含一个 lammps/src/ 目录,其中包含大约 40 个源文件。使用提供的说明,我将 lammps 编译为 lammps/src/liblammps_serial.so 中的 .so 文件。

我在“~/code/ljtube/”中也有单独的代码。这使用 cmake 来尝试查找库。因此,我写了一个 FindLAMMPS.txt 以便我可以使用

FIND_PACKAGE (lammps)

在我的 CMakeLists 中。我修改了 libtool 配置文件以在 /usr/local/ 中搜索成功。我发现它在 /usr/local/lib/ 中搜索 .so 文件,在 /usr/local/include/ 中搜索 .h 文件。所以我在/usr/local/lib/ 中创建了一个.so 文件的动态链接,并将.h 文件从lammps/src/ 复制到/usr/local/include/。

CMake 现在可以找到这两个文件,但它无法链接到 lammps/src/ 中的任何其他文件。需要为我想要包含的每个 .h (group.h、fix.h、force.h、pair.h 等)创建一个单独的 FIND_PACKAGE 似乎很荒谬。将整个 .h 文件包转储到 /usr/local/include/ 目录中似乎也很荒谬。我将在本地和集群上使用此代码,并可能将其分发给其他组成员。

如何让 CMake 在 /usr/local/lib/lammps/src/ 的位置没有硬编码的情况下找到我想要找到的内容?更笼统地说,我应该如何管理像这样的大包,以使它们在我编写的代码中易于链接,即使原始开发人员没有使用最佳约定?

(作为旁注,我使用共享库是因为它似乎是正确的选择,但我并不是特别喜欢它。我应该使用静态库吗?CMake 有没有办法找到已经编译的相对于当前源目录的库,这可能是实现这一点的更好方法吗?我知道我将在多个项目中使用 LAMMPS,因此从表面上看,拥有一个本地共享副本似乎是最有意义的。)

4

1 回答 1

1

通常,find_package调用会产生一个变量,该变量指定包的“包含”文件夹的路径。然后,这将通过 . 添加到调用者的 CMakeLists.txt 中include_directories

例如,要使用find_packageboost,你可以这样做:

find_package(Boost)  # sets ${Boost_INCLUDE_DIRS} and ${Boost_LIBRARIES}
if(Boost_FOUND)
  include_directories(${Boost_INCLUDE_DIRS})
  add_executable(foo foo.cc)
  target_link_libraries(foo ${Boost_LIBRARIES})
endif()


关于您的旁注,您可以使用find_library和/或find_path查找给定位置的库及其标题。

可以通过避免在公共位置搜索的方式调用这两个命令,例如通过设置PATHS为已知位置并NO_DEFAULT_PATH在查找命令中使用。

另一种选择是让您的项目使用本文ExternalProject_Add中更详细描述的功能。从这篇文章:

ExternalProject_Add功能可以说“从互联网上下载这个项目,运行它的配置步骤,构建它并安装它”</p>

这种方法的一个缺点是您的每个项目最终都会有自己的第三方源代码和库的副本。

于 2013-01-01T03:32:15.010 回答