How to compile .c .h .so file? - c

Another company gives me three files(demo.c,api.h,libapi.so). they told me that't enough for develop. I'm confuse how to build these thing together.
I use gcc demo.c -o demo -l libapi.so . But's it's said "ld: library not found". I use Mac OS system. Some websites said i should use Linux to use .so file. what should I do?

*.so is "shared object" it works only on Linux. The Windows counterpart of *.so is DLL.These are combiled object code.
What you have to do is
1] "compile" your .c to .o [object file]
2] "Link" the new .o file with the .so

Related

What does g++ / gcc do when asked to link against .a files?

I'm reading a tutorial about C development with the SDL library on MingW and Windows. (The tutorial is actually about C++ but I'm assuming installation and building is the same).
The tutorial gives the following command for building the program:
g++ 01_hello_SDL.cpp -IC:\mingw_dev_lib\include\SDL2 -LC:\mingw_dev_lib\lib -w -Wl,-subsystem,windows -lmingw32 -lSDL2main -lSDL2 -o 01_hello_SDL
In this command we use -L and -l to tell g++ where to find .a files (not .DLL or .so files) for linking. However, as far as I understand - this command is supposed to dynamically link the library. And as we know, .a files are static library files. What am I missing?
Why are we not linking with the .DLL file of the library, but instead we link with these .a files? When executing, the .DLL file will have to be present near the executable, but the .a won't have to as far as I understand. Again, what am I missing?
-l is not only for dynamic libraries. It can also be used to link static libraries.
On Linux, it is normal to directly link with a .so file (equivalent to a .dll). On Windows, it is still possible to do this (I think), but it is more normal to link with a .lib file called an import library, which wraps the .dll (you link to the .lib and the .lib links to the .dll). Since you are not using the Microsoft toolchain, it's possible that your toolchain still uses import libraries, but calls them .a files instead of .lib files.

How to make a .so executable on OSX?

I have a simple C library that I compile to a .so file on my linux machine. I'd like to do the same on my Mac, but after I compile and move the library to /usr/local/lib, but I'm not sure how to link it seeing as ldconfig isn't a thing.
How would I go about doing this?
While Linux has .so files, OSX has .dylib files. The process is similar, you just invoke compiler as in
clang -dynamiclib -o libname.dylib sources.c

Library files in C

Are library files .o or .exe files in C?
Neither; generally .o files are object files and .exe files are fully-linked binaries (on Windows).
Static libraries in Linux are .a
Dynamic libraries in Linux are .so
Static libraries in Windows are .lib
Dynamic libraries in Windows are .dll
It's more operating system dependent than language dependent.
In Windows, they are likely to be .dll files.
In Linux, they are likely to be .a or .so files.
In OS X, they are likely to be .a, .so or .dylib files.
Neither. It also depends on the platform. Also, the file extension is only convention and libraries can have any other or no extension at all.
The answer is libraries are neither *.o or *.exe. Also the naming convention depends on the Platform you are compiling.
A *.so file is a shared lib. *.a is a static library on the Linux platform.
You can specify options at compile time to build the libraries.
Here you can check more about shared libraries and compilation and build options for the same.
In linux, library files are an archive of one or more .o files. Linux uses the 'ar' program ( think 'tar' without the tape ), to create the archive. After bundling them together, you then use the ranlib program to add some indexing.
ar rc mylib.a source1.o source2.o source3.o
ranlib mylib.a

How to create executable coff file from a C source

I am trying to do a simulate with Simcore Alpha/Functional Simulator and I need to create an image file but it is giving an error like "This is not Coff Executable" how can I create an Executable Coff file from a C source in linux?
In order to do this, you'll need a cross compiling gcc that is built to output COFF files. You may need to build gcc yourself if you can't find a pre-built one.
After you download gcc, you will need to configure it. The important option is --target; so if you want to target an Alpha architecture you would do:
configure --target=alpha-coff
I would also recommend you add a prefix to the binaries and install them into a different directory so you have no problems with the compiler interacting with the system compiler:
configure --target=alpha-coff --prefix=/opt/cross-gcc --program-prefix=coff-
(this will create coff-gcc in /opt/cross-gcc/bin, you can tweak those if want something different).
Linux executable format is called ELF.
COFF is a common file format for object modules, which are linked to make an ELF file or an EXE file
In your case if you have access to gcc, you can try
gcc mysource.c -o myprogram

How do you actually use a C library?

