Shared library creation in LINUX throws error - c

I've ten ".o" files in a directory.i want to combine them as a shared lib (.so) file.
For doing so,I am issuing following command
#gcc -shared *.o -o abc.so
but it throws following error message:
No command '-shared' found, did you mean:
Command 'gshared' from package 'gshare' (universe)
-shared: command not found
What could be the possible reason? Anything wrong with the command?
Any help ?

I agree with Chen Levy. It looks like gcc is either a stange version or not what you think it is. When I do:
gcc -shared *.o -o abc.so
I get the desired reponse. Try echo, or even:
which gcc
to try and see what's really going on. PS: I Tested on Ubuntu 10.10

Related

Problem compiling C-Function to Postgres; compiler didn't find postgres.h

I was asked to create a C-Function to integrate with Postgres. The Postgres documentation to this kind of function is available here: Postgres documentation.
The function I am trying to compile is from the manual and it is called add_one, just for test. But I had a problem while compiling it. The command I followed of the documentation was:
cc -fPIC -c foo.c
cc -shared -o foo.so foo.o
And the problem it returned was:
[igoralberte#localhost inside-postgres]$ cc -fPIC -c serializacao.c
serializacao.c:1:10: fatal error: postgres.h: Arquivo ou diretório inexistente
#include "postgres.h"
^~~~~~~~~~~~
compilation terminated.
In English, it means: Non-existent file or directory (postgres.h).
I have tried to copy some files I thought were important to /usr/lib directory. They were on /usr/include/pgsql or on /lib64. Those files were:
libpq.so
libpq.so.5
libpq.so.5.13
libpq (directory)
postgres_ext.h
Some important informations about my system:
I am using CentOS 8
System architecture: x86-64
GCC version: gcc (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1)
Postgres version: 13.3
Thanks in advance!
It is a bold step to write a postgres plugin before you have a solid grasp on linux/unix, shell programming and how to compile c programs.
Typically your c compiler has to be told where to find header files using the -I compiler switch. So if postgres.h is in /path/containing/headerfile, you must add -I/path/containing/headerfile to the compile command:
cc -I/path/containing/headerfile -fPIC -c foo.c
The postgres documentation you linked to tells you to use pg_config --includedir-server to find out where the the header files are stored.
I am not familiar with pg_config, but if it acts like similar tools and
gives the output -I/path/containing/headerfile when calling it with the paramater --includedir-server, then you don't have to hardcode the path in your compile command. But just write:
cc `pg_config --includedir-server` -fPIC -c foo.c
See "Command Substitution" in your favorite shell documentation.
I also recommend learning how to use a build-tool like make. Things are soon going to be tedious if you have to retype compilation and link commands all the time.
Oh, and by the way, you probably want to write #include <postgres.h> and not #include "postgres.h" (Unless you are a postgres contributor and postgres.h is part of your project files)

libtiff build undefined reference to `_imp__TIFFOpen' error

probably this is a trivial newbie question, however, I can't figure out how to solve it.
I'm trying to build a test program using libtiff (test program copied from here). I've downloaded the static library libtiff.lib as well as the required header file tiffio.h. When I compile the main c function with no problem I have a main.o file. When I try to link main.o with libtiff using this command
gcc -g -Wall -o test.exe ./libtiff.lib ./test.o
I have this error:
undefined reference to `_imp__TIFFOpen'
I've looked into the lib file with nm -A libtiff.lib command and I can find this line
libtiff.lib:libtiff3.dll:00000000 I __imp__TIFFOpen
but it has 2 leading underscores instead of 1 as required by the linker. I'm using mingw on Windows 7 and all the required files are in the same directory.
No clue how to link with no errors.
Thanks in advance.
As suggested in the the comments, it was sufficient to invert the order of objects passed as arguments:
gcc -g -Wall -o test.exe ./test.o ./libtiff.lib

libxml for c program in ubuntu

I want to use libxml2 as parser for a c program on a system with ubuntu. I used the following command to install libxml2:
sudo apt-get install -y libxml2-dev
I try to compile the following file: http://xmlsoft.org/examples/reader1.c
My makefile looks like this:
xml_reader: xml_reader.o
gcc -o xml_reader xml_reader.o -lxml2 -lm
xml_reader.c: xml_reader.c
gcc -c xml_reader.c -I/usr/include/libxml2
But sadly I get the following response:
fatal error: libxml/xmlreader.h: No such file or directory
Did I miss something, which I had to do before compiling or am I even using the right -l argument?
The target of your second Makefile rule should be xml_reader.o and not xml_reader.c. Right now make is using a default rule instead which does not make use of -I/usr/include/libxml2 and thus gcc cannot find the required header.

Making a makefile for C program on linux

I have a C programming exercise, which I have written (and runs perfectly) in Visual Studio on Windows. I now have to make sure it runs OK on Linux as well, and need to create a makefile for it (it is part of the assignment). Here is my makefile:
all: genericdfs.a sudSolver
genericdfs.a: genericdfs.c genericdfs.h
gcc -Wvla -c genericdfs.c
ar rs genericdfs.a genericdfs.c
sudSolver.o: sudSolver.c sudTree.h genericdfs.h
gcc -Wvla -c sudSolver.c -lm
sudukutree.o: sudTree.c sudTree.h
gcc -c sudTree.c -lm
sudSolver: sudSolver.o sudTree.o genericdfs.a
gcc -Wvla sudSolver.o sudTree.o -L. -lgenericdfs -o sudukusolver -lm
clean:
rm -f sudSolver.o
rm -f sudTree.o
rm -f genericfs.o
OK so the main C file is sudSolver which has includes for sudTree.h and math.h (hence the -lm)
sudTree.c includes sudTree.h and genericdfs.h as well.
One of the requirements is to create a .a library which should be linked to the main C file at the linkage operation.
We were given next to nothing of an explanation as how to write these makefiles so all I wrote above was according to makefile tutorials I found online.
This makefile however doesn't work, there seems to be a problem with the linkage to the library as this is the error that is being returned:
cannot find cannot find -lgenericdfs
I tried shifting things around but nothing seems to work, another error which appeared when I put -L. genericfs.a in the linkage line:
genericdfs.a: error adding symbols: Archive has no index; run ranlib to add one
Could anyone please explain how I link to the .a library which was created? I suppose its not that complicated but for the life of me I cannot get it to work
Thank you to anyone who helps!
EDIT
I managed to make it work by changing the line
ar rs genericdfs.a genericdfs.c
into
ar rs libgenericdfs.a genericdfs.o
and updating final linkage line to libgenericdfs.a
But now there is a different problem. I included a couple rm -f commands to a clean: tag, but they don't delete the files written there when i run "make" from the terminal.
If I run "make clean" then everything gets removed. Do I need to add "clean" to the "all" tag at the top? I read that you should not do that
gcc is passed libraries by using
gcc -Lfull/path/to/library
Or if the library name starts with 'lib' and is on a library search path then you can use -l with lib and .a removed. For example with library called libtest.a .
gcc -ltest
There are a couple of special cases for well used libraries like maths -lm and zlib I think.

gcc is working, but not yielding executable

My C compiler was working a second ago and making executables, but I started working on a new .c file and suddenly it won't work anymore. I haven't changed anything and I'm still using the same commands, Gitbash version, etc. The compiler is still able to catch errors, so gcc works, but after calling:
gcc -std=c99 my_file.c
there is no executable called my_file.exe. Help sites online suggest installing additional software to fix the error, but I'm hesitant to do so because everything was working fine earlier and I don't want to aggravate the problem with additional software.
Since you have not specified the name of the file to output, GCC will output a.exe.
If you desire output named something else, you must use the -o flag, for example:
gcc -std=c99 -o my_file.exe my_file.c
On Unix, that compiler command would generate an executable a.out. You may find that there is an executable with a default name — but I don't have Windows to check what that name is. Guesses might include a.exe, a_out.exe, aout.exe, etc.
To get my_file.exe:
gcc -std=c99 -o my_file.exe my_file.c
If you don't specify an output -o flag you will get a.exe by default (a.out on other platforms),
gcc -std=c99 my_file.c
If it is working, produces
a.exe
I think you wanted
gcc -std=c99 -o my_file.exe my_file.c

Resources