1

I am currently trying to link Bonmin using cmake in my project under macOS High Sierra (10.13.4) with Xcode version 9.3. Before I describe the setup I should mention that the Bonmin example (/PATH_TO_BONMIN/Bonmin/examples/CppExample) compiles with the included make files. Later example I try to get to work in my environment, but it is not working. Thus, I think there must be an incompatibility.

Bonmin 1.8 (https://www.coin-or.org/Tarballs/Bonmin/) was build on my Mac using

../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"

My FindBonmin.cmake uses the package configuration files from "${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()

From this I get the following:

${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

This is used for the example:

include_directories(${PKG_BONMIN_INCLUDE_DIRS} )
add_executable(bonminExample runnables/bonminExample.cpp)
target_link_libraries(bonminExample ${PKG_BONMIN_LDFLAGS})

Additional information:

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

...

The error message I get, while trying to link Bonmin is:

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

With the details:

[  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

Does anybody know what might be an issue or even has a solution to it?

Note that the make file from the Bonmin example gives me the following:

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`
Franzi
  • 315
  • 2
  • 9
  • 1
    Please, add command line which causes given error. (You may see command lines with make `VERBOSE=1`). – Tsyvarev Apr 11 '18 at 10:52
  • I added the verbose details. I think the problem is that it adds it like that "-framework -lAccelerate" instead of "-framework Accelerate". However, I could not find a solution for that or have an idea to add it like in the example make, which I added at the end of the post. – Franzi Apr 13 '18 at 11:10
  • Thanks for fixing quoutation in my answer's code. But next time, before changing the other's code, drop the comment to the post about the problem in it. Otherwise you risk you edit to be rejected. As a person who asks the question, you may freely comment on its answers irrespective of your reputation. – Tsyvarev Apr 16 '18 at 14:19
  • Okay. Sorry, I thought it is easier and helps others to understand it faster. Next time I will just comment on it. Thanks twice! – Franzi Apr 16 '18 at 14:25

1 Answers1

1

Before XXX_LDFLAGS variable, obtained from PkgConfig module, is used in target_link_libraries call, modify that variable:

string(REPLACE "-framework;" "-framework " PKG_BONMIN_LDFLAGS "${PKG_BONMIN_LDFLAGS}")

(The quotation marks at "${PKG_BONMIN_LDFLAGS}" are important.)

After that, -framework option will be processed correctly:

target_link_libraries(... ${PKG_BONMIN_LDFLAGS})

Explanations

It seems that CMake incorrectly works with pkg-config when framework is used. When extract

-framework Acceletate

from the pkg-config output, these 2 words are interpreted as separate arguments. So, when passed to target_link_libraries:

target_link_libraries(... -framework Acceletate)

-l is appended to the second word according to the command's rules:

ld .... -framework -lAccelerate

Proper command's call should be

target_link_libraries(... "-framework Acceletate")

And this is exactly the purpose of above-mentioned string(REPLACE): It replaces CMake arguments delimiter ;, following -framework option, with normal space .

Community
  • 1
  • 1
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153