【问题标题】:Successful Makefile fails with "identical" CMake in CLion成功的 Makefile 因 CLion 中的“相同”CMake 而失败
【发布时间】:2020-02-03 06:48:36
【问题描述】:

我正在尝试使用 CLion 在我的 Mac OS 10.13.1 (macOS High Sierra) 上使用 IBM ILOG CPLEX 12.7.1。这是一段非常简单的 C++ 代码。

#include <iostream>
#include <ilcplex/ilocplex.h>
using namespace std;
int main() {
    std::cout << "Hello, World!" << std::endl;
    IloEnv env;
    x: IloCplex cplex(env);
    std::cout << env.getVersion() << endl;

    return 0;
}

以下在我的Makefile

SYSTEM = x86-64_osx
LIBFORMAT = static_pic
CPLEXDIR = /Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/cplex
CONCERTDIR = /Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/concert
# ---------------------------------------------------------------------
# Compiler selection 
# --------------------------------------------------------------------- 
CCC = clang++ -O0
# ---------------------------------------------------------------------
# Compiler options 
# ---------------------------------------------------------------------
CCOPT = -m64 -O -fPIC -fexceptions -DNDEBUG -DIL_STD -stdlib=libc++
# ---------------------------------------------------------------------
# Link options and libraries
# ---------------------------------------------------------------------

CPLEXBINDIR = $(CPLEXDIR)/bin/$(BINDIST)

CPLEXLIBDIR = $(CPLEXDIR)/lib/$(SYSTEM)/$(LIBFORMAT)
CONCERTLIBDIR = $(CONCERTDIR)/lib/$(SYSTEM)/$(LIBFORMAT)

CCLNDIRS  = -L$(CPLEXLIBDIR) -L$(CONCERTLIBDIR) 
CCLNFLAGS = -lconcert -lilocplex -lcplex -lm -lpthread -ldl #-framework CoreFoundation -framework IOKit -stdlib=libc++
all:
   make main

CONCERTINCDIR = $(CONCERTDIR)/include
CPLEXINCDIR = $(CPLEXDIR)/include

CCFLAGS = $(CCOPT) -I$(CPLEXINCDIR) -I$(CONCERTINCDIR) 
# ------------------------------------------------------------
main: main.o
$(CCC) $(CCFLAGS) $(CCLNDIRS) -o main main.o $(CCLNFLAGS)
main.o: ./main.cpp
$(CCC) -c $(CCFLAGS) ./main.cpp -o main.o

这是CMakeLists.txt,我尝试使用与Makefile 中提到的参数完全相同的参数来创建它。

cmake_minimum_required(VERSION 3.14)
project(cplextest)
add_executable(cplextest main.cpp)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  -m64 -O -fPIC -fexceptions -DNDEBUG -DIL_STD -stdlib=libc++")
include_directories(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/cplex/include/)
include_directories(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/cplex/include/ilcplex)
include_directories(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/concert/include)
include_directories(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/concert/include/ilconcert)
find_library(lib1 NAMES libcplex.a PATHS /Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/cplex/lib/x86-64_osx/static_pic/)
find_library(lib2 NAMES libilocplex.a PATHS /Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/cplex/lib/x86-64_osx/static_pic/)
find_library(lib3 NAMES libcplexdistmip.a PATHS /Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/cplex/lib/x86-64_osx/static_pic/)
set (CMAKE_SHARED_LINKER_FLAGS "-lconcert -lilocplex -lcplex -lm -lpthread -ldl #-framework CoreFoundation -framework IOKit -stdlib=libc++")
target_link_libraries(cplextest PUBLIC ${lib1})
target_link_libraries(cplextest PUBLIC ${lib2})
target_link_libraries(cplextest PUBLIC ${lib3})

然而,虽然 Makefile 工作完美(即,我可以从终端成功运行我的程序),但 CLion 会产生以下错误消息。

