在 macOS High Sierra 下使用 Cmake 将 Bonmin 与 "ld: framework not found -lAccelerate" 链接时出现问题
Problems linking Bonmin using Cmake under macOS High Sierra with "ld: framework not found -lAccelerate"
我目前正在尝试 link Bonmin 在我的 macOS High Sierra (10.13.4) 项目中使用 cmake Xcode 版本 9.3。在描述设置之前,我应该提到 Bonmin 示例 (/PATH_TO_BONMIN/Bonmin/examples/CppExample) 使用包含的 make 文件进行编译。后面的示例我尝试在我的环境中开始工作,但它不起作用。因此,我认为必须存在不兼容性。
Bonmin 1.8 (https://www.coin-or.org/Tarballs/Bonmin/) 是在我的 Mac 上使用
构建的
../configure -C --disable-shared F77="/usr/local/bin/gfortran" FFLAGS="-fexceptions -m64 -fbackslash" CFLAGS="-fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64" CXXFLAGS="-fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64"
我的 FindBonmin.cmake 使用来自“${BONMIN_LIBRARY_DIR}/pkgconfig”的包配置文件:
find_path(BONMIN_LIBRARY_DIR
NAMES libbonmin.a
HINTS ...
HINTS /usr/local/include/coin
HINTS ${BONMIN_ROOT_DIR}/include/coin
HINTS ${BONMIN_ROOT_DIR}/include
)
if(IS_DIRECTORY "${BONMIN_LIBRARY_DIR}/pkgconfig")
set(CMAKE_PREFIX_PATH "${BONMIN_LIBRARY_DIR}/pkgconfig")
set(ENV{PKG_CONFIG_PATH} "${BONMIN_LIBRARY_DIR}/pkgconfig")
else()
message("Directory ${BONMIN_LIBRARY_DIR}/pkgconfig does not exist!")
endif()
由此我得到以下信息:
${BONMIN_LIBRARY_DIR}/pkgconfig =
/Users/<PATH>/Bonmin-1.8/build/lib/pkgconfig
${PKG_BONMIN_INCLUDE_DIRS} =
/Users/<PATH>/Bonmin-1.8/build/include/coin;/Users/<PATH>/Bonmin-1.8/build/include/coin/ThirdParty;/Users/<PATH>/Bonmin-1.8/build/include/coin;/Users/<PATH>/Bonmin-1.8/build/include/coin/ThirdParty
${PKG_BONMIN_LDFLAGS} = -L/Users/<PATH>/Bonmin-1.8/build/lib;-L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/x86_64;-L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/../../../x86_64;-L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3;-L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/../../..;-lbonmin;-lCbcSolver;-lCbc;-lCgl;-lOsiClp;-lClpSolver;-lClp;-lcoinasl;-lm;-ldl;-lOsi;-lCoinUtils;-lbz2;-lz;-framework;Accelerate;-lm;-lipopt;-framework;Accelerate;-lm;-ldl;-lcoinmumps;-framework;Accelerate;-lgfortranbegin;-lgfortran;-lSystem
这个用于示例:
include_directories(${PKG_BONMIN_INCLUDE_DIRS} )
add_executable(bonminExample runnables/bonminExample.cpp)
target_link_libraries(bonminExample ${PKG_BONMIN_LDFLAGS})
附加信息:
cmake_minimum_required(VERSION 3.6)
project(MyProject CXX)
# The version number.
set (MyProject_VERSION_MAJOR 1)
set (MyProject_VERSION_MINOR 0)
set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/5.0.1/bin/clang" CACHE FILEPATH "Path to the used C compiler; default clang." FORCE)
set(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/5.0.1/bin/clang++" CACHE FILEPATH "Path to the used C++ compiler; default clang++." FORCE)
set(OPENMP_LIBRARIES "/usr/local/Cellar/llvm/5.0.1/lib" CACHE FILEPATH "Path to the OpenMP libraries." FORCE)
set(OPENMP_INCLUDES "/usr/local/Cellar/llvm/5.0.1/include" CACHE FILEPATH "Path to the OpenMP includes." FORCE)
## Set c++14
set(CMAKE_CXX_STANDARD 14)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif()
...
我在尝试 link Bonmin 时收到的错误消息是:
ld: framework not found -lAccelerate
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [/Users/<PATH>/myproject/bin/bonminExample] Error 1
make[1]: *** [src/CMakeFiles/bonminExample.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
详细信息:
[ 3%] Linking CXX executable /Users/<PATH>/myproject/bin/bonminExample
cd /Users/<PATH>/build_debug/src && /opt/local/bin/cmake -E cmake_link_script CMakeFiles/bonminExample.dir/link.txt --verbose=1
cd /Users/<PATH>/build_debug && /opt/local/bin/cmake -E cmake_depends "Unix Makefiles" /Users/<PATH>/myproject /Users/<PATH>/build_debug/googletest-src/googlemock /Users/<PATH>/build_debug /Users/<PATH>/build_debug/googletest-build/googlemock /Users/<PATH>/build_debug/googletest-build/googlemock/CMakeFiles/gmock_autogen.dir/DependInfo.cmake --color=
cd /Users/<PATH>/build_debug && /opt/local/bin/cmake -E cmake_depends "Unix Makefiles" /Users/<PATH>/myproject/ /Users/<PATH>/myproject/src /Users/<PATH>/build_debug /Users/<PATH>/build_debug/src /Users/<PATH>/build_debug/src/CMakeFiles/PGT.dir/DependInfo.cmake --color=
/usr/local/Cellar/llvm/5.0.1/bin/clang++ -fopenmp=libomp -Wno-unused-command-line-argument -DCOIN_USE_MUMPS_MPI_H -fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64 -DBONMIN_BUILD -march=native -g -Wall -ggdb -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/bonminExample.dir/runnables/BonminExample.cpp.o CMakeFiles/bonminExample.dir/bonminExample_autogen/mocs_compilation.cpp.o -o /Users/<PATH>/myproject/bin/bonminExample -L/usr/local/Cellar/llvm/5.0.1/lib -L/Users/<PATH>/external_libraries/ogdf20170723 -Wl,-rpath,/usr/local/Cellar/llvm/5.0.1/lib -Wl,-rpath,/Users/<PATH>/external_libraries/ogdf20170723 -L/Users/<PATH>/external_libraries/Bonming-1.8/build/lib -L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/x86_64 -L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/../../../x86_64 -L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3 -L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/../../.. -lbonmin -lCbcSolver -lCbc -lCgl -lOsiClp -lClpSolver -lClp -lcoinasl -lm -ldl -lOsi -lCoinUtils -lbz2 -lz -framework -lAccelerate -lm -lipopt -framework -lAccelerate -lm -ldl -lcoinmumps -framework -lAccelerate -lgfortranbegin -lgfortran -lSystem -lm -ldl -lOsi -lCoinUtils -lbz2 -lz -lipopt -lcoinmumps -lgfortranbegin -lgfortran -lSystem
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f googletest-build/googlemock/CMakeFiles/gmock_autogen.dir/build.make googletest-build/googlemock/CMakeFiles/gmock_autogen.dir/build
[ 4%] Automatic MOC for target gmock
cd /Users/<PATH>/build_debug/googletest-build/googlemock && /opt/local/bin/cmake -E cmake_autogen /Users/<PATH>/build_debug/googletest-build/googlemock/CMakeFiles/gmock_autogen.dir Debug
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f src/CMakeFiles/PGT.dir/build.make src/CMakeFiles/PGT.dir/build
ld: framework not found -lAccelerate
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [/Users/<PATH>/myproject/bin/bonminExample] Error 1
make[1]: *** [src/CMakeFiles/bonminExample.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f src/CMakeFiles/PGTIP.dir/build.make src/CMakeFiles/PGTIP.dir/build
有谁知道可能是什么问题,甚至有解决方案吗?
请注意,Bonmin 示例中的 make 文件为我提供了以下内容:
MBP:CppExample myname$ make VERBOSE=1
clang++ -fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64 -DBONMIN_BUILD `PKG_CONFIG_PATH=/Users/<PATH>/Bonmin-1.8/build/lib64/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/lib/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/share/pkgconfig:/opt/X11/lib/pkgconfig pkg-config --cflags bonmin` -c -o MyBonmin.o `test -f '../../../../Bonmin/examples/CppExample/MyBonmin.cpp' || echo '../../../../Bonmin/examples/CppExample/'`../../../../Bonmin/examples/CppExample/MyBonmin.cpp
clang++ -fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64 -DBONMIN_BUILD `PKG_CONFIG_PATH=/Users/<PATH>/Bonmin-1.8/build/lib64/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/lib/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/share/pkgconfig:/opt/X11/lib/pkgconfig pkg-config --cflags bonmin` -c -o MyTMINLP.o `test -f '../../../../Bonmin/examples/CppExample/MyTMINLP.cpp' || echo '../../../../Bonmin/examples/CppExample/'`../../../../Bonmin/examples/CppExample/MyTMINLP.cpp
bla=;\
for file in MyBonmin.o MyTMINLP.o; do bla="$bla `echo $file`"; done; \
clang++ -fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64 -DBONMIN_BUILD -o CppExample $bla `PKG_CONFIG_PATH=/Users/<PATH>/Bonmin-1.8/build/lib64/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/lib/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/share/pkgconfig:/opt/X11/lib/pkgconfig pkg-config --libs bonmin`
在从 PkgConfig
模块获得的 XXX_LDFLAGS
变量用于 target_link_libraries
调用之前,修改该变量:
string(REPLACE "-framework;" "-framework " PKG_BONMIN_LDFLAGS "${PKG_BONMIN_LDFLAGS}")
("${PKG_BONMIN_LDFLAGS}"
处的引号很重要。)
之后,-framework
选项将被正确处理:
target_link_libraries(... ${PKG_BONMIN_LDFLAGS})
解释
使用框架时,CMake 似乎无法正确地与 pkg-config
一起使用。提取时
-framework Acceletate
从 pkg-config
输出中,这 2 个词被解释为 单独的参数 。所以,当传递给 target_link_libraries
时:
target_link_libraries(... -framework Acceletate)
-l
根据命令的rules:
附加到第二个单词
ld .... -framework -lAccelerate
正确的命令调用应该是
target_link_libraries(... "-framework Acceletate")
而这正是上述string(REPLACE)
的目的:它用正常的space [=28]替换了-framework
选项后面的CMake参数定界符;
=].
我目前正在尝试 link Bonmin 在我的 macOS High Sierra (10.13.4) 项目中使用 cmake Xcode 版本 9.3。在描述设置之前,我应该提到 Bonmin 示例 (/PATH_TO_BONMIN/Bonmin/examples/CppExample) 使用包含的 make 文件进行编译。后面的示例我尝试在我的环境中开始工作,但它不起作用。因此,我认为必须存在不兼容性。
Bonmin 1.8 (https://www.coin-or.org/Tarballs/Bonmin/) 是在我的 Mac 上使用
构建的../configure -C --disable-shared F77="/usr/local/bin/gfortran" FFLAGS="-fexceptions -m64 -fbackslash" CFLAGS="-fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64" CXXFLAGS="-fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64"
我的 FindBonmin.cmake 使用来自“${BONMIN_LIBRARY_DIR}/pkgconfig”的包配置文件:
find_path(BONMIN_LIBRARY_DIR
NAMES libbonmin.a
HINTS ...
HINTS /usr/local/include/coin
HINTS ${BONMIN_ROOT_DIR}/include/coin
HINTS ${BONMIN_ROOT_DIR}/include
)
if(IS_DIRECTORY "${BONMIN_LIBRARY_DIR}/pkgconfig")
set(CMAKE_PREFIX_PATH "${BONMIN_LIBRARY_DIR}/pkgconfig")
set(ENV{PKG_CONFIG_PATH} "${BONMIN_LIBRARY_DIR}/pkgconfig")
else()
message("Directory ${BONMIN_LIBRARY_DIR}/pkgconfig does not exist!")
endif()
由此我得到以下信息:
${BONMIN_LIBRARY_DIR}/pkgconfig =
/Users/<PATH>/Bonmin-1.8/build/lib/pkgconfig
${PKG_BONMIN_INCLUDE_DIRS} =
/Users/<PATH>/Bonmin-1.8/build/include/coin;/Users/<PATH>/Bonmin-1.8/build/include/coin/ThirdParty;/Users/<PATH>/Bonmin-1.8/build/include/coin;/Users/<PATH>/Bonmin-1.8/build/include/coin/ThirdParty
${PKG_BONMIN_LDFLAGS} = -L/Users/<PATH>/Bonmin-1.8/build/lib;-L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/x86_64;-L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/../../../x86_64;-L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3;-L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/../../..;-lbonmin;-lCbcSolver;-lCbc;-lCgl;-lOsiClp;-lClpSolver;-lClp;-lcoinasl;-lm;-ldl;-lOsi;-lCoinUtils;-lbz2;-lz;-framework;Accelerate;-lm;-lipopt;-framework;Accelerate;-lm;-ldl;-lcoinmumps;-framework;Accelerate;-lgfortranbegin;-lgfortran;-lSystem
这个用于示例:
include_directories(${PKG_BONMIN_INCLUDE_DIRS} )
add_executable(bonminExample runnables/bonminExample.cpp)
target_link_libraries(bonminExample ${PKG_BONMIN_LDFLAGS})
附加信息:
cmake_minimum_required(VERSION 3.6)
project(MyProject CXX)
# The version number.
set (MyProject_VERSION_MAJOR 1)
set (MyProject_VERSION_MINOR 0)
set(CMAKE_C_COMPILER "/usr/local/Cellar/llvm/5.0.1/bin/clang" CACHE FILEPATH "Path to the used C compiler; default clang." FORCE)
set(CMAKE_CXX_COMPILER "/usr/local/Cellar/llvm/5.0.1/bin/clang++" CACHE FILEPATH "Path to the used C++ compiler; default clang++." FORCE)
set(OPENMP_LIBRARIES "/usr/local/Cellar/llvm/5.0.1/lib" CACHE FILEPATH "Path to the OpenMP libraries." FORCE)
set(OPENMP_INCLUDES "/usr/local/Cellar/llvm/5.0.1/include" CACHE FILEPATH "Path to the OpenMP includes." FORCE)
## Set c++14
set(CMAKE_CXX_STANDARD 14)
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
endif()
...
我在尝试 link Bonmin 时收到的错误消息是:
ld: framework not found -lAccelerate
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [/Users/<PATH>/myproject/bin/bonminExample] Error 1
make[1]: *** [src/CMakeFiles/bonminExample.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
详细信息:
[ 3%] Linking CXX executable /Users/<PATH>/myproject/bin/bonminExample
cd /Users/<PATH>/build_debug/src && /opt/local/bin/cmake -E cmake_link_script CMakeFiles/bonminExample.dir/link.txt --verbose=1
cd /Users/<PATH>/build_debug && /opt/local/bin/cmake -E cmake_depends "Unix Makefiles" /Users/<PATH>/myproject /Users/<PATH>/build_debug/googletest-src/googlemock /Users/<PATH>/build_debug /Users/<PATH>/build_debug/googletest-build/googlemock /Users/<PATH>/build_debug/googletest-build/googlemock/CMakeFiles/gmock_autogen.dir/DependInfo.cmake --color=
cd /Users/<PATH>/build_debug && /opt/local/bin/cmake -E cmake_depends "Unix Makefiles" /Users/<PATH>/myproject/ /Users/<PATH>/myproject/src /Users/<PATH>/build_debug /Users/<PATH>/build_debug/src /Users/<PATH>/build_debug/src/CMakeFiles/PGT.dir/DependInfo.cmake --color=
/usr/local/Cellar/llvm/5.0.1/bin/clang++ -fopenmp=libomp -Wno-unused-command-line-argument -DCOIN_USE_MUMPS_MPI_H -fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64 -DBONMIN_BUILD -march=native -g -Wall -ggdb -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/bonminExample.dir/runnables/BonminExample.cpp.o CMakeFiles/bonminExample.dir/bonminExample_autogen/mocs_compilation.cpp.o -o /Users/<PATH>/myproject/bin/bonminExample -L/usr/local/Cellar/llvm/5.0.1/lib -L/Users/<PATH>/external_libraries/ogdf20170723 -Wl,-rpath,/usr/local/Cellar/llvm/5.0.1/lib -Wl,-rpath,/Users/<PATH>/external_libraries/ogdf20170723 -L/Users/<PATH>/external_libraries/Bonming-1.8/build/lib -L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/x86_64 -L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/../../../x86_64 -L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3 -L/usr/local/lib/gcc/i686-apple-darwin8/4.2.3/../../.. -lbonmin -lCbcSolver -lCbc -lCgl -lOsiClp -lClpSolver -lClp -lcoinasl -lm -ldl -lOsi -lCoinUtils -lbz2 -lz -framework -lAccelerate -lm -lipopt -framework -lAccelerate -lm -ldl -lcoinmumps -framework -lAccelerate -lgfortranbegin -lgfortran -lSystem -lm -ldl -lOsi -lCoinUtils -lbz2 -lz -lipopt -lcoinmumps -lgfortranbegin -lgfortran -lSystem
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f googletest-build/googlemock/CMakeFiles/gmock_autogen.dir/build.make googletest-build/googlemock/CMakeFiles/gmock_autogen.dir/build
[ 4%] Automatic MOC for target gmock
cd /Users/<PATH>/build_debug/googletest-build/googlemock && /opt/local/bin/cmake -E cmake_autogen /Users/<PATH>/build_debug/googletest-build/googlemock/CMakeFiles/gmock_autogen.dir Debug
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f src/CMakeFiles/PGT.dir/build.make src/CMakeFiles/PGT.dir/build
ld: framework not found -lAccelerate
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [/Users/<PATH>/myproject/bin/bonminExample] Error 1
make[1]: *** [src/CMakeFiles/bonminExample.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f src/CMakeFiles/PGTIP.dir/build.make src/CMakeFiles/PGTIP.dir/build
有谁知道可能是什么问题,甚至有解决方案吗?
请注意,Bonmin 示例中的 make 文件为我提供了以下内容:
MBP:CppExample myname$ make VERBOSE=1
clang++ -fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64 -DBONMIN_BUILD `PKG_CONFIG_PATH=/Users/<PATH>/Bonmin-1.8/build/lib64/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/lib/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/share/pkgconfig:/opt/X11/lib/pkgconfig pkg-config --cflags bonmin` -c -o MyBonmin.o `test -f '../../../../Bonmin/examples/CppExample/MyBonmin.cpp' || echo '../../../../Bonmin/examples/CppExample/'`../../../../Bonmin/examples/CppExample/MyBonmin.cpp
clang++ -fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64 -DBONMIN_BUILD `PKG_CONFIG_PATH=/Users/<PATH>/Bonmin-1.8/build/lib64/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/lib/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/share/pkgconfig:/opt/X11/lib/pkgconfig pkg-config --cflags bonmin` -c -o MyTMINLP.o `test -f '../../../../Bonmin/examples/CppExample/MyTMINLP.cpp' || echo '../../../../Bonmin/examples/CppExample/'`../../../../Bonmin/examples/CppExample/MyTMINLP.cpp
bla=;\
for file in MyBonmin.o MyTMINLP.o; do bla="$bla `echo $file`"; done; \
clang++ -fno-common -no-cpp-precomp -fexceptions -arch x86_64 -m64 -DBONMIN_BUILD -o CppExample $bla `PKG_CONFIG_PATH=/Users/<PATH>/Bonmin-1.8/build/lib64/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/lib/pkgconfig:/Users/<PATH>/Bonmin-1.8/build/share/pkgconfig:/opt/X11/lib/pkgconfig pkg-config --libs bonmin`
在从 PkgConfig
模块获得的 XXX_LDFLAGS
变量用于 target_link_libraries
调用之前,修改该变量:
string(REPLACE "-framework;" "-framework " PKG_BONMIN_LDFLAGS "${PKG_BONMIN_LDFLAGS}")
("${PKG_BONMIN_LDFLAGS}"
处的引号很重要。)
之后,-framework
选项将被正确处理:
target_link_libraries(... ${PKG_BONMIN_LDFLAGS})
解释
使用框架时,CMake 似乎无法正确地与 pkg-config
一起使用。提取时
-framework Acceletate
从 pkg-config
输出中,这 2 个词被解释为 单独的参数 。所以,当传递给 target_link_libraries
时:
target_link_libraries(... -framework Acceletate)
-l
根据命令的rules:
ld .... -framework -lAccelerate
正确的命令调用应该是
target_link_libraries(... "-framework Acceletate")
而这正是上述string(REPLACE)
的目的:它用正常的space [=28]替换了-framework
选项后面的CMake参数定界符;
=].