I want to use the ta_lib functions in my C code and am trying to import the ta_lib functions. The header file gets imported correctly but i cannot get the linker to find the actual library.
I want to do the compiling process with MAKE and gcc.
Firstly I import the header
#include <ta-lib/ta_libc.h>
And then when i need to use a function
TA_ADOSC(0, CSV_LENGTH - 1, temp_high, temp_low, temp_close, temp_volume, 3, 10, &beginIdx, &endIdx, tmp_adosc);
The program compiles fine using my makefile
# create CC variable
CC = gcc
# create CFLAGS variable
CFLAGS = -L/usr/local/lib -Wall -g
LDLIBS = -lta_lib -I/usr/local/include -lm
output: main.o
$(CC) $(CFLAGS) -o output main.o
main.o: main.c
$(CC) $(LDLIBS) -c main.c
# target: dependencies
# action
clean:
rm -f \*.o output
Once I try to run make i get the following
gcc -L/usr/local/lib -Wall -g -o output main.o
/usr/bin/ld: main.o: in function `calculate_indicators': main.c:(.text+0x226): undefined reference to `TA_ADOSC'
collect2: error: ld returned 1 exit status
make: \*\*\* \[Makefile:10: output\] Error 1
From my understanding I need to fix the linking to the shared library.
The library is installed:
ldconfig -p | grep libta_lib.so
Returns the following
libta_lib.so.0 (libc6,x86-64) => /usr/local/lib/libta_lib.so.0
libta_lib.so.0 (libc6,x86-64) => /lib/libta_lib.so.0
libta_lib.so (libc6,x86-64) => /usr/local/lib/libta_lib.so
libta_lib.so (libc6,x86-64) => /lib/libta_lib.so
Since i am fairly new to C and using external libraries I can't find what seems to be the problem
You are adding the libraries to the compile line. They need to be added to the link line. And preprocessor options like -I are used by the compiler, and "where to find libraries" options like -L are used by the linker.
Also, libraries always must come at the end of the link line, after all the object files. And, the -L "where to search" option should come before the -l "what library to find" option.
Write your rules like this:
CFLAGS = -I/usr/local/include -Wall -g
LDFLAGS = -L/usr/local/lib
LDLIBS = -lta_lib -lm
output: main.o
$(CC) $(CFLAGS) $(LDFLAGS) -o output main.o $(LDLIBS)
main.o: main.c
$(CC) $(CFLAGS) -c main.c
However, it's better to just let make do the work for you; it knows how to correctly compile things (as long as you set the standard variables). You don't need to include a rule to build main.o at all.
Related
I have just started learning about makefile files. I created a program that consists of two functions and wanted to use a makefile to put it all together. This is my file:
#Makefile
all: main
main: main.o find_root.o
clang -o main main.o find_root.o
main.o: main.c
clang -c -Wall --pedantic -std=c11 main.c -lm
find_root.o: find_root.c
clang -c -Wall --pedantic -std=c11 find_root.c -lm
clean: rm -f main *.o*
However, when I run this, I get an error - "undefined reference to cos". I am using the cosine functions in my program, but I have already linked the library to the compilation of those two files. I thought about adding "-lm" to the first clang option as well. This led to no errors, but it made a warning instead - saying that "-lm linker is unused". What should I change in my file?
The "-lm" is a linker option but you have only included it in your compilation rule (main.o: main.c). You need to include it in your linker rule (main: main.o find_root.o).
As it stand the -lm option is ignored during compilation and missing during linking.
The linker flags aren't used when compiling, but when linking, so the command for the main rule should have -lm, rather than the command for the *.o files.
Better would be just to set the appropriate variables, and let Make use its built-in rules:
#Makefile
LDLIBS += -lm
CFLAGS += -Wall --pedantic -std=c11
C = clang
all: main
main: main.o find_root.o
$(LINK.c) $^ $(LDLIBS) -o $#
clean:
$(RM) main *.o *~
[Files in my directory][1]
Need help compiling in a make file.
So I have this link list assignment i'm doing and the directions were.
stringlist.h is supposed to contain the node and the function prototypes
stringlist.c is supposed to have the functions completed that are defined in stringlist.h. BUT stringlist.c is not supposed to contain main at all. Then, namelist.c is supposed to contain main and just have the I/O and its just supposed to call the command functions that are in stringlist.c.
So to compile this we are supposed to create a make file. Whenever I try to I get an error because main doesn't exit in one of the c files. Throughout the term we compiled code like this "gcc -std=gnu99 -m32 -Wall -g -o file file.c"
But it doesn't work.
How would I create the make file? Been spending hours and can't figure it out.
As stated by Jonathan Leffler, the sample Makefile I provided had a few bad ideas. Here's an improvement:
# compiler:
CC = gcc
# compiler flags:
CFLAGS = -g -Wall
# the build target executable:
TARGET = executable
# object files to build:
OBJ = namelist.o stringlist.o
all: $(TARGET)
$(TARGET): $(OBJ)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJ)
Try this:
OBJ := namelist.c stringlist.c
GCC := gcc -g
CFLAGS := -std=gnu99 -m32 -Wall
compile: $(OBJ)
$(GCC) $(CFLAGS) $(OBJ) -o executable
I am trying to work with id3 tags with C, so I downloaded mplib and installed it.
I am trying to call this function inside mplib.h where __P is a Macro
extern id3_tag_list* mp_get_tag_list_from_file __P((const char* path));
by writing in
example.c:
int main() {
char* pa = "R U MINE";
id3_tag_list* list = mp_get_tag_list_from_file(pa);
id3_tag *newTag = list->tag;
printf("tag %d\n", newTag->version);
return 0;
}
but when I link, I get an error:
example.o: In function `main':
example.c:(.text+0x27): undefined reference to `mp_get_tag_list_from_file'
collect2: error: ld returned 1 exit status
make: *** [example] Error 1
My makefile looks like this
OBJECTS = example.o
target=example
misc=Makefile
cflags=-Wall -g -O0 -Werror -pedantic -std=c99
all: $(target)
$(target) : $(OBJECTS) $(misc)
gcc $(cflags) -o $(target) $(OBJECTS)
clean:
rm -f $(OBJECTS) $(target)
I am having trouble compiling this. I believe the problem is that I am having issues with linking it to the actual mplib.c file where that function is actually defined, but I am not sure how to do it exactly. I got the library from http://mplib.sourceforge.net/ and I installed it by using 'make' and 'make install'. Am I supposed to manually move the mplib.c file somewhere?
If you build mplib 1.0.3, it creates a library libmp.a. Therefore, you need to specify -lmp on the linker command line, and perhaps -L /where/you/installed/it/lib to specify the directory where the library was installed.
The linker command line should probably look like:
LDFLAGS = -L/usr/local/lib
LDLIBS = -lmp
gcc $(cflags) -o $(target) $(OBJECTS) $(LDFLAGS) $(LDLIBS)
Actually, it would be better if it looked like:
$(CC) $(CFLAGS) -o $# $(OBJECTS) $(LDFLAGS) $(LDLIBS)
The upper-case macro CFLAGS is used for flags to the C compiler. $# means 'the name of the current target'. LDFLAGS are flags for the linker, such as where to find libraries, and LDLIBS contains the specification of libraries. An option such as -lmp means 'look for libmp.so or libmp.a in each of the directories on the list of places searched for libraries' (to a sufficiently close approximation). The -L option prefixes the following directory to the list of places searched for libraries.
I'm trying to compile a few .c files that used msgpack-c functions into a shared library. I have the following Makefile:
MSGPACK_CS = msgpack.c
CFLAGS = -std=c99
MSGPACK_OBJECTS = $(subst .c,.o,$(MSGPACK_CS))
MSGPACK_LIBS = msgpack.so
all: $(MSGPACK_OBJECTS) $(MSGPACK_LIBS)
%.o: %.c
$(CC) -c -shared -fPIC $(CFLAGS) $<
$(MSGPACK_LIBS): $(MSGPACK_OBJECTS)
ld -Lmsgpack/.libs -share -o $# $(MSGPACK_OBJECTS) -lmsgpack
I can compile a program that uses msgpack without problem, but this gives me the following error:
msgpack.o: In function `msgpack_pack_int64':
/usr/local/include/msgpack/pack_template.h:373: undefined reference to `__stack_chk_fail_local'
ld: msgpack.so: hidden symbol `__stack_chk_fail_local' isn't defined
ld: final link failed: Bad value
Apparently the linkage process isn't going well, but I don't know what is wrong. What can I do?
Try linking with the gcc driver instead of calling ld directly. ld doesn't know about the gcc support libs that are needed for the C runtime:
gcc -Lmsgpack/.libs -shared -o $# $(MSGPACK_OBJECTS) -lmsgpack
If this still doesnt't work, you might need to add -fno-stack-protector to your CFLAGS to supress runtime stack checking.
I am trying to compile a very simple program using the -m32 flag.
If I try to do this using gcc -m32 it works just fine(I have the needed libs)
Yet, when I add this flag to my flags in a makefile, I get a weird error
This is the makefile that I have
CC=gcc
CFLAGS=-m32 -O1 -W -Wall -pedantic -std=c99
all: main.o
$(CC) -o main main.o
rm main.o
clean:
rm main
The error that I receive is the following
gcc -o main main.o
/usr/bin/ld: i386 architecture of input file `main.o' is incompatible with i386:x86-64 output
collect2: ld returned 1 exit status
make: *** [all] Error 1
Can someone please tell me what does this mean? and how can I fix it?
As for the code, the code does NOTHING except printing 'hello world'
I am using GCC 4.4.3 under Linux 2.6.35 64-bits
Your mistake is that you don't pass -m32 to the linker.
You actually need to change your Makefile to look like this:
CC=gcc
CFLAGS=-m32 -O1 -W -Wall -pedantic -std=c99
LDFLAGS = -m32
all: main.o
$(CC) $(LDFLAGS) -o main main.o
rm main.o
clean:
rm main
An even better approach would be the following Makefile:
CC=gcc
CFLAGS=-m32 -O1 -W -Wall -pedantic -std=c99
LDFLAGS=-m32
.INTERMEDIATE: main.o
all: main
main: main.o
clean:
-rm main
In the later you just say that main depends on main.o and GNU Make will invoke the linker with the LDFLAGS as arguments for you as it invokes the compiler with the CFLAGS as arguments for the main.o
"The targets which .INTERMEDIATE depends on are treated as intermediate files. See section Chains of Implicit Rules. .INTERMEDIATE with no dependencies marks all file targets mentioned in the makefile as intermediate." Special Built-in Target Names
You should inform the linker as well about the architecture being 32-bit. Try adding
LD = $(CC)
LDFLAGS = -m32
to your Makefile and change
$(CC) -o main main.o
to
$(LD) $(LDFLAGS) -o main $^
and it shoud work.
(Why it worked? If you use GCC to compile and link your code in one step, all the relevant flags and options will be passed down not only to the compiler but to the linker as well.)