Xcode 7.1 not linking from /usr/local/lib library - c

I am building a Swift command-line application with references to a third party library (netcdf) in /usr/local/lib. I have a bridging header in the project and when making the appropriate calls, there are no errors. So I'm fairly confident that the #include is being found in the bridging file.
In Build Settings, I have added /usr/local/lib to Library Search Paths and -lnetcdf to Other Linker Flags.
However I am seeing a link failure. Specifically I am seeing an undefined symbols message. Looking at the ld command shown when I click on the error, I can see that -L/usr/local/lib is there. However the -lnetcdf is not.
What else do I have to do to get the -l into the link command?

After three hours of trying to resolve this, I eventually thought 'stuff it' and spent about 15 mins writing a Makefile.
CLIBS=-lnetcdf
SWFILES=main.swift NCUtil.swift
SWIMPORT=-import-objc-header ../GSIP-Bridging-Header.h
SWIFTLIB=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx
SLIBS=-lSystem -lobjc
GSIP: main.o NCUtil.o
ld $^ -arch x86_64 -L $(SWIFTLIB) $(SLIBS) $(CLIBS) -rpath $(SWIFTLIB) -macosx_version_min 10.10 -no_objc_category_merging -o $#
%.o: %.swift
swiftc -c $(SWFILES) -target x86_64-apple-darwin14.5.0 -I /usr/local/include -I /usr/include $(SWIMPORT) -module-name=GSIP
.PHONY: clean
clean:
rm -f *.o GSIP

There is in fact another solution. Using the Finder menu to Go -> Go to Folder, go to the directory where the dylib is located. Then from Finder, drop and drag the dylib into your project. Probably a wise idea to use a reference rather than make a copy of the file.
This resolved all my link errors!

Related

Install third-party C library on Mac OS X

