首页 > 解决方案 > 根据机器上安装的库依赖编译不同的代码

问题描述

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

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

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

感谢您的任何帮助,您可以提供!

标签: c++cmakecplexgurobi

解决方案


考虑到您没有发布任何代码,有很多选项。如果库本身使用 CMake,并带有FindGurobi.cmakeor FindCPLEX.cmake,则可以使用 CMakefind_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()

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

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

推荐阅读