【问题标题】:Compile different code depending on library dependencies installed on machine根据机器上安装的库依赖编译不同的代码
【发布时间】:2019-09-19 19:00:39
【问题描述】:

我有使用 cmake 构建的 c++ 代码。我写了一个类,它依赖于一个名为 Gurobi 的库。 Gurobi 的竞争对手之一是 CPLEX,这是另一个允许类似优化任务的库。我必须为一个研究项目重写我在 CPLEX 中的课程(因为我们的资金来自一个只能访问 CPLEX 的机构)。因此,我想更改我的 cmake 文件,以便它查找 Gurobi 和 CPLEX,如果找到 Gurobi,则使用 GurobiClass.cpp 文件编译我的代码,如果找到 cplex,则使用 CPLEX.cpp 文件。

我基本上是在问如何在编译步骤中忽略代码,这样用户就不必同时拥有两个库来编译我的代码。

我确定已经有人问过这个问题,但我不确定这个问题的正确名称是什么/要搜索什么,所以我再次问这个问题,但请随时向我指出在线资源。

感谢您提供的任何帮助!

【问题讨论】:

  • 在 cmake 中你可以找到库并检查是否安装了这个库。根据此状态,您可以设置宏。见cmake.org/cmake/help/latest/command/find_package.html
  • 您的 CMake 如何找到这些外部库(CPLEX 和 Gurobi)?您是在使用find_package(),对预建库的硬编码路径,使用add_subdirectory(),还是其他?当您没有提供一些示例代码时,很难提出解决方案。

标签: c++ cmake cplex gurobi


【解决方案1】:

考虑到您尚未发布任何代码,有多种选择。如果库本身使用 CMake,并带有 FindGurobi.cmakeFindCPLEX.cmake,您可以使用 CMake 的 find_package() 来定位它们。您可以使用 if 语句确定要包含哪些文件(以及要链接的库)到您的目标。一个简单的例子是这样的:

find_package(Gurobi)
find_package(CPLEX)

if(Gurobi_FOUND)
    # Compile with Gurobi classes.
    add_library(MyLibrary 
        TopLevelClass.cpp
        GurobiClass1.cpp
        GurobiClass2.cpp
        ...
    )
    target_include_directories(MyLibrary PUBLIC ${Gurobi_INCLUDE_DIR})
    target_link_libraries(MyLibrary PUBLIC ${Gurobi_LIBRARIES})
elseif(CPLEX_FOUND)
    # Compile with CPLEX classes.
    add_library(MyLibrary 
        TopLevelClass.cpp
        CPLEXClass1.cpp
        CPLEXClass2.cpp
        ...
    )
    target_include_directories(MyLibrary PUBLIC ${CPLEX_INCLUDE_DIR})
    target_link_libraries(MyLibrary PUBLIC ${CPLEX_LIBRARIES})
else()
    message(FATAL_ERROR "Neither Gurobi nor CPLEX library was found.")
endif()

如果您以某种方式对这些库的路径进行硬编码,您也可以执行以下操作(检查if 库文件是否存在):

set(Gurobi_INCLUDE_DIR /path/to/local/gurobi/include)
set(Gurobi_LIBRARY /path/to/local/gurobi/lib/gurobi.lib)

set(CPLEX_INCLUDE_DIR /path/to/local/CPLEX/include)
set(CPLEX_LIBRARY /path/to/local/CPLEX/lib/cplex.lib)

if(EXISTS ${Gurobi_LIBRARY})
    # Compile with Gurobi classes...
elseif(EXISTS ${CPLEX_LIBRARY})
    # Compile with CPLEX classes...
else()
    message(FATAL_ERROR "Neither Gurobi nor CPLEX library was found.")
endif()

【讨论】:

    猜你喜欢
    • 2017-10-21
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 2015-08-09
    • 2014-10-26
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多