根据机器上安装的库依赖编译不同的代码
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.cmake
或 FindCPLEX.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()
我有使用 cmake 构建的 C++ 代码。我写了一个 class 依赖于一个叫做 Gurobi 的库。 Gurobi 的竞争对手之一是 CPLEX,这是另一个允许执行类似优化任务的库。我必须在 CPLEX 中为一个研究项目重写我的 classes(因为我们的资金来自一个只能访问 CPLEX 的机构)。因此,我想更改我的 cmake 文件,以便它查找 Gurobi 和 CPLEX,如果找到 Gurobi,则使用 GurobiClass.cpp 文件编译我的代码,如果找到 cplex,则使用 CPLEX.cpp 文件。
我基本上是在问如何在编译步骤中忽略代码,这样用户就不必同时拥有两个库来编译我的代码。
我确定已经有人问过这个问题,但我不确定这个问题的正确名称是什么/要搜索什么,所以我再问一次,但请随时将我指向在线资源。
感谢您提供的任何帮助!
考虑到您尚未发布任何代码,有多种选择。如果库本身使用 CMake,并带有 FindGurobi.cmake
或 FindCPLEX.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()