====================[ Build | cplextest | Debug ]===============================
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake --build /Users/soheilmn/CLionProjects/CplexTest/cmake-build-debug --target cplextest -- -j 2
[ 50%] Linking CXX executable cplextest
Undefined symbols for architecture x86_64:
  "IloCplex::IloCplex(IloEnv)", referenced from:
      _main in main.cpp.o
  "IloCplexI::getVersion() const", referenced from:
      _main in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[3]: *** [cplextest] Error 1
make[2]: *** [CMakeFiles/cplextest.dir/all] Error 2
make[1]: *** [CMakeFiles/cplextest.dir/rule] Error 2
make: *** [cplextest] Error 2

有趣的是,如果我在我的 C++ 代码中注释掉行 (x),我可以成功地从 CLion 运行我的代码。这确实让我很困惑,因为我的理解是两个程序都使用clang++ 和相同的库/头文件。任何帮助将不胜感激。 (抱歉提前发了这么长的帖子!)

谢谢!

【问题讨论】:

    标签: c++ makefile clion cplex


    【解决方案1】:

    CMAKE_SHARED_LINKER_FLAGS 指定创建新共享库时要使用的标志。但是您的项目不会创建共享库,它会创建一个可执行文件。您应该像这样将所有库名称传递给target_link_libraries

    target_link_libraries(cplextest PUBLIC "concert;cplex;ilocplex;cplexdistmip")
    

    然后您可能需要添加库搜索路径(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/cplex/lib/x86-64_osx/static_pic/),它应该可以工作.如果您想查看实际运行的链接器命令,请在运行cmake 之后运行make VERBOSE=1

    要启用 pthread,请参阅 cmake and libpthread

    【讨论】:

    • 非常感谢您的帮助。为了确保我完全理解你,我需要问这些问题: 1. 所以,你是说我不需要使用CMAKE_SHARED_LINKER_FLAGS 但是将这些标志传递给链接器的正确方法是什么? 2)我已经通过了您使用find_library提到的库搜索路径。这不是正确的做法,我应该使用另一个命令吗? 3. 如何/在哪里运行make VERBOSE=1' in CLion? Do I need to put that command somewhere in the Makefile' 或 `CMakeLists.txt'?再次感谢您的帮助!
    • 如果需要(也许不需要),请使用target_link_options 添加链接器选项。使用target_link_libraries 添加要链接的库。您可以将完整路径传递给target_link_libraries,因此当您已经知道完整的绝对路径时,绝对不需要使用find_library。我不使用 CLion,因此无法在 VERBOSE=1 部分为您提供帮助,但这不是必需的,只是您可以在某个时候尝试找出的调试工具。
    • 谢谢!现在完美运行。
    【解决方案2】:

    特别感谢“John Zwinck”的帮助。我认为在 macOS 10.13.1 / CLion 2109.2.3 下分享与 IBM ILOG CPLEX 12.9 完美配合的最终 CMake 文件是有意义的。这里是:

    cmake_minimum_required(VERSION 3.14)
    project(cplextest)
    add_executable(cplextest main.cpp)
    set(CMAKE_CXX_COMPILER clang++)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  -m64 -O -fPIC -fexceptions -DNDEBUG -DIL_STD -stdlib=libc++")
    include_directories(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio129/cplex/include/)
    include_directories(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio129/cplex/include/ilcplex)
    include_directories(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio129/concert/include)
    include_directories(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio129/concert/include/ilconcert)
    target_link_libraries(cplextest PUBLIC /Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio129/cplex/lib/x86-64_osx/static_pic/libcplex.a)
    target_link_libraries(cplextest PUBLIC /Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio129/cplex/lib/x86-64_osx/static_pic/libilocplex.a)
    target_link_libraries(cplextest PUBLIC /Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio129/concert/lib/x86-64_osx/static_pic/libconcert.a)
    set (target_link_options "-lconcert -lilocplex -lcplex -lm -lpthread -ldl -framework CoreFoundation -framework IOKit -stdlib=libc++")
    

    【讨论】:

      猜你喜欢
      • 2022-10-01
      • 2018-03-11
      • 1970-01-01
      • 2015-01-11
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      • 1970-01-01
      • 2019-05-05
      相关资源
      最近更新 更多