如何解决在 CMake 中为 CPLEX 传递链接器标志
简而言之:我无法将使用 CPLEX 的程序与 CMake 链接起来,链接器似乎没有找到 CPLEX 库 (cplex
),但找到了其他一些库 (ilocplex
) #include <ilcplex/ilocplex.h>
int main(int argc,char *argv[]) {
IloEnv env;
IloModel model(env);
IloCplex cplex(model);
return 0;
}
)。从命令行,它确实有效。
详细:
对于使用 CPLEX 的程序:
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}")
:
-- 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=
CPLEX 相关的 CMake 输出是
/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)'
中的最后一行,错误是
IloEnv
即链接器在 /opt/ibm/ILOG/CPLEX_Studio_Community201/concert/include/ilconcert/iloenv.h
中找到类 IloModel
,在 /opt/ibm/ILOG/CPLEX_Studio_Community201/concert/include/ilconcert/ilomodel.h
中找到 IloCplex
,但在 /opt/ibm/ILOG/CPLEX_Studio_Community201/cplex/include/ilcplex/ilocplexi.h
中找不到 $ 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
。
从命令行编译工作(为了便于阅读,这里格式化):
Program Explanation
1. Take the number which you have to reverse as the input and store it in the variable num.
2. Copy the input number to the another variable temp.
3. Firstly initialize the variable reverse to zero.
4. Obtain the remainder of the input number.
5. Multiply the variable reverse with 10 and add the Obtained remainder to it and store the result in the same variable.
6. Obtain the quotient of the input number and considering this as input number repeat the steps as mentioned above until the obtained quotient becomes zero.
7. When it becomes zero,using if,else statement check whether the reversed number is equal to original number or not.
8. If it is equal,then print the output as “Yes”,otherwise print the output as “No”.
#include <stdio.h>
void main()
{
int num,temp,remainder,reverse = 0;
printf("Enter an integer \n");
scanf("%d",&num);
/* original number is stored at temp */
temp = num;
while (num > 0)
{
remainder = num % 10;
reverse = reverse * 10 + remainder;
num /= 10;
}
printf("Given number is = %d\n",temp);
printf("Its reverse is = %d\n",reverse);
if (temp == reverse)
printf("Yes \n");
else
printf("No \n");
}
Case:1
Enter an integer
6789
Given number is = 6789
Its reverse is = 9876
No
Case:2
Enter an integer
58085
Given number is = 58085
Its reverse is = 58085
Yes
解决方法
正如 Tsyvarev 指出的那样:不应使用未设置的 CPLEX_ILOCPLEX_LIBRARY
,而应在 CPLEX_ILO_LIBRARY
的定义中使用变量 CPLEX_LIBRARIES
。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。