How to link pnglite library in c? - c

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

Related

how do I import a c library?

I'm new to programming and am taking the cs50 online course, the course provides an online container with an IDE but in order to do the problem sets offline i downloaded the library files but haven been able to reference them on my code, the library import statement is declared as not used and the function from that library is marked as non existent, could anyone lend a helping hand? print from the issue
Download all the files, I suppose they are cs50.h and cs50.c.
Put both files in the same directory of your main file, and use include statement for cs50.h like this:
#include "cs50.h"
When we use a library that is not in the standard library folder, we must include it with "" instead of <>
Note by editor
The above statement is stricken because it's misleading. You can in fact use <> to include your own headers, provided you pass the directory in which those headers reside as one of the search paths to your compiler.
Let's say you want to compile foo.c that uses a header file called bar.h residing in /where/bar/lives/include/ directory, and a library called libbar.a in /where/bar/lives/lib/ directory, then in majority of C compilers you can use -I flag and -L flags to make it possible to include and link the right bits into your project:
To compile your program foo.c you would:
cc -I/where/bar/lives/include -o foo.o -c foo.c
To link you would:
cc -o foo foo.o -L/where/bar/lives/lib -lbar
These two steps would produce your program binary foo
Interestingly you can use -I. and -L. to include present working directories and use <> to your heart's content.
First off, the mechanism is called include in C, as the code itself suggests.
Then, your issue is in the #include statement. Using <...> tells the compiler (specifically the preprocessor) to look for libraries installed in your system. To include local libraries you should use "...". When using this, also pay attention to the path because it's relative.
So, considering your folder structure, the include statement should be
#include "src/cs50.h"

How to use shared object file in c compilation

I'm trying to use this C library using gcc Apple LLVM version 8.0.0 (clang-800.0.42.1) on macOS Sierra. I've done the following steps:
make libquirc.so
Copied libquirc.so into my project directory
gcc -o quirc_test quirc_test.c -L. -l libquirc.so.1.0
It produces the error:
quirc_test.c:1:10: fatal error: 'quirc.h' file not found
#include <quirc.h>
^
1 error generated.
quirc_test.c
#include <quirc.h>
This is the first time I've tried to do anything in C and other related questions about compiling with the link flag didn't seem to help as seen above.
C is somewhat primitive. Shared object libraries do not contain the declaration of the API they implement - at least not in enough detail or a form that the compiler can understand.
You'll need the header file quirc.h somewhere you can find it. You could just copy it into the current directory just like the library, but you'll need a minor adjustment to the include statement.
#include "quirc.h"
If the included file is surrounded by double quotes instead of angle brackets, it will first look in the source code directory instead of the system header directories.
An alternative is to install the library somewhere e.g. /usr/local. Your library would go in /usr/local/lib nd your header in /usr/local/include. If you do that, use the -I directive on the compiler command line to tell the compiler where to look for the header e.g.
cc -I/usr/local/include -L/usr/local/lib -lquirc quirc_test.c

Compiling with .lst file

I am trying to install the MIRACL library for my crypto system. While I was configuring the library, it gave me "miracle.lst" that contains list of files I need to compile. I was just wondering is there any way me to compile all files inside of .lst file once? I don't think it is an assembly file because it only contains names. I saw this link but it is nothing related with my situation.
List File In C (.LST)
Inside of miracl.lst
mrcore.c
mrarth0.c
mrarth1.c
mrarth2.c
...
In my case
gcc -I./include -c -O2 source/mr*.c

Use one c source code file in multiple projects