I'd like to install a third-party C library (http://cgm.cs.mcgill.ca/~avis/C/lrs.html) on a Mac OS X. However, the binaries won't seem to install on a Mac OS X (10.9.5). The library is intended for Unix/Linux platforms.
Here are a couple example of errors I get when trying to install the make file. First, here's the error when running make all out of the box (for some reason, running make all64 does nothing):
ld: library not found for -lgmp
I installed the GMP library (https://gmplib.org/) via MacPorts in /opt/local. However, the library does not appear to be found:
cc 2nash-GMP.o -L. -llrsgmp -L/opt/local/include -lgmp -o 2nash
ld: library not found for -lgmp
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [2nash] Error 1
rm 2nash-GMP.o
How can I get around all this and install on a Mac?
I'll mention that I intend to call a function from this C library many, many times within functions from some (Matlab) code I've written. I'd prefer any potential solution to allow for this.
Update #1:
I've since done the following:
In the makefile, changed LIBDIR from /usr/lib to /opt/local/lib
In the makefile, changed INCLUDEDIR from /usr/include to /opt/local/include
Copied gmp.h file from /opt/local/include to /usr/include
In the makefile, changed RANLIB ?= /bin/true to RANLIB ?= /usr/bin/true
Now, when I run make all, I get the following message:
make: Nothing to be done for `all'.
What other steps should be taken?
I think you would, instead, want something like:
cc 2nash-GMP.o -L. -llrsgmp -I/opt/local/include -L/opt/local/lib -lgmp -o 2nash
The -I option specifies a path to headers to include. The -L option specifies a path to library files to include.
Change the variable LIBDIR in the makefile to the location where the libraries are installed, e.g.:
LIBDIR = /opt/local/lib

C Shared Library : No Such File or Directory Upon Execution

first off, this is a programming assignment so you are aware.
Anyhow, what I am trying to do is include a shared library I wrote (a linked list from a previous project) in with my own shell I am writing. The issue I incur is that when I compile using my Makfile, the compile is successful. Then when I try to run my executable (let's say it's called prog), I get the following:
[terminal]# ./prog
./prog: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory
The following is my file structure for reference:
include
|_
common.h
List.h
Node.h
lib
|_
libmylib.a
libmylib.so
libsrc
|_
Makefile // This makefile builds the library correctly and puts it in lib via 'make install'
List.c
List.h
Node.c
Node.h
common.h
Makefile
prog.c
Here is my main Makefile
CC=gcc
CFLAGS=-g -Wall -Llib
LIBS=-lreadline -lncurses -lmylib
PROGS=library prog
all: $(PROGS)
library:
cd libsrc; make install
prog: prog.o
$(CC) $(CFLAGS) -o $# $< $(LIBS)
clean:
cd libsrc; make installclean
/bin/rm -f *.o $(PROGS) a.out core *.log
Any help or advice is appreciated, thanks!
The runtime dynamic linker does not know where to find your shared library.
Two options:
Set the LD_LIBRARY_PATH environment variable to include the absolute path to your lib directory:
LD_LIBRARY_PATH=/path/to/lib
export LD_LIBRARY_PATH
Hard-code the absolute path to your lib directory in the executable image by passing -R/path/to/lib to the linker (e.g. in your makefile, CFLAGS=... -Llib -R/path/to/lib.
The first option is flexible, in the sense that the shared library can be installed anywhere and even moved to another location, and the executable won't break as long as the environment variable is updated accordingly. But it does require the user (or system administrator) must set up the environment correctly.
The second option does not allow the shared library to be moved from its predefined installation directory, but removes the dependencies on a correctly setup environment.
Note that you won't need to do either if you install your shared library in a standard system-specific location (e.g. /usr/lib or /usr/lib64 on Unix/Linux) as the runtime linker will search such locations automatically.

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

OpenWrt SDK custom package 'make' fails because of missing libpthread.so.0

So I wrote a program to run on a Tp-link device running OpenWrt Attitude Adjustment 12.09.
I wrote the makefiles successfully in the /OpenWrt-SDK../package/myprogram/src/Makefile and it all ran smoothly when I did a 'make'.
Now I added threads in my program so I configured the Makefile like this:
# build myprogram executable when user executes "make"
LDFLAGS=-pthread
myprogram: myprogram.o
$(CC) $(LDFLAGS) myprogram.o -o myprogram
myprogram.o: myprogram.c
$(CC) $(CFLAGS) -c myprogram.c
# remove object files and executable when user executes "make clean"
clean:
rm *.o myprogram
and when I 'make' inside the package/myprogram/src folder it compiles successfully and runs just fine on my PC.
Now when I go to the root OpenWrt-SDK directory to 'make' I get a missing dependencies error:
Package myprogram is missing dependencies for the following libraries:
libpthread.so.0
So what do I need to do to include these dependencies?
I went to my OpenWrt-SDK root and tried:
./scripts/feeds search libpthread
And I got this result:
./scripts/feeds search libpthread
Search results in feed 'trunk':
libpthread POSIX thread library
Should I install that or is that not it? I do not know if I am doing something else wrong.
I will appreciate any help! Thanks.
Under package definition add
DEPENDS:=+libpthread

gcc /usr/bin/ld: error: cannot find -lncurses

I am running Ubuntu 12.04 and I'm currently working on a project involving C, OpenGL, a teapot and input methods.
The problem started when I decided to have arrow keys as input. I checked to see the key codes for arrow keys but all of the arrows return 0. I looked up how to get this to work and I found conio.h. Unfortunately, it is an old DOS header that is not available for Linux. Then I found a substitute called ncurses.
After installing the necessary libraries, by following the build instructions closely, I #included curses.h in my main.c source. When I first tried to compile using gcc, I got the following errors:
main.o:main.c:function _Key: error: undefined reference to 'stdscr'
main.o:main.c:function _Key: error: undefined reference to 'wgetch'
main.o:main.c:function _Key: error: undefined reference to 'stdscr'
main.o:main.c:function _Key: error: undefined reference to 'wgetch'
I found a fix by adding -lncurses to the makefile like so:
SOURCES=main.c
main: main.o
gcc -lm -lGL -lGLU -lglut -lncurses main.o -o main
main.o: main.c
gcc -lm -lGL -lGLU -lglut -c main.c
But I was greeted by another error:
/usr/bin/ld: error: cannot find -lncurses
As well as the previous errors.
I have spent the last 2 days searching both the Ubuntu forums and StackOverFlow. Any help would be appreciated.
P.S. I don't know if this is important but when I try to run /usr/bin/ld I get this error:
ld: fatal error: no input files
For anyone with the same problem I had: I was missing the 32 bit libraries; I was compiling 32 bit on a 64 bit server which was missing the lib32ncurses5-dev package.
On Ubuntu I simply ran:
sudo apt-get install lib32ncurses5-dev
First off, you should put the libraries after the object file when linking. And not have them at all in the compilation of of the source file.
After that, if ncurses is not installed in a standard search folder you need to point out to the linker where it is, this is done with the -L command line option:
gcc main.o -o main -L/location/of/ncurses -lm -lGL -lGLU -lglut -lncurses
Try installing the ncurses-static package too, if you have only the ncurses-devel package installed in your Ubuntu OS.
If that solves your problem, plus if you add #Joachim's compiling instructions, you are off to a great start.
gcc main.o -o main -L/location/of/ncurses -lm -lGL -lGLU -lglut -lncurses
The linker can't find your shared library in it's search path. If you add the directory where your shared lib is to the LD_LIBRARY_PATH environment variable the linker should find it and be able to link against it. In that case you could omit the -L option to gcc:
gcc main.o -o main -lm -lGL -lGLU -lglut -lncurses
And it should compile fine.
EDIT:
Good to know that apt-get install libncurses5-dev fixes your problem.
FYI.
The LD_LIBRARY_PATH environment variable contains a colon separated list of paths that the linker uses to resolve library dependencies at run time. These paths will be given priority over the standard library paths /lib and /usr/lib. The standard paths will still be searched, but only after the list of paths in LD_LIBRARY_PATH has been exhausted.
The best way to use LD_LIBRARY_PATH is to set it on the command line or script immediately before executing the program. This way you can keep the new LD_LIBRARY_PATH isolated from the rest of your system i.e. local to the current running running instance of shell.
$ export LD_LIBRARY_PATH="/path/to/libncurses/library/directory/:$LD_LIBRARY_PATH"
$ gcc main.o -o main -lm -lGL -lGLU -lglut -lncurses

Resources