link static library with headers with Green Hills compiler - c

I have a static library .a with several header files provided. I want to link it with .o files into binary using Green hills compiler.
The error I get is:
[elxr] (error #412) unresolved symbols.
I am trying to specify path to header files providing -I filepath to linker.
However, this does not seem to work.
Updated with code.
# Recipe for linking
__GHSRH850_ERRALL += $(__GHSRH850_TARGETERR)
GHSRH850_LIB = SRC\MCU\DROME\RGL\libd1mx_rh850_ghs.a
$(GHSRH850_TARGETEMU): $(__GHSRH850_OBJS) $(GHSRH850_LSCRIPT) $(GHSRH850_LIB) \
$(CORE_MAKPREREQS) | __GHSRH850_DIRS
$(call CORE_REPORTFILE,Linking,$(#F))
$(eval __GHSRH850_ERRDONE += $(__GHSRH850_TARGETERR))
$(GHSRH850_LD) \
$(GHSRH850_LSCRIPT) \
-o $# \
$(GHSRH850_LIB) \
$(__GHSRH850_OBJS) \
$(GHSRH850_LFLAGS) \
> $(__GHSRH850_TARGETERR)
The make file is quite huge, so I cannot put all of it here. Basically library is added with:
GHSRH850_LIB = file\path\to\libname.a
In flags added filepath to headers with:
GHSRH850_LFLAGS += -I file\path\to\headers
Other descriptions are:
GHSRH850_LFLAGS - Linker flags
GHSRH850_LSCRIPT - Linker script file
__GHSRH850_OBJS - Object files list
Compiler that is used ccrh850.exe.
Error code:
[elxr] (error #412) unresolved symbols: 35
_R_UTIL_DHD_Init from drglgmm_dhd.o
_R_UTIL_DHD_Config from drglgmm_dhd.o
_R_DEV_SQRTF from libd1mx_rh850_ghs.a(r_drw2d_main.o)
_R_VDCE_Sys_HsyncActLevelSet from libd1mx_rh850_ghs.a(r_vdce_api.o)

Thanks all for quick answer. The problem was solved.
Basically errors appeared due to other source files were not compiling, because of missing headers and compiler did not throw any notification about that. Thus, when all object files compiled errors have gone. The correct way to add library is either to add path as I did or use -lname as mentioned by Ian Abbot.

Related

Static library not linking when using -l and -L flags?

So, I have a static library called libtree-sitter.a that I'm trying to use. Here is the compilation command from the documentation:
clang \
-I tree-sitter/lib/include \
test-json-parser.c \
tree-sitter-json/src/parser.c \
tree-sitter/libtree-sitter.a \
-o test-json-parser
The above command successfully compiles and the executable works correctly. I tried changing the loading of the static library into flags so I could make my build system more generic. My changes are below:
clang \
-I tree-sitter/lib/include \
test-json-parser.c \
tree-sitter-json/src/parser.c \
-o test-json-parser \
-Ltree-sitter -ltree-sitter
This compiles, but running the executable gives this error:
dyld: Library not loaded: /usr/local/lib/libtree-sitter.0.dylib
Referenced from: /Users/jason/Downloads/tree sitter test/test-json-parser
Reason: image not found
Can someone please explain the difference between those two examples? From my understanding of -l and -L, it should still find the library in the same place. What is an equivalent combination of flags so I can make loading libraries more generic and easily integrable with Makefile templates (I am using this one)? Thanks for reading.
Your error message says:
dyld: Library not loaded: /usr/local/lib/libtree-sitter.0.dylib
Referenced from: /Users/jason/Downloads/tree sitter test/test-json-parser
Reason: image not found
This gives you several hints about what is happening: It says that it doesn't find libtree-sitter.0.dylib in directory /usr/local/lib which indicates that you have not specified a -L option to search in the subdirectory you say.
First of all, I recommend you to execute clang with option -v to show what command line is it using to call the linker. This will probably don't show the -L option you specified and it's argument.
My guess is that you are using that command line in some script that is deleting some of the \ chars (or you have a space after the \, and you are getting a new line cutting your command line before the linker options. Check this.
The linker you are using will check all directories specified in -L options before any of the system directories, for a file called libyourLibraryName.number.dylib, if it doesn't find, will try libyourLibraryName.a, and then it will try the next directory in the list. If you call the compiler with the -v option you will get the set of options it is using to call the linker. Please, it would be nice if you include that in your question.

Dovecot plugin deleted_to_trash misses lib.h, make fails

I'm trying to install the Dovecot plugin deleted_to_trash. However, I need to update the configuration file, according to the readme, but I don't know what to fill in for DOVECOT_INC_PATH.
The directory that the author put, /usr/include/dovecot, doesn't exist.
If I try to make without changing anything, I get:
me#cs:/my-path/dtt# make
cc \
-fPIC -shared -Wall \
-I/usr/include/dovecot \
-I/usr/include/dovecot/src \
-I/usr/include/dovecot/src/lib \
-I/usr/include/dovecot/src/lib-storage \
-I/usr/include/dovecot/src/lib-mail \
-I/usr/include/dovecot/src/lib-imap \
-I/usr/include/dovecot/src/lib-index \
-DHAVE_CONFIG_H \
src/deleted-to-trash-plugin.c -o lib_deleted_to_trash_plugin.so
In file included from src/deleted-to-trash-plugin.c:4:0:
src/deleted-to-trash-plugin.h:4:17: fatal error: lib.h: No such file or directory
compilation terminated.
make: *** [lib_deleted_to_trash_plugin.so] Error 1
I tried to find the missing lib.h, but nothing useful:
me#cs:/my-path/dtt# find / -name "lib.h"
/usr/src/linux-headers-3.8.0-19-generic/include/config/rtc/lib.h
/usr/src/linux-headers-3.8.0-19-generic/include/config/iio/adis/lib.h
/usr/src/linux-headers-3.8.0-19-generic/include/config/snd/opl3/lib.h
/usr/src/linux-headers-3.8.0-19-generic/include/config/snd/firewire/lib.h
/usr/src/linux-headers-3.8.0-19-generic/include/config/snd/oxygen/lib.h
/usr/src/linux-headers-3.8.0-19-generic/include/config/snd/vx/lib.h
/usr/src/linux-headers-3.8.0-19-generic/include/config/ceph/lib.h
/usr/src/linux-headers-3.8.0-19-generic/include/config/x86/speedstep/lib.h
/usr/src/linux-headers-3.8.0-19-generic/include/config/rt2800/lib.h
/usr/src/linux-headers-3.8.0-19-generic/include/config/rt2x00/lib.h
/usr/src/linux-headers-3.8.0-35-generic/include/config/rtc/lib.h
/usr/src/linux-headers-3.8.0-35-generic/include/config/iio/adis/lib.h
/usr/src/linux-headers-3.8.0-35-generic/include/config/snd/opl3/lib.h
/usr/src/linux-headers-3.8.0-35-generic/include/config/snd/firewire/lib.h
/usr/src/linux-headers-3.8.0-35-generic/include/config/snd/oxygen/lib.h
/usr/src/linux-headers-3.8.0-35-generic/include/config/snd/vx/lib.h
/usr/src/linux-headers-3.8.0-35-generic/include/config/ceph/lib.h
/usr/src/linux-headers-3.8.0-35-generic/include/config/x86/speedstep/lib.h
/usr/src/linux-headers-3.8.0-35-generic/include/config/rt2800/lib.h
/usr/src/linux-headers-3.8.0-35-generic/include/config/rt2x00/lib.h
How can I find out the value I need for DOVECOT_INC_PATH?
I think you want to compile dovecot from source.
And I can find lib.h in dovecot-2.2.13.tar.gz from below url.
http://www.dovecot.org/releases/2.2/dovecot-2.2.13.tar.gz
If you installed dovecot as package, how about to install more dovecot related packages as like dovecot-dev or dovecot-source? I think you can find it.
If you can't resolve the problem, please copy lib.h file from sources tarball file to /usr/include/dovecot/src/lib.

unresolved external symbol on user code

There are plenty of questions about this link error, but most of it about undefined methods or missing lib files.
I'm trying to compile nginx with my custom module on Windows. I used MSYS with nlink, I set up all environment etc, so nginx without my module compiles and run ok. For some reason I used xxHash algorithm, and I wanted to compile it from source just-in-time, when my module compiles. So I put xxHash folder with its source in subfolder of solution and put #include "xxhash/xxhash.h". It works well when I build standalone test app from VS 2013. However when I do so from nmake, I get linker error
ngx_http_imagick_module.obj : error LNK2019: unresolved external
symbol _XXH32 referenced in function _RunJob ngx_modules.obj : error
LNK2001: unresolved external symbol _ngx_http_imagick_module
objs/nginx.exe : fatal error LNK1120: 2 unresolved externals
My questions:
Why method XXH32 called external at all if it built from source and not statically linked?
Isn't #include directive put physical text from file in place where directive was placed? If so, how it can be that linker searches this symbol somewhere? If not so, shouldn't compiler create something like xxhash.obj? Because I don't see anything similar in compiler log, but I see cl -c -O2 -W4 -nologo -MT -Zi -DFD_SETSIZE=1024 -I "C:/msys/1.0/home/tommi/imagick" -I src/core -I src/event -I src/event/modules -I src/os/win32 -I objs/lib/pcre -I objs/lib/zlib -I objs -I src/http -I src/http/modules -I src/mail -Foobjs/addon/ngx_http_imagick_module/ngx_http_imagick_module.obj ../ngx_http_imagick_module/ngx_http_imagick_module.c?
Should I compile xxHash separately to static lib in order to get this work? It's not a big deal, but I prefer to investigate this issue in order to not face it again later.
Not sure if this relevant, but xxhash has this preprocessor directive in its header:
#if defined (__cplusplus)
extern "C" {
#endif
Can this be reason? If so, how to solve it and why/how VS does this automatically?

Why do I need to include .o files when compiling?

When I compiled my program and ran it, I got a a symbol lookup error. I was doing this:
$ gcc -o parts parts.c -lnettle
$ ./parts
$ ./parts: symbol lookup error: ./parts: undefined symbol: nettle_pbkdf2
My code included these header files:
#include <nettle/pbkdf2.h>
#include <nettle/hmac.h>
#include <pbkdf2-hmac-sha1.c>
I solved my problem by including the object files for the two included header files during gcc compilation.
$ gcc -o parts parts.c hmac.o pbkdf2.o -lnettle
The thing is, I don't understand what is going on and therefore why this works. Why must I include the .o files and not just the header files to avoid symbol lookup or undefined reference errors?
As Tobias mentioned, a header file tells the compiler what is done, the object file tells the compiler how it is done. You can see here what an object file is, but in reality it's just a precompiled version of a source file.
Truly, you were not actually getting compiler errors, but linker errors. It knew how to compile your source file, but it couldn't put everything together until it got the other object files.

Getting undefined references when linking against a static library

I made a static library with GCC. Building of the library was OK.
When I use it the linker throws undefined reference errors on some functions. But nm says the functions are defined and exported in the static library (marked with T). I know about the linking order that I need to put the libraries after that module that needs them so this can not be a problem.
The static library was built from 3 C files. A.c B.c and D.c The D module depend on A and B (includes their headers).
No problem when I use functions from A and B but when I try to use any function from D I get undefined reference errors on them.
If I move these functions in A or B it works. But not if they are in the D module.
I'm completely run out of ideas what's going on or what is I'm overlooked.
I'm using Code::Blocks and working with plain C files.
An old trick that many times works: List each static library twice in the linking phase.
i.e., in your makefile (or whatever you're using), put:
gcc -o <outfile> <liba> <libb> <libc> <liba> <libb> <libc>
Anyway, I hope you get the idea.
I found out that I added A .cpp file to my project and I just renamed it to .c. I chose C language instead of C++ when I created the project. I did't think this could cause problems
I thought the file extension decides when the IDE chooses between gcc and g++. But not. In Code::Blocks if you add a file with a .cpp extension it will use g++. If you add a file with a .c extension it will use gcc. But if you rename the file it will use the same compiler. You have to change it explicitly in the project options.
That D module was built using g++ instead of gcc.
I realized this when I set the IDE to show me the entire command line when building not just "Compiling foo.c".
In the master make file I wrote to simplify my application/library builds, the solution I used was to run the link step twice. Using the -u linker option to specify undefined symbols on the second link.
In my make file I have a target like this:
undefined.txt:
#$(generate-undefined-syms)
which calls this macro... the first attempt at linking...
define generate-undefined-syms
$(PRINTF) "$(this_makefile): Generating undefined symbols ... \n"
$(CC) -o rubbish $(LDFLAGS) $(objects) $(LDLIBS) 2>&1 | $(GREP) 'undefined reference' > tmp.txt; \
$(SED) 's/^.*`/-Wl,-u/g' < tmp.txt > undefined.txt; \
rm -f tmp.txt rubbish
endef
As my sed/regexp skills aren't good (and I wrote this stuff in a rush) I end up with undefined.txt containing:
-uSomeSym'
-uSomeOtherSym'
i.e. with a trailing '
I then use this make syntax to strip the 's, and remove duplicates
undefined_references = $(filter-out follow, $(sort $(subst ',,$(shell cat undefined.txt))))
The 'follow' filter is because if an undefined symbol is referenced many times, a message "more references to XXX follow" appears in the output, which leads to a spurious 'follow' in the undefined.txt file e.g.
-Wl, uXXXX' follow
Finally I link the second time (note the dependency on undefined.txt)
$(application): $(library_dependencies) $(objects) undefined.txt
$(CC) -o $# $(LDFLAGS) $(undefined_references) $(objects) $(LDLIBS)
I'd totally recommed the following book by the way, as I was able to write from scratch a simple build system in a couple of days.
Managing Projects with GNU Make, Third Edition
By: Robert Mecklenburg
Perhaps you should use ranlib or the approriate ar option to provide an index to your .a file.

Resources