Issue linking to libpng when trying to make pngnq on Linux - linker

I am trying to install pngnq, which relies on libpng >= 1.2.8. I have installed libpng 1.5.7 via ./configure, make, sudo make install (without problems), because the libpng version in the Software Center was too old. I am now trying to install pngnq via ./configure, make, sudo make install (again, because Software Center version is too old), but am getting stuck at the make step on error messages which I believe pertain to libpng linking. A small sample of the error messages:
undefined reference to `png_destroy_write_struct'
undefined reference to `png_convert_from_time_t'
undefined reference to `png_set_PLTE'
I have limited experience with installing software manually on Linux, and so am not really sure what the next step is in diagnosing the problem. I've done substantial searching, but haven't really found anything targeted at the issue I'm having. Based on a forum post on a similar-ish issue I've done an ls on /usr/local/lib directory and found:
libpng15.a libpng15.so.15 libpng.la libpng15.la
libpng15.so.15.7.0 libpng.so libpng15.so libpng.a
though I don't know if that's actually any use in diagnosing/ruling out certain problems. Can anyone advise what might be wrong, keeping in my my minimal experience with compiling code on Linux?
Edit:
As requested, here is a sample of the trace beginning at the make call:
bryce#whatever:~/Downloads/pngnq-1.1$ make
Making all in src
make[1]: Entering directory `/home/bryce/Downloads/pngnq-1.1/src'
make all-am
make[2]: Entering directory `/home/bryce/Downloads/pngnq-1.1/src'
gcc `libpng-config --I_opts` -Wall --pedantic -std=gnu99 -g -O2 `libpng-config
--ldflags` -lz -o pngnq pngnq.o neuquant32.o rwpng.o -lm -lz
pngnq.o: In function `pngnq':
/home/bryce/Downloads/pngnq-1.1/src/pngnq.c:518: undefined reference to `png_get_gAMA'

Sounds like includes don't match the library. Double check to see if you've got png.h in /usr/include or libpng* in /usr/lib/.
Also show the gcc line that shows up before you see the error. That might point to the issue.

Related

How to modify CMakeList.txt: library found, but there are linking errors

I am creating a C library which is to be built with cmake, using Mac OS for development. In the CMakeList.txt, I have the following
#htslib
find_package(htslib REQUIRED)
include_directories(${HTSLIB_INCLUDE_DIR})
target_link_libraries(projectname ${HTSlib_LIBRARIES})
which outputs upon cmake ..
Found hstlib
However, upon make, I'm getting linker errors:
clang: error: linker command failed with exit code 1 (use -v to see invocation)
So...it can find the library, and the library is definitely installed with sudo make install, but there are linking errors only with this library.
(1) I'm guessing that find_package(htslib REQUIRED) is finding something else. How do I find out what?
(2) How do I explicitly write in CMakeList.txt to find the library which I know has been installed correctly?
Use VERBOSE=1 make to see the linker output. Search for -lhtslib
Read the documentation for the specific Find<LIB>.cmake.
Your specific questions:
"How do I find what CMake found": Use cmake-gui or ccmake. They both show the same info, but one is a GUI and the other is a Curses interface. In the advanced mode ("t" on ccmake) you will find all the variables for the searched packages. Additionally, you may use MESSAGE(STATUS "Found htslib at: ${htslib_LIBRARIES}").
"How to explicitly write in CMakeLists.txt where the library is?" Please, do not do that! CMake is meant for abstracting exactly this kind of information away. You have two options, first the good one: configure cmake on the command line (or in the GUIs mentioned above) to get a CMAKE_MODULES_PATH or a more specific hint to the library -D htslib_PATH=/usr/local/.../ (pointing to the dir where libhts.dylib resides). The worse solution would be to provide a HINT to find_package. find_package(htslib REQUIRED PATH /usr/local/lib) or find_package(htslib REQUIRED HINT /usr/local/lib /some/second/path/where/it/may/be).
Solution
Your linked project has a custom FindHTSlib.cmake link. This one uses pkg_config to configure the library. To replicate your problem, I used brew to install htslib. The pkg-config file can be found (for me, but brew info htslib tells you) under /usr/local/Cellar/htslib/1.8/lib/htslib.pc. So, let's give CMake the required hint.
I couldn't test this, because for me it found the htslib package directly with no further hints.
git clone https://github.com/D-Lo/bamdb # I am using version f5f03d0
mkdir -p bamdb/build; cd bamdb/build
brew install ck htslib lmdb
cmake .. # -G Ninja recommended, but needs brew install ninja
make # lot's of missing symbols
I would recommend to change in CMakeLists.txt the minimum required version of CMake from 2.8 to 3.10 (or at least 3.6).
This is the error I get:
[ 62%] Linking C shared library libbamdb.dylib
/usr/local/Cellar/cmake/3.11.1/bin/cmake -E cmake_link_script CMakeFiles/libbamdb.dir/link.txt --verbose=1
/Library/Developer/CommandLineTools/usr/bin/cc -Wall -g -std=gnu99 -fPIC -dynamiclib -Wl,-headerpad_max_install_names -o libbamdb.dylib -install_name #rpath/libbamdb.dylib CMakeFiles/libbamdb.dir/src/bam_api.c.o CMakeFiles/libbamdb.dir/src/bam_lmdb.c.o CMakeFiles/libbamdb.dir/src/bamdb.c.o
Undefined symbols for architecture x86_64:
"_bam_destroy1", referenced from:
_get_bam_row in bam_api.c.o
_deserialize_func in bam_lmdb.c.o
This can be fixed by adding the following line in the CMakeLists.txt, after the line add_library(libbamdb ${SOURCES}):
target_link_libraries(libbamdb ${LIBS})
Some further notes: you now have a library with a main function. This is because ${SOURCES} is used to build the executable and the library. That can have unexpected side effects. Unless it's needed, don't do it.

how do i use cmockery in my projects

I was searching for a way to create mocking objects with c-code until I stumbled upon cmockery.
For me it seems to be the best mocking software available since it doesn't have a lot of dependencies.
I'm working in ubuntu and downloaded the tarball cmockery from https://code.google.com/p/cmockery/downloads/list
I ran the ./configure, make and make install.
I am able to execute the given examples but I just can't figure out how to get it working on my own projects. I had a look at the configure and makefile to try and find out how they did it, but that was no success. I think it's the linking that's causing my problems.
Files of cmockery can be find at:
/usr/local/include/google/cmockery.h
/usr/local/lib/libcmockery.la
/usr/local/lib/libcmockery.a
/usr/local/lib/libcmockery.so.0.0.0
/usr/local/lib/libcmockery.so.0
/usr/local/lib/libcmockery.so
I tried copying the example files calculator.c and calculater_test.c to a separate directory and compile them there.
This is what I did:
gcc -c -o calculator.o calculator.c
gcc -c -o calculator_test.o calculator_test.c -I /usr/local/include/google/
gcc -o run *.o -L /usr/local/lib/
At the last step I got a lot of undefined references to all functions specific to cmockery and the error:
collect2: error: ld returned 1 exit status
I guess I'm messing things up with the linker but I can't find anywhere how it should be done correctly.
You are missing -lcmockery:
gcc -o run *.o -L /usr/local/lib/ -lcmockery

problems compiling TCC on ubuntu for arm

I tried to compile tcc for ARM using gcc 4.6.3 . but I got following error while compiling in both shared/static lib mod :
root#localhost:/p/tcc/tcc# make
gcc -o tcc tcc.o libtcc.so.1.0 -lm -ldl -Wall -g -O2 -fno-strict-aliasing -Wno-pointer-sign -Wno-sign-compare -D_FORTIFY_SOURCE=0 -Wl,-rpath,"/usr/local/lib" libtcc.so.1.0: undefined reference to `vrotb'
collect2: ld returned 1 exit status
make: *** [tcc] Error 1
I am using lastest branch from tcc github
Just checked it on raspberry pi (ARMv6 CPU). https://github.com/TinyCC/TinyCC repository, removed static qualifier from vrotb function in tccgen.c (line 945). It builds and passes 'hello world'.
Since that's obvious mistake likely to be introduced by some change that they forgot to adapt for ARM - i suggest performing further tests to ensure it works as intended. Bug report should be filed - probably on github.
I know it is little confusing, but your problem is that you are using wrong repository. Fabrice Bellard does not work any more on TinyCC (see http://bellard.org/tcc/). He keeps his repositories for personal/historical reasons. However all development has moved to http://repo.or.cz/w/tinycc.git. To confuse things even more the 0.9.26 release from Fabrice's web site is actually from the http://repo.or.cz/w/tinycc.git repository, and not Fabrice's own. But this is all just communication issue. In short you should use new repository. On the repository web site is a link to a mailing list where you should report any problems in case the new repo code does not compile.

C Program Compilation issue involving Glib2 library?

I'm trying to compile the following project on a remote server.
I've git cloned the project on a folder called 'scode'.
The project requires glib2 and gsl libraries. Since I'm trying to compile on a remote server, I do not have sudo privileges. So I can't use a tool to install glib2 and gsl for me.
As a result, I've manually compiled both gsl and gslib2 under the folders 'scode/gsl' and 'scode/glib'.
I've had to modify the Makefile and add absolute paths to these directories as -I options.
Nonetheless, when I try to compile the final executable. I get the following error:
[dyuret#psglogin scode]$ make
gcc -O3 -D_GNU_SOURCE -Wall -std=c99 -I. -I /home-2/dyuret/scode/gsl
-I /home-2/dyuret/scode/glib/ pkg-config --cflags glib-2.0 scode.o svec.o pkg-config --libs glib-2.0 -lm -lgsl -lgslcblas -o scode
//home-2/dyuret/scode/glib/glib/libglib-2.0.la: file not recognized:
File format not recognized
collect2: error: ld returned 1 exit status make: * [scode] Error 1
I've researched the issue a bit. This link looks informative but I can't quite decipher what the author is saying, as I'm not that experienced with compilers, libtools and the compilation flow in general.
Any help would be much appreciated. I've already spent some time on this issue and I haven't been able to make much progress.
It sounds as if what you did in order to compile the libraries in non-default (i.e. non-system) locations was maybe wrong.
For packages using autoconf (i.e. that have a configure script in the source root) you're supposed to use the --prefix option to ./configure to set the target location where you want the package installed.
With packages building shared libraries, it's often essential to do the make install step, which it sounds as if you maybe didn't do.
Sorry for being vague, these things are a bit complicated.
Someone at my group helped me with the problem. Here're the steps he roughly carried out:
(1) Manually installed glib and additional libraries at $HOME directory - i.e. $HOME/lib, $HOME/include.
(1.1) I think he did this by './configure prefix=$HOME', 'make', 'make install'.
(2) Got rid of `pkg_config` usage, which was causing the problem I outlined originally. Here are his new CLFAGS and LIBS variables:
CFLAGS=-O3 -D_GNU_SOURCE -Wall -std=c99 -I. -I$$HOME/include -I$$HOME/include/glib-2.0 -I$$HOME/lib/glib-2.0/include
LIBS=-lglib-2.0 -lm -lgsl -lgslcblas -L$$HOME/lib -L/usr/local/cuda/lib64 -lcudart
After this, the code compiled without additional problems.

ld: library not found for -lplot

I am new here. I recently installed plotutils-dev on my mac using fink, but when I try to compile a little program I have by doing
gcc -g -o atomos.o atomos.c -lplot
it says
ld: library not found for -lplot
collect2: ld returned 1 exit status
I have searched the problem on the web with little success. The only thing I know is that when I type
dpkg -S libplot.dylib
it says
plotutils-dev: /sw/lib/libplot.dylib
which I believe it means I have installed libplot on my mac. So I don't know what is the problem. Any help is welcomed. I am a beginner so It would be nice if some guidelines are provided in a user-friendly way.
The linker can't find the libplot library. I'm not familiar with mac, but with gcc you can tell it the path to the library with the -L flag, e.g.:
gcc -g -o atomos.o atomos.c -lplot -L/sw/lib/
(I'm guessing at that path, but you can probably figure out the path to the library if that isn't right.)
Also, it's probably a typo in your question, but I changed it to -lplot (note extra -l). You want the -l to link with the plot library.

Resources