I've written several c text processing functions that I've placed in a the files: string_functions.c and string_functions.h.
I was using these functions for one project and that worked out well. Now I want to use these same functions in a completely different project at the same time. I'm using gcc in Debian.
Is there a good way to use the same c source code in multiple projects at the same time. The projects are in different sub-directories with the same parent directory.
How do I structure the make files to do this?
Or do I just place a copy of the string_functions.c(h) in both projects. This seems like it would make it harder to maintain the source code.
Best way to do this is to build your C files (.h and .c) into a shared library.
There are many tutorials available on how to do this with gcc; one is at this link
Once the shared library is built, you can then link it into many other projects.
Briefly, these are the steps.
Ensure your string_functions.c includes string_functions.h and builds, of course.
Then compile position independent (that's what -fPIC is for)
$gcc -Wall -fPIC -c string_functions.c
Finally build your shared library like this
$gcc -shared -o my_stringfunctions.so string_functions.o
To link to your new shared library from some other program, ensure that whatever directory
you put it in is in your LD_LIBRARY_PATH.
Then you may link using something like
$gcc my_otherprogram.c -L/path/to/my/lib -lmy_stringfunctions
As pointed out, one should put include files (.h) used by a shared library in some directory path, and add the location to the include search path using the -I option:
$gcc my_otherprogram.c -I/path/to/include/files -L/path/to/my/lib -lmy_stringfunctions
If this is how your directory looks:
/parent
/project1
...
string_functions.h
string_functions.c
/project2
...
string_functions.h
string_functions.c
Then all you have to do is store it in a common location, and then point to that location when building your code. This is the standard way of doing it for custom installed libraries in /opt/, for example.
Hence, one suggestion is to do your directory structure like this:
/parent
/include
string_functions.h
string_functions.c
/project1
...
/project2
...
And when building your respective projects, you include that search path when compiling (using the -I flag):
gcc mainfile.c -I/parent/include <other options>

MinGW linker can't find MPICH2 libraries

MPICH2 is installed in C:\Program Files\MPICH2. There are two subdirectories (of interest), \include which contains .h files, and \lib which contains .lib files.
The readme that comes with MPICH2 has the following instructions:
create a makefile
add –I...mpich2\include
add –L...mpich2\lib
add –lmpi
add the rules for your source files
compile
Since there are no other rules in my project, I don't create a makefile, I just go to the command line and try compiling like this:
g++ -I"C:\Program Files\MPICH2\include" main.cpp -L"C:\Program Files\MPICH2\lib" -lmpi
This gives me a fistful of undefined reference errors on every single MPI symbol in the code. I spent hours trying to fix it, juggling -I, -L and -l switches around, shuffling the order of the parameters, even copied all the .lib files into the same directory as my source, but nothing seems to work.
What kind of voodoo is needed to get this thing to link?
EDIT: I think I found the problem: here's an excerpt of the linker's output in verbose mode (adding -Wl,--verbose to the compile command):
attempt to open C:\Program Files\MPICH2\lib/libmingwex.dll.a failed
attempt to open C:\Program Files\MPICH2\lib/mingwex.dll.a failed
attempt to open C:\Program Files\MPICH2\lib/libmingwex.a failed
attempt to open C:\Program Files\MPICH2\lib/mingwex.lib failed
attempt to open C:\Program Files\MPICH2\lib/libmingwex.dll failed
attempt to open C:\Program Files\MPICH2\lib/mingwex.dll failed
attempt to open C:\Program Files\MPICH2\lib\libmingwex.a failed
Apparently, the linker adds a / instead of a \ to the directory names I supply it with (except when looking for the lib___.a format for some reason), which is obviously not a valid path. Is there any way to tell the linker to use backslashes instead of slashes?
This also caught my eye:
attempt to open /mingw/lib/libmingwex.a succeeded
So I tried compiling like this:
g++ -I"/Program Files/MPICH2/include" -L"/Program Files/MPICH2/lib" objManager.cpp ongom.cpp io.cpp main.cpp -lmpi -lcxx
But I still get the same undefined reference errors.
GCC is able to find your library. Otherwise it would report: cannot find -lmpi.
Somehow it happens that the routines cannot be found in that library. I managed to compile an example with this syntax:
g++ -I../include cpilog.c ../lib/mpi.lib ../lib/mpe.lib
I did that inside msys though. And my directory does not contain spaces.
After removing libmpi.a file, this also works:
g++ -I../include -L../lib cpilog.c -lmpi -lmpe
try adding -lmpicxx (the lib for the c++ bindings), and make sure the -l... come after the cpp source file *. this works for me:
g++ -Iinclude -Llib test/cxxpi.cpp -lmpicxx -lmpi
EDIT: re: "undefined reference to 'MPI_Comm_rank'": could it be that your are mixing up / using c and / instead of c++? MPI_Comm_rank seems to be the c binding - the c++ binding would be MPI::Comm::Get_rank(). maybe try compiling your program as c, or, if you want to use c++, using the proper bindings (see cxxpi.cpp in the examples dir)?
* http://newsgroups.derkeiler.com/Archive/Comp/comp.parallel.mpi/2006-08/msg00036.html
I had the similar problem resulting from linking 32-bit object files with 64-bit MPICH library. Linking with 32-bit libmpi.a solved the problem.
I had a similar issue with mingw: for those library files with a .lib ending, I had to put the name of the library without the ending (e.g. -llibboost_system-mgw34-mt when the filename is libbboost_system-mgw34-mt.lib). For library files with a .a ending, I had to put the name of the library excluding the starting "lib" and the trailing .a (e.g. -lws2_32 for libws2_32.a).
So in your case - try -llibmpi (or whatever your file is called without the .lib ending), perhaps it's the same issue.
from: http://www.mingw.org/node/98/revisions/358/view
Note: some paths were printed with “/” as the path separator while some other was printed with “\” as the path separator. I've substitued all with “/” as MinGW GCC accept both.
So I would not put too much time into finding a way to correct the path seperator. Is your library compiled for mingw?
perhaps: http://www.mingw.org/wiki/LibraryPathHOWTO helps you a bit further.

Resources