Linking not working in homebrew's cmake since Mojave - c++

I've reproduced this symptom on two computers now, cmake seems to no longer look in /usr/local/lib (or more properly, $(brew --prefix)/lib) for Homebrew-provided libraries since upgrading my machine to macOS Mojave.
Although there are ways to circumvent this (e.g. search for homebrew prefix using EXECUTE_PROCESS; add the result to LINK_LIBRARIES(...) command) none are ideal. What changed in Mojave to break this behavior?
The temporary workaround is to add the following to CMakeLists.txt:
# WARNING: Don't hard-code this path
LINK_DIRECTORIES(/usr/local/lib)
I've already tried brew doctor and updated all homebrew packages to no avail.
The specific error that cmake (make) shows is:
ld: library not found for -l<somelib>
I've asked the question on the Homebrew forums and the Apple developer forums.

Ran into a related (?) issue while trying to pip install psycopg2 in a Django app under OS X Mojave (10.14). I was getting the following errors:
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: command 'clang' failed with exit status 1
The short explanation: « As of High Sierra, /usr/local is no longer
chown-able... »
The solution: change permissions for /usr/local to allow Homebrew to
create links.
I adapted the solution to my needs. Then I was finally able to run pip install psycopg2. Here is the sequence of commands (update: inside your project root i.e. where you see manage.py).
First
sudo chown -R $(whoami) $(brew --prefix)/*
Then
brew reinstall openssl
export LDFLAGS="-L/usr/local/opt/openssl/lib"
export CPPFLAGS="-I/usr/local/opt/openssl/include"
pip install psycopg2

I've isolated this to the following change in the VERBOSE=1 make logs...
High Sierra (<=10.13) and below did NOT use the -isysroot command.
Mojave (>=10.14) DOES use the -isysroot command.
From gnu.org:
-isysroot <dir>
This option is like the --sysroot option, but applies only to header files (except for Darwin targets, where it applies to both header files and libraries). See the --sysroot option for more information.
So this flag specifically clobbers the lib search path only on Apple. This results in the compilation never looking in the standard ld locations, which can be seen by typing ld -v dummy.
Library search paths:
/usr/lib
/usr/local/lib
Why does cmake do this? My thought is it was to fix the /usr/local/include issues introduced with the new Mojave SDK behavior.
Unfortunately, I can't find a cmake compile flag to add the default library search paths back in. For now the only solution I've found is to add the following to my project:
IF(APPLE)
# Fix linking on 10.14+. See https://stackoverflow.com/questions/54068035
LINK_DIRECTORIES(/usr/local/lib)
ENDIF()
I'm not sure if this is a behavior that warrants an upstream cmake patch. If there is a better solution, please provide it.

Related

CMake/Make cannot find libusb

I'm new to C/C++ and am trying to build and run ttwatch from github locally on an Ubuntu machine (Trusty Tahr). Instructions include installing some libraries first: cmake, openssl, curl, libusb, and include a note to install the "-dev" versions (eg. libssl-dev, libcurl-dev, libusb-1.0-0-dev). I'm having some trouble with libusb. I see questions about this all over the internet, but haven't yet found a solution that works.
Running cmake . appears to work fine:
meowmeow#kittytown:~/code/ttwatch$ cmake .
-- Enabled daemon function
-- Found libusb-1.0:
-- - Includes: /usr/include/libusb-1.0
-- - Libraries: /usr/lib/x86_64-linux-gnu/libusb.so
-- Configuring done
-- Generating done
-- Build files have been written to: /home/meowmeow/code/ttwatch
But running make shows that libusb is not being located properly:
meowmeow#kittytown:~/code/ttwatch$ make
[ 42%] Built target libttbin
[ 42%] Built target libttwatch
[ 42%] Built target ttbincnv
[ 42%] Built target ttbinmod
[ 42%] Built target manifest
Linking CXX executable ttwatch
CMakeFiles/ttwatch.dir/src/ttwatch.c.o: In function `main':
/home/meowmeow/code/ttwatch/src/ttwatch.c:1618: undefined reference to `libusb_init'
/home/meowmeow/code/ttwatch/src/ttwatch.c:1796: undefined reference to `libusb_exit'
...
If I check /usr/includes/, I see libusb:
meowmeow#kittytown:~/code/ttwatch$ ls /usr/include/libusb-1.0/libusb.h
/usr/include/libusb-1.0/libusb.h
And dpkg shows:
meowmeow#kittytown:~/code/ttwatch$ dpkg -L libusb-1.0-0-dev
/.
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/pkgconfig
/usr/lib/x86_64-linux-gnu/pkgconfig/libusb-1.0.pc
/usr/lib/x86_64-linux-gnu/libusb-1.0.a
/usr/share
/usr/share/doc
/usr/share/doc/libusb-1.0-0-dev
/usr/share/doc/libusb-1.0-0-dev/copyright
/usr/include
/usr/include/libusb-1.0
/usr/include/libusb-1.0/libusb.h
/usr/lib/x86_64-linux-gnu/libusb-1.0.so
/usr/share/doc/libusb-1.0-0-dev/README
/usr/share/doc/libusb-1.0-0-dev/changelog.Debian.gz
meowmeow#kittytown:~/code/ttwatch$ dpkg -L libusb-1.0-0
/.
/lib
/lib/x86_64-linux-gnu
/lib/x86_64-linux-gnu/libusb-1.0.so.0.1.0
/usr
/usr/share
/usr/share/doc
/usr/share/doc/libusb-1.0-0
/usr/share/doc/libusb-1.0-0/README
/usr/share/doc/libusb-1.0-0/copyright
/usr/share/doc/libusb-1.0-0/changelog.Debian.gz
/lib/x86_64-linux-gnu/libusb-1.0.so.0
The file ttwatch/includes/libttwatch.h includes libusb as #include <libusb.h>, and I've tried modifying that to #include <libusb-1.0/libusb.h>, in hopes of better matching my /usr/includes/ files, but that didn't change the error output.
Any help would be greatly appreciated!
EDIT:
Using make VERBOSE=1does show -lusb, and not -lusb-1.0:
...
/usr/bin/c++ -g CMakeFiles/ttwatch.dir/src/ttwatch.c.o CMakeFiles/ttwatch.dir/src/log.c.o CMakeFiles/ttwatch.dir/src/options.c.o CMakeFiles/ttwatch.dir/src/json.c.o CMakeFiles/ttwatch.dir/src/download.c.o CMakeFiles/ttwatch.dir/src/firmware.c.o CMakeFiles/ttwatch.dir/src/misc.c.o CMakeFiles/ttwatch.dir/src/get_activities.c.o CMakeFiles/ttwatch.dir/src/update_gps.c.o CMakeFiles/ttwatch.dir/src/set_time.c.o -o ttwatch -rdynamic libttwatch.a libttbin.a -lusb -lssl -lcrypto -lcurl
And libusb.so appears to exist:
meowmeow#kittytown:~/code/ttwatch$ dpkg-query -S /usr/lib/x86_64-linux-gnu/libusb.so
libusb-dev: /usr/lib/x86_64-linux-gnu/libusb.so
I tried uninstalling libusb-dev (sudo apt-get remove libusb-dev) and installed libusb-1.0 (sudo apt-get install libusb-1.0) to see if that would solve the issue. I now have a /usr/lib/x86_64-linux-gnu/libusb-1.0.so (note the 1.0) instead, but am now getting this from make:
make[2]: *** No rule to make target /usr/lib/x86_64-linux-gnu/libusb.so', needed by ttwatch'. Stop.
I was not aware that Debian has the packages libusb-dev and
libusb-1.0-dev. From the package information I cannot tell why there are 2
packages for the same library, perhaps libusb-dev is an older version with a
different API and other packages might still have that as a dependency. So
removing the package might not be a good idea, unless you don't care/need
packages depending on libusb-dev, in which case you can do apt-get purge
libusb-dev && apt-get autoremove. Be ware that this might uninstall
packages that you need. So do it only if you know what you are doing.
I did not expect that Debian allows you to install both packages at the same
time, but this could be if the APIs of both libraries are different and don't
conflict with each other.
This seems to confuse cmake, which somehow cannot handle when both libraries
are simultaneously installed. I've gone through the issues page and I
haven't found an issue relating to that. So if you cannot manage to build it,
I'd suggest that you go to the issue page, if you don't have an github
account, create one and leave a bug report about building the package when
libusb-dev and libusb-1.0-dev are simultaneously installed.
Another option would be to make a small modification in the file cmake_modules/FindLibUSB.cmake before you do
$ mkdir build && cd build
$ cmake ..
Find the line find_library(LIBUSB_1_LIBRARY, on the current stable version it is line 62. The next line is NAMES
and the next line is usb-1.0 usb. Remove the usb from that, so that
find_library only searches for libusb-1.0. Save the file and then you can do
$ mkdir build && cd build
$ cmake ..
This should fix the problem.

compiling code with opencv - /usr/bin/ld: cannot find -lippicv

When compiling some code with opencv I get this error
# g++ txtbin-03.1.cpp -o txtbin `pkg-config opencv --cflags --libs`
/usr/bin/ld: cannot find -lippicv
collect2: error: ld returned 1 exit status
installing opencv
# apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
# apt-get install libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libjasper-dev libdc1394-22-dev
# cd /var/bin && git clone https://github.com/Itseez/opencv.git && cd opencv
# cmake . && make -j2 && make install
In my case, all it took was to copy libippicv.a from the OpenCV SDK to /usr/local/lib:
sudo cp 3rdparty/ippicv/unpack/ippicv_lnx/lib/intel64/libippicv.a /usr/local/lib/
Recompiling whole library isn't necessary, especially if you don't need this library. I found great and instantly working solution here. In case link expired or broke:
The solution is simply to remove -lippicv from opencv pkg-config configuration file. So you have to locate opencv.pc file, which default is in /usr/local/lib/pkgconfig/ directory. Then from section Libs: just remove aforementioned library.
Recompile OpenCv using following option:
cmake -DWITH_IPP=ON . && make -j $(nproc) && make install
libippicv.a is a third party library, so you need to explicitly provide it during compilation or make it part of your execution environment.
It is located in ~/OpenCV/opencv-3.1.0/3rdparty/ippicv/unpack/ippicv_lnx/lib/intel64/
Also, provide cmake -DWITH_IPP=ON at the time of Makefile generation.
I was running into the same problem while trying to install the opencv_contrib repository (opencv-3.1.0/Ubuntu 16.04), and none of the solutions worked (I tried to make OpenCV with flag WITH_IPP=ON, but somehow OpenCV 3.1.0 failed to download the ippicv library(?) and there was no error prompt so I only figured this out when I tried to locate ippicv in terminal).
My solution was to download another OpenCV build (3.0.0 worked for me), make + make install with flag WITH_IPP=ON, and then copy the downloaded ippicv library (which should be located in /usr/local/share/OpenCV/3rdparty/lib/libippicv.a by now) to /usr/local/lib/.
I don't know if this is a known bug in OpenCV 3.1.0, but this one is definitely worth keeping an eye out for.

c++ LAPACK library not detected whereas it's installed

I have installed the lapack library using the following commands:
sudo apt-get install liblapack-dev
In synaptic I have checked if everything was installed and it sounds good:
I would like to compile the g2o library which use liblaback but by doing cmake I have the following output:
CMake Error at cmake_modules/FindLAPACK.cmake:247 (message): A
required library with LAPACK API not found. Please specify library
location. Call Stack (most recent call first): CMakeLists.txt:75
(FIND_PACKAGE)
-- Configuring incomplete, errors occurred!
I'm pretty sure that It's not because the CmakeList file and all the Cmake file including for example the FindLAPACK.cmake (can find it there) file because I remember to have compiled it well before using another computer with Ubuntu 14.04.
So now I don't know what is the problem. I tried to uninstall, purge and then install it again but still the same issue.
I also checked the /etc/ld.so.conf in case and it contains
include /etc/ld.so.conf.d/*.conf
/usr/local/lib
I did then to be sure
sudo ldconfig -p
I noticed that the library is on /usr/lib
For example:
/usr/lib/liblapack.so
/usr/lib/liblapack.so.3
/usr/lib/liblapack.so.3gf
/etc/alternatives/liblapack.so /etc/alternatives/liblapack.so.3
/etc/alternatives/liblapack.so.3gf /usr/lib/liblapack.so
/usr/lib/liblapack.so.3 /usr/lib/liblapack.so.3gf
/usr/lib/atlas-base/atlas/liblapack.so
/usr/lib/atlas-base/atlas/liblapack.so.3
/usr/lib/atlas-base/atlas/liblapack.so.3.0
/usr/lib/lapack/liblapack.so /usr/lib/lapack/liblapack.so.3
/usr/lib/lapack/liblapack.so.3.0
/var/lib/dpkg/alternatives/liblapack.so
/var/lib/dpkg/alternatives/liblapack.so.3
If I take a look on the Cmake file error, I have those lines inside:
/usr/bin/ld: /usr/local/lib/liblapack.a(xerbla.f.o): undefined
reference to symbol '_gfortran_string_len_trim##GFORTRAN_1.0'
//usr/lib/x86_64-linux-gnu/libgfortran.so.3: error adding symbols: DSO
missing from command line collect2: error: ld returned 1 exit status
But I checked and Gfortran is well installed also.
Do you have any idea ? I getting crazy about it.

Installing Moses Translation Software. Error message: "ld: library not found for -lboost_thread"

I am installing the Moses Translation Software on my Mac OS X 10.9.5 with Xcode 6.1. The instructions say that I need g++ and Boost installed. Once I do that, I git clone, "cd" into the directory, and then type ./bjam -j8. First, I verified I have the prerequisites. First, g++ (I just clicked the TAB to see what was available):
$ g++
g++ g++-4.9
Then boost:
$ brew install boost
Warning: boost-1.56.0 already installed
Then I tried installing:
$ ./bjam -j8
Tip: install tcmalloc for faster threading. See BUILD-INSTRUCTIONS.txt for more information.
mkdir: bin: File exists
...patience...
...patience...
...found 4469 targets...
...updating 155 targets...
darwin.link lm/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi/query
ld: library not found for -lboost_thread
clang: error: linker command failed with exit code 1 (use -v to see invocation)
// Additional error messages...
...failed darwin.link mert/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi/util_test...
...skipped <pmert/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi>util_test.passed for lack of <pmert/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi>util_test...
darwin.link mert/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi/vocabulary_test
ld: library not found for -lboost_thread
clang: error: linker command failed with exit code 1 (use -v to see invocation)
"g++" -o "mert/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi/vocabulary_test" "mert/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi/VocabularyTest.o" "mert/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi/libmert_lib.a" -lboost_unit_test_framework -llzma -lbz2 -ldl -lboost_system -lz -lboost_thread -lm -liconv -g -Wl,-dead_strip -no_dead_strip_inits_and_terms
...failed darwin.link mert/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi/vocabulary_test...
...skipped <pmert/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi>vocabulary_test.passed for lack of <pmert/bin/darwin-4.2.1/release/debug-symbols-on/link-static/threading-multi>vocabulary_test...
...failed updating 72 targets...
...skipped 83 targets...
The build failed. If you need support, run:
./jam-files/bjam -j8 --debug-configuration -d2 |gzip >build.log.gz
then attach build.log.gz to your e-mail.
You MUST do 3 things before sending to the mailing list:
1. Subscribe to the mailing list at http://mailman.mit.edu/mailman/listinfo/moses-support
2. Attach build.log.gz to your e-mail
3. Say what is the EXACT command you executed when you got the error
ERROR
There's a ton of error messages not shown (condensed into "// Additional error messages"), and they are all of the form "ld: library not found for -lboost_thread". So it's clear that something can't find a boost-related library, but I don't know how to fix this. Does anyone have suggestions? I literally just copied a couple of lines from the installation instructions, and Moses is popular enough such that an obvious error in the installation instructions would have been caught long ago.
Additional comment: On the installation instructions page, they list a command where they can force an installer to find the boost library:
./bjam --with-boost=~/workspace/temp/boost_1_55_0 -j8
My boost is in
/usr/local/Cellar/boost/1.56.0/
I tried substituting the --with-boost= argument with the above file path, but that did not work either (I got the same errors).
I'm going to post this on the Moses mailing list but I'd also want to ask here because I have gotten this same error ("library not found ... clang: error: linker command failed with exit code 1") with other software and it would be helpful for me to learn a general strategy for making sure that clang can find my libraries.
This package expects a non-standard layout of boost (or maybe that's the standard liayout for installed boost on many systems, but it certainly isn't the default layout for boost in my working directories):
bjam --help says:
--with-boost=/path/to/boost
If Boost is in a non-standard location, specify it here. This directory is
expected to contain include and lib or lib64.
When my Boost build tree is in
/home/sehe/custom/boost/boost // headeers
/home/sehe/custom/boost/stage
/home/sehe/custom/boost/stage/lib // libraries
I have created a "forwarding" directory - so I'm not required to install boost:
mkdir /tmp/boost-moses
cd /tmp/boost-moses/
ln -sfv /home/sehe/custom/boost/stage/lib lib
ln -sfv /home/sehe/custom/boost include
Now I could trigger a build in the mosesdecoder directory with
./bjam --with-boost=/tmp/boost-moses
It's not said here which Moses version ComputerScientist compiled, but his last comment hit the nail. When I was about to compile version 2.1.1, I needed to rewrite Jamroot file and jam-files/boost-build/tools/mpi.jam and change all the boost_mpi mentions to boost_mpi-mt. It seems to me that boost-1.55 used different library style then boost-1.56 and Moses was in that version adapted to 1.55.
However I am not able to compile Moses 3.0 with either boost-1.55 or boost-1.56 now because of undefined reference to boost::filesystem::path::stem().
Unfortunatelly I can not post this as a comment to previous answer...

Installing gevent on Mavericks (Enthought Canopy python)

Has anyone had any luck building gevent 1.0 in Mavericks?
I've tried the following:
pip (as recommended on the gevent package index)
easy_install
compiling from source
I keep getting the same error when building 'gevent.core':
...
building 'gevent.core' extension
creating build/temp.macosx-10.6-i386-2.7/gevent
Compiling with an SDK that doesn't seem to exist: /Developer/SDKs/MacOSX10.6.sdk
Please check your Xcode installation
gcc -DNDEBUG -g -O3 -arch i386 -isysroot /Developer/SDKs/MacOSX10.6.sdk -U__llvm__ -
DLIBEV_EMBED=1 -DEV_COMMON= -DEV_CHECK_ENABLE=0 -DEV_CLEANUP_ENABLE=0 -DEV_EMBED_ENABLE=0
-DEV_PERIODIC_ENABLE=0 -Ibuild/temp.macosx-10.6-i386-2.7/libev -Ilibev -
I/Applications/Canopy.app/appdata/canopy-1.2.0.1610.macosx-
x86/Canopy.app/Contents/include/python2.7 -c gevent/gevent.core.c -o build/temp.macosx-
10.6-i386-2.7/gevent/gevent.core.o
clang: warning: no such sysroot directory: '/Developer/SDKs/MacOSX10.6.sdk'
In file included from gevent/gevent.core.c:17:
/Applications/Canopy.app/appdata/canopy-1.2.0.1610.macosx-
x86/Canopy.app/Contents/include/python2.7/Python.h:33:10: fatal error:
'stdio.h' file not found
#include <stdio.h>
^
1 error generated.
error: command 'gcc' failed with exit status 1
Seems to be a problem with XCode. I made sure I have the XCode (v. 5.0.2) command line tools installed with:
xcode-select --install
But that didn't seem to change anything. Apparently I'm not alone with this problem (a missing /Developer/SDKs/MacOSX10.6.sdk), but I'd like to stick with Enthought's Canopy version of python if I can (and have already spent too much time combing the Apple Developer site to try download MacOSX10.6.sdk directly).
Any suggestions that don't involve starting over with a macport'ed python? Thanks!
IIUC, Apple pulled a fast one on the latest XCode, such that gcc is no longer actually gcc, but is symlinked to clang, which is not compatible with standard Pythons, including Canopy's.
It should work better if you install Xcode 3.2.1 Developer Tools from https://developer.apple.com/downloads/index.action
For me the hint on gevent website helped:
pip install cython git+git://github.com/gevent/gevent.git#egg=gevent