I'm sure this question has been asked many times, but I can't figure this out. Bear with me.
So when you download a library, you get a bunch of .c and .h files, plus a lot of other stuff. Now say you want to write a program using this library.
I copy all the .h files into my project directory. It just doesn't compile.
Great, so then I get the library as a bunch of .dll's, and i copy the dlls into my project directory. Still doesn't compile.
How does this work?
What do you do, like right after creating the folder for your project? What parts of the library package do you copy/paste into the folder? How do you make it so that it can compile? Go through the steps with me please.
Where to put the .h files?
Where to put the .dll files?
How to compile?
Thanks.
(the library I'm trying to get working is libpng, I'm in windows with MinGW, and i'm looking to compile from command-line like usual.)
(from what i gather, you put the .h files in directory A and the .dll files in directory B and you can use -l and -L compiler options to tell the compiler where to find them, is this correct?)
Here's a brief guide to what happens when you compile and build a basic C project:
The first stage compiles all your source files - this takes the source files you've written and translates them into what are called object files. At this stage the compiler needs to know the declaration of all functions you use in your code, even in external libraries, so you need to use #include to include the header files of whatever libraries you use. This also means that you need to tell the compiler the location of those header files. With GCC you can use the -I command line to feed in directories to be searched for header files.
The next stage is to link all the object files together into one executable. At this stage the linker needs to resolve the calls to external libraries. This means you need the library in object form. Most libraries will give you instructions on how to generate this or might supply it ready built. Under Linux the library file is often a .a or .so file, though it might just be a .o. Again you can feed the location of the library's object file to GCC with the -L option.
Thus your command line would look like this:
gcc myProg.c -I/path/to/libpng/include -L/path/to/libpng/lib -lpng -o myProg.exe
(Note that when using the -l command line GCC automatically adds lib to the start of the library, so -lpng causes libpng.a to be linked in.)
Hope that helps.
Doing it under windows (supposing you user Visual Studio)
After unpacking add the library include directories to your projects' settings (Project -> Properties -> C/C++ -> Additional Include Directories)
Do the same thing for the Libraries Directory (Project -> Properties -> Linker -> Additional Library Directories)
Specify the name of the library in your Linker Input: Project -> Properties -> Linker -> Input -> Additional Dependencies
After this hopefully should compile.
I don't recommend adding the directories above to the Global settings in Visual Studio (Tools -> Options -> Project and Solutions) since it will create and environment where something compiles on your computer and does NOT compile on another one.
Now, the hard way, doing it for a Makefile based build system:
Unpack your stuff
Specify the include directory under the -I g++ flag
Specify the Library directory under the -L g++ flag
Specify the libraries to use like: -llibrary name (for example: -lxml2 for libxml2.so)
Specify the static libraries like: library name.a
at the end you should have a command which is ugly and looks like:
g++ -I/work/my_library/include -L/work/my_library/lib -lmylib my_static.a -o appname_exe MYFILE.CPP
(the line above is not really tested just a general idea)
I recommend go, grab a template makefile from somewhere and add in all your stuff.
You must link against a .lib or something equivalent i.e. add the ".lib" to the libraries read by the linker. At least that's how it works under Linux... haven't done Windows so a long while.
The ".lib" contains symbols to data/functions inside the .dll shared library.
It depends on the library. For examples, some libraries contain precompiled binaries (e.g. dlls) and others you need to compile them yourself. You'd better see the library's documentation.
Basically, to compile you should:
(1) have the library's include (.h) file location in the compiler's include path,
(2) have the library stubs (.lib) location in the linker's library path, and have the linker reference the relevant library file.
In order to run the program you need to have the shared libraries (dlls) where the loader can see them, for example in your system32 directory.
There are two kinds of libraries: static and dynamic (or shared.)
Static libraries come in an object format and you link them directly into your application.
Shared or dynamic libraries reside in a seperate file (.dll or .so) which must be present at the time your application is run. They also come with object files you must link against your application, but in this case they contain nothing more than stubs that find and call the runtime binary (the .dll or the .so).
In either case, you must have some header files containing the signatures (declarations) of the library functions, else your code won't compile.
Some 'libraries' are header-only and you need do nothing more than include them. Some consist of header and source files. In that case you should compile and link the sources against your application just as you would do with a source file you wrote.
When you compile, assuming you have the libs and the headers in the same folder as the sources you are compiling, you need to add to your compile line -L . -I . -lpng. -L tells the linker where to look for the library, -I tells the compiler where to look for the headers and -lpng tells the linker to link with the png library.
[Edit]
Normal projects would have some sort of hierarchy where the headers are in an /include folder and the 3rd party libs are in a /libs folder. In this case, you'd put -I ./include and -L ./libs instead of -I . and -L.
[Edit2] Most projects make use of makefile in order to compile from the command line. You can only compile manually for a small number of files, it gets quite hectic after that
Also,
you may want to look over Dynamic Loading support in various languages and on various
platforms.
This support is very handy in cases when you want to use a library optionally and you don't want your program to fail in case that library is not available.

Resources