【发布时间】:2021-04-01 03:09:55
【问题描述】:
简而言之:我无法将使用 CPLEX 的程序与 CMake 链接,链接器似乎没有找到 CPLEX 库 (cplex),但找到了一些其他库 (@987654323 @)。从命令行,它确实有效。
详细说明:
对于使用 CPLEX 的程序:
#include <ilcplex/ilocplex.h>
int main(int argc, char *argv[]) {
IloEnv env;
IloModel model(env);
IloCplex cplex(model);
return 0;
}
我有以下CMakeLists.txt:
cmake_minimum_required(VERSION 3.17)
project(myprog C CXX)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
find_package(CPLEX)
if (CPLEX_FOUND)
add_definitions(-DIL_STD)
else()
message (FATAL_ERROR "CPLEX not found!")
endif()
add_executable(myprog src/main.cpp )
target_include_directories(myprog PUBLIC ${CPLEX_INCLUDE_DIRS})
target_link_libraries(myprog PUBLIC ${CPLEX_LIBRARIES})
set_target_properties(myprog PROPERTIES LINK_FLAGS "-lconcert -lilocplex -lcplex -lpthread -ldl")
和cmake/FindCPLEX.cmake:
set (CPLEX_DIR "/opt/ibm/ILOG/CPLEX_Studio_Community201")
if (CPLEX_INCLUDE_DIR)
set(CPLEX_FOUND TRUE)
set(CPLEX_INCLUDE_DIRS "${CPLEX_INCLUDE_DIR};${CPLEX_CONCERT_INCLUDE_DIR}" )
set(CPLEX_LIBRARIES "${CPLEX_ILO_LIBRARY};${CPLEX_CONCERT_LIBRARY};${CPLEX_LIBRARY};${CPLEX_PTHREAD_LIBRARY}" )
else (CPLEX_INCLUDE_DIR)
find_path(CPLEX_INCLUDE_DIR
NAMES ilcplex/cplex.h
PATHS "${CPLEX_DIR}/cplex/include"
)
find_path(CPLEX_INCLUDE_ILCPLEX
NAMES cplex.h
PATHS "${CPLEX_DIR}/cplex/include/ilcplex"
)
find_path(CPLEX_CONCERT_INCLUDE_DIR
NAMES ilconcert/ilomodel.h
PATHS "${CPLEX_DIR}/concert/include"
)
find_path(CPLEX_INCLUDE_ILCONCERT
NAMES ilomodel.h
PATHS "${CPLEX_DIR}/concert/include/ilconcert"
)
find_library(CPLEX_LIBRARY
cplex
PATHS "${CPLEX_DIR}/cplex/lib/x86-64_sles10_4.1/static_pic"
"${CPLEX_DIR}/cplex/lib/x86-64_darwin/static_pic/"
"${CPLEX_DIR}/cplex/lib/x86-64_linux/static_pic"
)
find_library(CPLEX_ILO_LIBRARY
ilocplex
PATHS "${CPLEX_DIR}/cplex/lib/x86-64_sles10_4.1/static_pic"
"${CPLEX_DIR}/cplex/lib/x86-64_darwin/static_pic/"
"${CPLEX_DIR}/cplex/lib/x86-64_linux/static_pic"
)
find_library(CPLEX_CONCERT_LIBRARY
concert
PATHS "${CPLEX_DIR}/concert/lib/x86-64_linux/static_pic/"
"${CPLEX_DIR}/concert/lib/x86-64_sles10_4.1/static_pic"
"${CPLEX_DIR}/concert/lib/x86-64_darwin/static_pic/"
)
find_library( CPLEX_PTHREAD_LIBRARY
pthread
PATHS "/usr/lib"
"/usr/lib64"
"/lib"
"/lib64"
)
find_library( CPLEX_DL_LIBRARY
dl
PATHS "/usr/lib"
"/usr/lib64"
"/lib"
"/lib64"
)
set(CPLEX_COMPILER_FLAGS "-DIL_STD" CACHE STRING "Cplex Compiler Flags")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CPLEX DEFAULT_MSG
CPLEX_LIBRARY CPLEX_INCLUDE_DIR CPLEX_CONCERT_INCLUDE_DIR CPLEX_ILO_LIBRARY CPLEX_CONCERT_LIBRARY)
if(CPLEX_FOUND)
set(CPLEX_INCLUDE_DIRS "${CPLEX_INCLUDE_DIR};${CPLEX_CONCERT_INCLUDE_DIR};${CPLEX_INCLUDE_ILCPLEX};${CPLEX_INCLUDE_ILCONCERT}" )
set(CPLEX_LIBRARIES ${CPLEX_CONCERT_LIBRARY} ${CPLEX_ILOCPLEX_LIBRARY} ${CPLEX_LIBRARY} ${CPLEX_PTHREAD_LIBRARY} ${CPLEX_DL_LIBRARY})
endif(CPLEX_FOUND)
mark_as_advanced(CPLEX_INCLUDE_DIR CPLEX_LIBRARY CPLEX_CONCERT_INCLUDE_DIR CPLEX_ILO_LIBRARY CPLEX_CONCERT_LIBRARY CPLEX_PTHREAD_LIBRARY)
endif(CPLEX_INCLUDE_DIR)
message(STATUS "CPLEX_ILO_LIBRARY=${CPLEX_ILO_LIBRARY}")
message(STATUS "CPLEX_LIBRARIES=${CPLEX_LIBRARIES}")
message(STATUS "CPLEX_INCLUDE_DIRS=${CPLEX_INCLUDE_DIRS}")
message(STATUS "concert=${concert}")
message(STATUS "cplex=${cplex}")
CPLEX 相关的 CMake 输出是
-- Found CPLEX: /opt/ibm/ILOG/CPLEX_Studio_Community201/cplex/lib/x86-64_linux/static_pic/libcplex.a
-- CPLEX_ILO_LIBRARY=/opt/ibm/ILOG/CPLEX_Studio_Community201/cplex/lib/x86-64_linux/static_pic/libilocplex.a
-- CPLEX_LIBRARIES=/opt/ibm/ILOG/CPLEX_Studio_Community201/concert/lib/x86-64_linux/static_pic/libconcert.a;/opt/ibm/ILOG/CPLEX_Studio_Community201/cplex/lib/x86-64_linux/static_pic/libcplex.a;/usr/lib/x86_64-linux-gnu/libpthread.so;/usr/lib/x86_64-linux-gnu/libdl.so
-- CPLEX_INCLUDE_DIRS=/opt/ibm/ILOG/CPLEX_Studio_Community201/cplex/include;/opt/ibm/ILOG/CPLEX_Studio_Community201/concert/include;/opt/ibm/ILOG/CPLEX_Studio_Community201/cplex/include/ilcplex;/opt/ibm/ILOG/CPLEX_Studio_Community201/concert/include/ilconcert
-- concert=
-- cplex=
错误是
/usr/bin/ld: cannot find -lconcert
/usr/bin/ld: cannot find -lilocplex
/usr/bin/ld: cannot find -lcplex
CMakeLists.txt中没有最后一行,错误是
/usr/bin/ld: CMakeFiles/myprog.dir/src/main.cpp.o: in function `main':
/<my path>/src/main.cpp:7: undefined reference to `IloCplex::IloCplex(IloModel)'
即链接器在/opt/ibm/ILOG/CPLEX_Studio_Community201/concert/include/ilconcert/iloenv.h 中找到类IloEnv 和/opt/ibm/ILOG/CPLEX_Studio_Community201/concert/include/ilconcert/ilomodel.h 中的IloModel,但在/opt/ibm/ILOG/CPLEX_Studio_Community201/cplex/include/ilcplex/ilocplexi.h 中找不到IloCplex。
从命令行编译是可行的(为了便于阅读,此处进行了格式化):
$ for f in src/*.cpp; do
... g++ -c -I/opt/ibm/ILOG/CPLEX_Studio_Community201/cplex/include
... -I/opt/ibm/ILOG/CPLEX_Studio_Community201/concert/include
... -Iinclude $f -o build/$(basename $f .cpp).o;
... done
$ unset OBJ_FILES
$ for i in build/*.o; do OBJ_FILES="$i $OBJ_FILES"; done
$ g++ -I/opt/ibm/ILOG/CPLEX_Studio_Community201/cplex/include
... -I/opt/ibm/ILOG/CPLEX_Studio_Community201/concert/include
... -Iinclude
... -L/opt/ibm/ILOG/CPLEX_Studio_Community201/cplex/lib/x86-64_linux/static_pic
... -L/opt/ibm/ILOG/CPLEX_Studio_Community201/concert/lib/x86-64_linux/static_pic
... $OBJ_FILES
... -o progr
... -lconcert -lilocplex -lcplex -lpthread -ldl
【问题讨论】:
-
我认为您的
target_link_libraries需要声明为STATIC,至少对于 cplex 和 Concert。见cmake.org/cmake/help/latest/command/… -
另外我建议使用
find_library和HINTS。另外,我建议不推荐使用set_target_properties设置链接器输入。 -
@Den-Jason
STATIC没有帮助。而set_target_properties是在target_link_options不起作用后尝试解决问题。无论如何,谢谢。 -
set_target_properties(LINK_FLAGS)绝对是链接库的错误方式。您的target_link_libraries电话应该可以工作。如果您使用make构建项目,请将VERBOSE=1选项传递给它并查看用于编译和链接的确切命令行。在该命令行中,您可以检查实际的包含目录和库、编译器(确保g++指向 CMake 使用的同一编译器)和其他内容。 -
@Tsyvarev 最初,我还希望
target_link_libraries可以工作,但他们没有(非常烦人!)。问题中给出了确切的命令行。编译器是一样的。
标签: c++ linux cmake cplex linker-flags