Error including shared library - linker

I am new to g++ and Makefile. I am trying to link this BeBOP SMC library, which is in my lib directory. Under the lib directory are bebop_util and sparse_matrix_converter, both of which have already been built without errors. I see libbebop_util.a, libbebop_util.so under bebop_util and libsparse_matrix_converter.a, libsparse_matrix_converter.so under sparse_matrix_converter. Below is the source:
Makefile
CC=g++
CFLAGS=-c
# CFLAGS=-c -Wall
INCLUDE_DIRS=-Ilib/bebop_util/include -Ilib/sparse_matrix_converter/include
LIB_DIRS=-Llib/bebop_util -Llib/sparse_matrix_converter
LIBS=-lbebop_util -lsparse_matrix_converter
test.out: test.o
$(CC) -o test.out $(LIB_DIRS) $(LIBS) test.o
test.o: test.cpp
$(CC) $(CFLAGS) $(INCLUDE_DIRS) test.cpp
clean:
rm -f test.o test.out
test.cpp
extern "C" {
#include <bebop/smc/sparse_matrix.h>
#include <bebop/smc/sparse_matrix_ops.h>
}
int main(int argc, const char* argv[])
{
struct sparse_matrix_t* A = load_sparse_matrix (MATRIX_MARKET, "sample_i
nput");
destroy_sparse_matrix(A);
return 0;
}
As a safeguard, I also have the LD_LIBRARY_PATH set:
login4% setenv | grep LD_LIBRARY_PATH
LD_LIBRARY_PATH=/share/apps/teragrid/globus-4.0.8-r1/myproxy-3.4/lib:/share/apps/teragrid/globus-4.0.8-r1/lib:/share/apps/teragrid/srb-client-3.4.1-r1/lib:/opt/apps/pgi7_2/mvapich/1.0.1/lib:/opt/apps/pgi7_2/mvapich/1.0.1/lib/shared:/opt/apps/pgi/7.2-5/linux86-64/7.2-5/libso:/opt/gsi-openssh-4.3/lib:/opt/apps/binutils-amd/070220/lib64:/share/home/01355/tomwang/cs380p_assn3/lib:/share/home/01355/tomwang/cs380p_assn3/lib/bebob_util:/share/home/01355/tomwang/cs380p_assn3/lib/sparse_matrix_converter
Output
login3% make
g++ -c -Ilib/bebop_util/include -Ilib/sparse_matrix_converter/include test.cpp
g++ -o test.out -Llib/bebop_util -Llib/sparse_matrix_converter -lbebop_util -lsparse_matrix_converter test.o
login3% ./test.out
./test.out: error while loading shared libraries: libbebop_util.so: cannot open shared object file: No such file or directory
Please suggest what may be wrong or additional info for me to provide. Thanks.
Tom

Are you sure the directory that libbebop_util.so is in is mentioned in your LD_LIBRARY_PATH? Based on your build line, the following should work:
env LD_LIBRARY_PATH=./lib:${LD_LIBRARY_PATH} ./test_out

It looks like you're not having problems with linking. Instead, the problem is that your built executable has a reference to libbebop_util.so that is invalid.
Try running ldd test.out to see where it's looking for the shared libraries.

Related

Where to change LD_LIBRARY_PATH

I want to compile these files into executable.
//main.c
#include <stdio.h>
#include <mylib.h>
int main(void){
call_hello_world();
return 0;
}
//mylib.h
void call_hello_world(void);
//mylib.c
#include <mylib.h>
#include <stdio.h>
void call_hello_world( void ) {
printf( ”Hello world!” );
}
I tried
gcc -c -I. -fPIC -o mylib.o mylib.c
gcc -shared -o libmylib.so mylib.o
gcc -c -o main.o main.c
gcc -o hello main.o -L. -lmylib
but at the third step, I got stucked because it couldn't find my 'mylib.h'. My professor said I needed to change 'LD_LIBRARY_PATH' so I tried to add this export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/dev/shm my .zshrc but it still didn't work for me. Any suggestions what I should do?
There are several issues with your approach.
First, there is a difference between including a header file like this #include <mylib.h> and including it like that #include "mylib.h".
The first option is usually used to include standard library header files, that should be located in the standard set of directories according to the FHS on Linux.
The latter is the option you might want to use as it is usually used to include user-defined headers and tells the preprocessor to search in the directory of the file containing the directive. (See #quest49 answer's https://stackoverflow.com/a/21594/3852949)
The LD_LIBRARY_PATH environment variable is used to indicate where libraries should be searched for first before looking into the standard set of directories.
So what you would want to do to make your main.c file compile, and after changing #include <mylib.h> directive to #include "mylib.h", is to either :
Add the include file into the directory where your main.c file is located
Indicate where the include file path is with -I option to gcc
These are the commands needed :
gcc -c -I. -fPIC -o mylib.o mylib.c
gcc -shared -o libmylib.so mylib.o
gcc -c -I. -o main.o main.c
gcc -o hello main.o libmylib.so
Then in your shell:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/full/path/of/directory/containing/libmylib-so

"curses.h: No such file or directory" even after installing into Cygwin

I'm working on a C clone of the 2048 game, using curses.h for the UI. When trying to compile it with Cygwin using the make commanad, I get following message:
PS D:\C\ps3> make all
gcc -std=c11 -Wall -Werror -g -c main.c -lm -lcurses -o main.o
main.c:4:20: fatal error: curses.h: No such file or directory
#include <curses.h>
^
compilation terminated.
make: *** [Makefile:13: main.o] Error 1
So I ran the setup again, looking for any package that has "curses" in it's name and installed it, added my /bin folder to the PATH variable but it didn't help.
I'm working on a 64-bit Win10 and trying to compile the program with Cygwin's terminal, using a Makefile. file. I've tried reinstalling the packages with curses in their name multiple times with no help.
Part of my Makefile:
CC=gcc
CFLAGS=-std=c11 -Wall -Werror -g
LDLIBS=-lm -lcurses
OUTPUT=game
# targets
all: $(OUTPUT)
$(OUTPUT): k.o hof.o main.o
$(CC) $(CFLAGS) k.o hof.o main.o $(LDLIBS) -o $(OUTPUT)
main.o: main.c
$(CC) $(CFLAGS) -c main.c $(LDLIBS) -o main.o
The line in main.c the error is pointing to:
#include "hof.h"
#include "k.h"
#include "ui.h"
#include <curses.h>
The header file would be in libncurses-devel (perhaps overlooked). Here's a screenshot showing the "curses" packages which I have in my local repository:

Linking static library with -l flag

How can I have my makefile compile with the -l flag?
I have a makefile that looks like
myLibrary:
gcc -c myLibrary.c -o myLibrary.o
ar cr libmyLibrary.a myLibrary.o
and then I compile my main program with
main:
gcc -g -c -o main.o main.c
gcc main.o -o main libmyLibrary.a
The above makefile works, but if I want to replace
libmyLibrary.a
with -lmyLibrary I get an error. Shouldn't both be working the same?
Here is a rudimentary, unrealistic makefile that will make the static library libmyLibary
before it makes the program main, which it will link with the static library
using the -L (library search-path) and -l (library) options.
Makefile
.PHONY: all clean
all: libmyLibrary.a main
main: main.o | libmyLibrary.a
$(CC) -o main main.o -L. -lmyLibrary
libmyLibrary.a: myLibrary.o
$(AR) rcs libmyLibrary.a myLibrary.o
clean:
rm -f *.o libmyLibrary.a main
which runs like:
$ make
cc -c -o myLibrary.o myLibrary.c
ar rcs libmyLibrary.a myLibrary.o
cc -c -o main.o main.c
cc -o main main.o -L. -lmyLibrary
As I think you know, it's unrealistic to make both a library and a program
that links with it in the same makefile, since the point of a library is
that you don't need to keep remaking it to link it with many programs. You'd really have
a makefile for libmyLibrary.a and other makefiles for programs that
use it.
This is how the gcc linkage options -L and -l work:
-L/path/to/search
tells the linker to look for any libraries that you specify with the -l option in /path/to/search,
before it looks for them in its default search directories. The current directory, .,
isn't one of the linker's default search directories. So if you want it to
find a library specified with the -l option in the current directory, then you need to
specify -L.
-lfoo
tells the linker to search for either a dynamic library, libfoo.so, or a static
library, libfoo.a, first in your -L directories, if any, in the order you've
specified them, and then in its default search directories. It stops searching
as soon as if finds either libfoo.so or libfoo.a in one of the search directories.
If it finds both of them in the same directory, then by default it will link libfoo.so with
your program and not link libfoo.a.
To link purely statically library, use -static, Like
gcc -static main.c libmyLibrary.a
And run executable file ./a.out GCC Linux.

makefile (link 2 source files non is main)

I have a project that contains 4 source files :
RTP.c, RTCP.c RTSP.c main.c
and 3 header files :
RTP.h RTCP.h RTSP.h
I have to include all the header files in the main and the RTCP.h in the RTP.c after I included the header files in the source files I linked them in a make file please help me understand the problem.
the RTP.c
#include "RTP.h"
#include "RTCP.h"
the RTCP.c
#include "RTCP.h"
The RTSP.c
#include "RTSP.h"
The main.c
#include "RTP.h"
#include "RTSP.h"
The make file:
OBJS = main.o RTPfunctions.o RTCPfunctions.o RTSPfunctions.o
CC = gcc
CCFLAGS = -g
Client : $(OBJS)
$(CC) $(OBJS) -o -pthread client
RTCPfunctions.o : RTCPfunctions.c RTCPfunctions.h
$(CC) -c -g -pthread RTCPfunctions.c
RTSPfunctions.o : RTSPfunctions.c RTSPfunctions.h
$(CC) -c -g -pthread RTSPfunctions.c
RTPfunctions.o : RTPfunctions.c RTPfunctions.h RTCPfunctions.h
$(CC) -c -g -o -pthread RTPfunctions.c RTCPfunctions.o
main.o : main.c RTPfunctions.h RTSPfunctions.h
$(CC) -c -g -o -pthread main.c RTPfunctions.o RTSPfunctions.o
clean:
\rm *.o *~ client
Your question is not very verbose, however, from a quick glance at your makefile, we can say, as per the online gcc manual,
-o file
Place output in file file. This applies to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code.
Basically, this says, the immidiate next argument to -o should be the output file name.
Also, to follow the order of linking, the pthread library should be placed at the end, like
$(CC) $(OBJS) -o client -pthread

How to create a Makefile for a program which takes in command line argument

I need to create a Makefile for a program which takes in a file as input via command line.
Here is what I mean:
A program has function main which looks like this:
int main(long argc, char **argv) //'argument command' and 'argument vector'respectively
{
some code;
}
You compile this C language source code file
gcc main.c function1.c function2.c -o execute
Which creates an executable program called 'execute'. Then you pass in an argument into this program:
./execute filename
The makefile I've created has the contents:
all: xsd
xsd: main.o function1.o function2.o
gcc -o xsd main. function1.o function2.o
main.o: main.c
gcc -c -o main.o main.c
function1.o: function1.c
gcc -c -o function1.c
function2.o: function2.c
gcc -c -o function2.c
clean:
rm -rf *o xsd
So how do I create a proper makefile which accomodates for the input file passed in via the command line? Perhaps something like this:
./{argv}
Anybody know how to do this?
just fix the type-o, and make all depend on xsd rather than prog...
all: xsd
xsd: main.o function1.o function2.o
gcc -o xsd main.o function1.o function2.o
main.o: main.c
gcc -c -o main.o main.c
function1.o: function1.c
gcc -c -o function1.c
function2.o: function2.c
gcc -c -o function2.c
clean:
rm -rf *o xsd
The make file doesn't run the program, it only compiles it, so it doesn't have to pass any parameters to it either.

Resources