根据机器上安装的库依赖编译不同的代码

Compile different code depending on library dependencies installed on machine

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

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

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

感谢您提供的任何帮助!

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

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()