Building against ancient C Object - c

I have a project I'm working on that has code from 1988 and is on Solaris Sparc machines.
I'm not a C programmer, but there is a header file and object file for the old code but no sourcecode.
I can live without it, if I can use the functions in the old object file to plug stuff into and prod the outputs.
/usr/sfw/bin/gcc -Wall -o test main.c
Outputs
Undefined first referenced
symbol in file
KES_ld_kb /var/tmp//cccjn5UP.o
Is there anything I can do to get gcc to build against the object so I can run some of this old code?
-- Edit --
got asked what the code looks like:
#include "kes.h"
#include <stdio.h>
int main(){
KES_ld_kb("/tmp/kb.kb", 50000L);
return 0;
}
-- Another Edit --
I have original .o and .h files, these are SPARC based and I'm doing my work on an old SPARC VM, so that much I do know.
I tried to create an archive with
ar ruv libkes.a kes.o
Which when I then build it returns
bash-3.2$ /usr/sfw/bin/gcc -L/export/home/zmmyks/ps -Wall -o test main.c -lkes
ld: warning: file /export/home/zmmyks/ps/libkes.a ignored: unable to locate archive symbol table

I really don't think you can live without the implementation of functions. A header file serves as a blueprint for the source, but it is not a replacement for it. If KES_ld_kb is defined in those missing source files you need to track those down or this will never work.

Related

How to use functions in a package that is written in C in a different location

I am trying to use a linear algebra package called hnfprof. I have done the installation with the given instructions and now its ready to use. Now I want to use some functions in hnfproj/src/lift/lift.c file. I want to create my own matrix examples and check outputs for each functions separately. I am not clear how to do this. (I know only basics of C language, creating .c files in a folder and running it in my Ubuntu terminal.)
I know that I should write a C file including this "#include <lift.c>" file name and creating a matrix in my file "main.c". I don't know how to include a file name in a different location. When I compile I can not use "gcc -o program main.c lift.c". My "main.c" file is in a different folder. I don't want to create any make file inside the package folder. So how I can just use the "lift.c" file inside my "main.c" file which is in a separate folder "Main" and create all executable make files inside "Main" folder?
If its difficult to give a answer, appreciate if you can suggest me some source to learn this. Thank you
No need to include lift.c directly in main.c, and you can call function in lift.c from main.
When it comes to compilation, you can use:
gcc -o program main.c file_location/lift.c
If you need other options, add them (most flags at the start; libraries at the end, after the source code). You can also compile each file to object code separately and then link the object files together:
gcc -c main.c
gcc -c file_location/lift.c
gcc -o program main.o lift.o
refer
Compiling multiple C files with gcc

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

Building object files that depends on other object files

EDITS: Including link to my makefile
I have a main program that calls a bunch of functions defined in other source files. This is not a problem because I am using cc -c functionSource.c functionHeader.h and generating object files before compiling my main program with cc main.c func1.o func2.o .... -o test.o
I am having problems when one of my functions depends on another function.
For example:
My main program calls an shuffle function which is defined in it's own source file and the shuffle function calls a swap function which in turn is defined in it's own source file.
When i try to generate the shuffle.o file for my main program using cc -c shuffle.o I get an undefined reference to swap error.
When I try to cc shuffle.c swap.o i get an undefined reference to main error.
Here is my makefile
How do I go about fixing this?
Found the problem. I had a swap function declared inside insertionSort.h and shuffle.h but no implementations.
Have a look to the man page: '-c' makes the compiler generating object files only (not trying to link).
Do the following:
cc -c insertionSort.c # => gives insertionSort.o
cc -c -c functionSource.c # => gives functionSource.o
cc insertionSort.o functionSource.o ...and-so-on... main.c -o test
It's not necessary to specify header files - it doesn't help.
BTW: If you have mor than one implementation file, it is rather useful
(a) to learn make
(b) stick to the convention that object files and programs should be named like th sources.
E.g:
foo.c => foo.o
bar.c => bar
etc - you get the picture.
This has nothing to do with make. You need to get a book on introductory C programming, that will explain how to use the preprocessor, and you need to examine the documentation for your compiler so you understand what the different compiler flags do (such as when you want to use the -c flag and when you don't, and what the difference is).
It's wrong to include header files (.h files) on the compile line. Only source files (.c) should be included on the command line when building object (.o) files. You should be adding the headers you need into your .c files using the #include directive: #include "insertionSort.h". If you're missing a reference to a function, then #include the header file that declares that function: #include "swap.h".

Including source files in C

So I get the point of headers vs source files. What I don't get is how the compiler knows to compile all the source files. Example:
example.h
#ifndef EXAMPLE_H
#define EXAMPLE_H
int example(int argument); // prototype
#endif
example.c
#include "example.h"
int example(int argument)
{
return argument + 1; // implementation
}
main.c
#include "example.h"
main()
{
int whatever;
whatever = example(whatever); // usage in program
}
How does the compiler, compiling main.c, know the implementation of example() when nothing includes example.c?
Is this some kind of an IDE thing, where you add files to projects and stuff? Is there any way to do it "manually" as I prefer a plain text editor to quirky IDEs?
Compiling in C or C++ is actually split up into 2 separate phases.
compiling
linking
The compiler doesn't know about the implementation of example(). It just knows that there's something called example() that will be defined at some point. So it just generated code with placeholders for example()
The linker then comes along and resolves these placeholders.
To compile your code using gcc you'd do the following
gcc -c example.c -o example.o
gcc -c main.c -o main.o
gcc example.o main.o -o myProgram
The first 2 invocations of gcc are the compilation steps. The third invocation is the linker step.
Yes, you have to tell the compiler (usually through a makefile if you're not using an IDE) which source files to compile into object files, and the compiler compiles each one individually. Then you give the linker the list of object files to combine into the executable. If the linker is looking for a function or class definition and can't find it, you'll get a link error.
It doesn't ... you have to tell it to.
For example, whe using gcc, first you would compile the files:
gcc file1.c -c -ofile1.o
gcc file2.c -c -ofile2.o
Then the compiler compiles those files, assuming that symbols that you've defined (like your example function) exist somewhere and will be linked in later.
Then you link the object files together:
gcc file1.o file2.o -oexecutable
At this point of time, the linker looks at those assumtions and "clarifies" them ie. checks whether they're present. This is how it basically works...
As for your IDE question, Google "makefiles"
The compiler does not know the implementation of example() when compiling main.c - the compiler only knows the signature (how to call it) which was included from the header file. The compiler produces .o object files which are later linked by a linker to create the executable binary. The build process can be controlled by an IDE, or if you prefer a Makefile. Makefiles have a unique syntax which takes a bit of learning to understand but will make the build process much clearer. There are lots of good references on the web if you search for Makefile.
The compiler doesn't. But your build tool does. IDE or make tool. The manual way is hand-crafted Makefiles.

Resources