i'm new on gcc compiler.
My friend wrote this script (graphic filter) for me but i can't use it because i receive some error.
I have 2 directory and a C file:
-dir- include --> basics.h common.h freeimage.h hqx.h imageIO.h pcxIO.h
-dir- lib --> libfreeimage-3.13.1.so libfreeimage.a libfreeimage.so.3 libhqx.a libhqx.so libhqx.so.1 libhqx.so.1.0.0
scaling.c
i try to compile with this command:
gcc scaling.c -I./include -L./lib -lm -lfreeimage -lhqx -lstdc++ -o filter
But i receive this error:
/usr/lib/gcc/i486-slackware-linux/4.2.4/../../../../i486-slackware-linux/bin/ld:./lib/libhqx.so: file format not recognized; treating as linker script
/usr/lib/gcc/i486-slackware-linux/4.2.4/../../../../i486-slackware-linux/bin/ld:./lib/libhqx.so:1: syntax error
collect2: ld returned 1 exit status
Thanks in advance and sorry for my english.
The linker will treat any file that doesn't look like an object file or library as a linker script containing commands to specify how linking should be done. Things like load addresses, section definitions, etc.
Apparently libhqx.so doesn't look like a shared library on you system. I assume it was built on your friend's system?
To get a clue about what the file is, use the file command. You should get something like:
main% file /lib/libc-2.11.2.so
/lib/libc-2.11.2.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
If not, you'll have to build or find a library compatible with your system.
I had a similar problem yesterday, and I think your libhqx.so was a symbolic link to libhqx.so.1.0.0 or to libhqx.so.1 in your friend's machine, and when you copied this files, this link had broken. (at least that was the situation in our system, and the problem solved after we remove the .so file, and create the right symbolic link)
Related
For example, there is three object files a.obj b.obj c.obj just compiled out with cl, and it is desired to combine them into one combined.obj.
A comment of an SO question points out that on *nix it's possible to do this kind of thing with ld. However, cl and link all seems only support .exe, .dll and .lib as output.
The whole procedure of what I want to do with the combined object file as follows:
a.obj b.obj c.obj -> combined.obj
combined.obj d.obj e.obj -> executable.exe
My problem is solved. a.obj b.obj c.obj use some variables and functions yet to be linked, and I thought that .lib can't tolerant missing functions since it is a library, but in fact it is OK. I can just merge them into an .lib file:
lib *.obj /OUT:combined.lib
You can apply the method employed here also to the COFF files created by cl.exe, provided that your build of ld supports the respective input and output formats and those formats lend themselves to the process.
What you can do in such a case is this (and yes $INPUTS means you can give multiple object files as you wanted):
ld --oformat pe-x86-64 -r $INPUTS -o $OUTPUT
The --oformat pe-x86-64 (aka AMD64, x64 on Windows) is necessary whenever the ld has been built with a different default output format.
If that's the case and you didn't give --oformat you will get something like:
ld: relocatable linking with relocations from format pe-x86-64 (input.obj) to format elf64-x86-64 (output.obj) is not supported
However the process doesn't work for all input/output format combinations, as I learned with ld 2.34 on Ubuntu 20.04:
ld: relocatable linking with relocations from format pe-i386 (input.obj) to format pe-i386 (output.obj) is not supported
NB: At this point I had no luck to get this to work with lld-link or ld.lld (both available through modern VS versions), though.
Seems not, but it is convenient to merge them into an .lib:
lib *.obj /OUT:combined.lib
I have a bunch of object files that have been compiled without the -fPIC option. So the calls to the functions do not use #PLT. (source code is C and is compiled with clang).
I want to link these object files into a shared library that I can load at runtime using dlopen. I need to do this because I have to do a lot of setup before the actual .so is loaded.
But every time I try to link with the -shared option, I get the error -
relocation R_X86_64_PC32 against symbol splay_tree_lookup can not be used when making a shared object; recompile with -fPIC
I have no issues recompiling from source. But I don't want to use -fPIC. This is part of a research project where we are working on a custom compiler. PIC wouldn't work for the type of guarantees we are trying to provide in the compiler.
Is there some flag I can use with ld so that it generate load time relocating libraries. In fact I am okay with no relocations. I can provide a base address for the library and dlopen can fail if the virtual address is not available.
The command I am using for compiling my c files are equivalent to -
clang -m64 -c foo.c
and for linking I am using
clang -m64 -shared *.o -o foo.so
I say equivalent because it is a custom compiler (forked off clang) and has some extra steps. But it is equivalent.
It is not possible to dynamically load your existing non PIC objects with the expectation of it working without problems.
If you cannot recompile the original code to create a proper shared library that supports PIC, then I suggest you create a service executable that links to a static library composed of those objects. The service executable can then provide IPC/RPC/REST API/shared memory/whatever to allow your object code to be used by your program.
Then, you can author a shared library which is compiled with PIC that provides wrapper APIs that launches and communicates with the service executable to perform the actual work.
On further thought, this wrapper API library may as well be static. The dynamic aspect of it is performed by launching the service executable.
Recompiling the library's object files with the -fpic -shared options would be the best option, if this is possible!
man ld says:
-i Perform an incremental link (same as option -r).
-r
--relocatable
Generate relocatable output---i.e., generate an output file that can in turn serve as input to ld. This is often called partial linking. As a side effect, in environments that support standard Unix magic numbers, this option also sets the output file’s magic number to "OMAGIC". If this option is not specified, an absolute file is produced. When linking C++ programs, this option will not resolve references to constructors; to do that, use -Ur.
When an input file does not have the same format as the output file, partial linking is only supported if that input file does not contain any relocations. Different output formats can have further restrictions; for example some "a.out"-based formats do not support partial linking with input files in other formats at all.
I believe you can partially link your library object files into a relocatable (PIC) library, then link that library with your source code object file to make a shared library.
ld -r -o libfoo.so *.o
cp libfoo.so /foodir/libfoo.so
cd foodir
clang -m32 -fpic -c foo.c
clang -m32 -fpic -shared *.o -o foo.so
Regarding library base address:
(Again from man ld)
--section-start=sectionname=org
Locate a section in the output file at the absolute address given by org. You may use this option as many times as necessary to locate multiple sections in the command line. org must be a single hexadecimal integer; for compatibility with other linkers, you may omit the leading 0x usually associated with hexadecimal values. Note: there should be no white space between sectionname, the equals sign ("="), and org.
You could perhaps move your library's .text section?
--image-base value
Use value as the base address of your program or dll. This is the lowest memory location that will be used when your program or dll is loaded. To reduce the need to relocate and improve performance of your dlls, each should have a unique base address and not overlap any other dlls. The default is 0x400000 for executables, and 0x10000000 for dlls. [This option is specific to the i386 PE targeted port of the linker]
I'm trying to use pcap functions, but it giving me compiler error:
project.c:(.text+0x140): undefined reference to `pcap_open_offline'
I have installed library and while compiling I give "-lpcap" at the and as it advised in many forums.
What can be wrong, please?
You need to understand what the arguments evoke into the linker.
I am supposing you are using Linux system with gcc, using ld as linker (note that this could change depending on the system and the linker used).
In such case, -Lpath tell the linker where to look for the libraries that you tell it that are needed to be linked with your program to create the final binary. For example -L/usr/lib.
when you type in for example:
# gcc -L/usr/lib -lcap my_program.c -o my_program
You are telling the linker to append /usr/lib to the list of paths to locate libraries, and to link the dynamic library "libcap.so" with your program.
Other modifiers for the path used to locate libraries is LD_LIBRAY_PATH (the name of this environment variable could change from one system to another, review the manual of your linker).
As you are using "-lcap" the error you get look to be related with the fact that no path is found where libcap.so exist. Locate that file into your system and pass the argument
-L/path/to/the/directory/that/contain/libcap.so
By the way, try to run this before any other thing and recompile:
# sudo ldconfig
With gcc in ubuntu I used this command to compile my source code:
gcc 1.c -L. -lagent -lm -lpthread -o 1
but I got this error:
/usr/bin/ld: skipping incompatible ./libagent.so when searching for -lagent
/usr/bin/ld: cannot find -lagent
collect2: ld returned 1 exit status
How can I solve this?
The linker is telling you that the file ./libagent.so exists, but isn't in the appropriate format.
It could be an empty file, or built for 32-bit instead of 64-bit, or it could be a symlink pointing to the wrong version.
Let's look at your command line parameters first.
gcc 1.c -L. -lagent -lm -lpthread -o 1
You call the compiler gcc with the input source code of 1.c and then you specify an additional (link) library path to include the current directory (.) -L.. Then you tell it to link against the agent and pthread libraries, where shared (dynamic) libraries have the default name format of libNAME.so where NAME is replaced with the name. Static libraries have the default file extension .a (from the term archive). Then you specify the output (executable in this case) to be the file 1 (digit one, not the letter 'ell').
/usr/bin/ld: skipping incompatible ./libagent.so when searching for -lagent
This is the linker (ld) telling you that the file ./libagent.so (it found presumably in the current directory) is not a valid shared library format as it was expecting. This could be for a different machine architecture (x86-64, ARMle, PowerPC, MIPS) or a incompatible library format (I don't know if library files, .so, have any COFF or ELF or PE dependencies or not). Or simply otherwise empty or corrupted (e.g. interrupted output due to errors compiling / linking).
So you normally want to not include your current directory in your linker's search path, unless you have the copy of the library that you have not yet installed (typically to /usr/lib/ or /usr/local/lib/), such as you wrote the library and wish to link test programs to it before you install it.
Debian and Unbuntu-oriented part of the answer:
Normally you want to install shared library's runtime component (often named something like libagent) and the associated development files (most often at least a header file and hopefully a manpage) in the format libagent-dev. RPM based Linux systems use libagent-devel style naming conventions (from memory). So sudo aptitude install libagent-dev should do the trick if that is the package's name.
I installed from kubuntu's package management this handy pnglite library. It contains just one header file "pnglite.h" and one object file "pnglite.o". I have found out where those files are, but I don't know how to link them. I'm using netbeans, but don't know how to link them in there. Also I don't understand how to link them at console.
I have a little test program that I would like to test, but I get the error message "undefined reference to function: XXXXXXX". Both netbeans and at console I'm using gcc. That header file is in /usr/include directory, object file is in /usr/lib directory and my test program is under my programming directory at my home directory.
Should I put that header and object into the same directory as where my source is? Or is there a way to link them from their current locations? I know that it should be possible to link them from where they are at the moment and I would like to know and understand how to do that.
Any help will be appreciated :)
You just need to add /usr/lib/pnglite.o to your linking invocation of gcc, plus any shared libraries that pnglite requires (from your comment it appears to require zlib). Eg if your source is in myapp1.c and myapp2.c, then:
gcc -c myapp1.c
gcc -c myapp2.c
gcc -o myapp myapp1.o myapp2.o /usr/lib/pnglite.o -lz