Компилировать различный код в зависимости от библиотечных зависимостей, установленных на компьютере - PullRequest
0 голосов
/ 19 сентября 2019

У меня есть код C ++, который построен с использованием cmake.Я написал класс, который зависит от библиотеки под названием Gurobi.Одним из конкурентов Gurobi является CPLEX, другая библиотека, которая позволяет выполнять аналогичные задачи оптимизации.Я должен переписать свои занятия в CPLEX для исследовательского проекта (потому что наше финансирование поступает из агентства, которое имеет доступ только к CPLEX).Поэтому я хочу изменить свой файл cmake, чтобы он искал Gurobi и CPLEX и компилировал мой код, используя файл GurobiClass.cpp, если он находит Gurobi, и использует файл CPLEX.cpp, если он находит cplex.

Я в основном спрашиваю, как игнорировать код на этапе компиляции, чтобы у пользователя не было обеих библиотек для компиляции моего кода.

Я уверен, что этот вопрос былЯ уже спрашивал, но я не уверен, что это правильное имя / что искать, поэтому я спрашиваю еще раз, но не стесняйтесь указывать мне на онлайн-ресурсы.

Спасибо за любую помощь вамможем предоставить!

1 Ответ

1 голос
/ 20 сентября 2019

Учитывая, что вы не опубликовали код, есть несколько вариантов.Если библиотеки сами используют CMake и поставляются с FindGurobi.cmake или FindCPLEX.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()

Если вы как-то жестко кодируете пути к этим библиотекам, вы также можете сделать что-то вроде этого (проверить , если библиотекафайлы существуют):

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