Compiling cmocka on windows - c

I'm trying to compile a simple unit test on my windows machine.
When I'm trying to compile my test I'm using the shared library flag.
gcc -c -L./bin/ -lcmocka .\Test.c .\src\some_module.c
gcc .\Test.o .\some_module.o -o main
But the second line throws this error:
undefined reference to `_cmocka_run_group_tests'
However, if I'm compiling using directly the cmocka.c file which I downloaded from their git it works fine:
gcc -c .\lib\cmocka.c .\Test.c .\src\some_module.c
gcc .\Test.o .\some_module.o .\cmocka.o
What am I doing wrong in the first compilation?
In addition, I would happy to understand the difference between the two compilations. Which one is the better practice?
Thank you

In order to compile your code, the compiler does not need to know where to look for the library. It's enough if the compiler "finds" the declarations of the functions which are usually in the header files provided by the library.
This step is done in the first line of your compilation procedure (maybe you need to specify the folder to the header files by adding -Ipath/to/headers/):
gcc -c .\Test.c .\src\some_module.c
The library itself is "combined" with your code during the linking step, which is done during your second compilation step. Here you need to specify the library (and its path via -Lpath/to/library, if the linker does not find the library on its own):
gcc .\Test.o .\some_module.o -o main -L./bin/ -lcmocka
You should definitely not use your second approach and compile the library by yourself.

Related

How to use LibFuzz on a C project that is not a library

I am trying to run libFuzz on a C project that usually compiles to an executable. The examples I found for libFuzz almost exclusively link with a library, i.e. a mylibary.a file. So I compiled the project with the normal Makefile, and combined the generated object files into a library with ar rcs a.o b.o etc.. Now I want to link this library file with the fuzzing target using clang++, but the linker is not able to find the implementation of the function I want to fuzz.
The command I use for linking inside the src directory of the project is
clang++ -Wall -fsanitize=fuzzer -Wno-cpp -Wpedantic -std=c++11 -O2 -g  -I/usr/include/libxml2 -g -O2 -rdynamic  -o fuzzing libmylib.a fuzztarget.cc -lcurl -lxml2 -I.
The error I get is "Undefined reference to function_xy()"
So the compiler finds the import of the function but not the implementation of it.
I am new to clang and generally building complex C projects so all help is greatly appreciated. Thank you!
I tried compiling the project with the included Makefile, then combining the generated object files into a .a library and finally linking the library with my fuzzing target.
The error you got is about linking, not the LibFuzzer. If you can compile and link your file without implementing function in LLVMFuzzerTestOneInput, then the fuzz-target should work: Include header in your code, call the function, compile file and link with libraries. Please check the order of include path, file, linked libraries. Be careful with the option of optimization (-O2), sometimes the fuzzer does not give crash with this option.

Clang: compile IR, C files and apply opt in one line

I'm building an IR level Pass for LLVM which instrument the functions with calls to my runtime library.
So far I have used the following lines to compile any C file with my pass and link it with the runtime library and guaranteeing that the runtime library function calls are inlined.
Compiling source to IR...
clang -S -emit-llvm example.c -o example-codeIR.ll -I ../runtime
Running Pass with opt...
opt -load=../build/PSS/libPSSPass.so -PSSPass -overwrite -always-inline -S -o example-codeOpt.ll example-codeIR.ll
Linking IR with runtime library...
llvm-link -o example-linked.bc example-codeOpt.ll ../runtime/obj/PSSutils.ll
Compiling bitcode to binary...
clang -ldl -O3 -o example example-linked.bc ../initializer/so/shim.so
Now I would like to test my pass with the LLVM testsuite and the only thing I can do is pass flags to the test suite. I can't control the steps of of compilation and generate so many files for each test case.
Is there a way to do the same as above without having to save intermediate files and yet keep the order of the steps?
I have tried the following:
clang -ldl -Xclang -load -Xclang ../build/PSS/libPSSPass.so ../initializer/so/shim.so ../runtime/obj/PSSutils.ll $<
But I ran into the problem that I can't compile both IR and .c files.
If I compile the runtime library to be an object file the functions in it will not get inlined anymore which is the main goal of the above steps.
So to Answer my question:
first of all, call to shared objects are never inlined. hence, the above mentioned shared objects should be compiled to objects instead. The -flto=thin flag should be used when compiling the objects to build a summary of the functions so the linker can perform link time optimizations.
And in the final step of compiling the target you will need to also compile it with -flto=thin flag and the compiler will do the magic for you.

Calling functions from an external C file that has its own main()

I have two C files, program.c and tests.c, that each contain a main function.
program.c is a standalone program, that compiles and run normally on its own. But I would like to also be able to use some of its functions in tests.c (without using a common header file). Is there a way of doing this?
If I insert the prototype of the function I want from program.c into tests.c and compile with:
gcc -o program.o -c program.c
gcc -o tests.o -c tests.c
gcc -o tests tests.o program.o
I obtain an error duplicate symbol _main, which I understand since there are indeed two `main' functions.
I basically would like to be able to treat program.c both as a standalone program and as a library, similarly to what could be done in Python with if __name__ == '__main__'.
If you need to have two separate distinct executables for which some of the functionality between them is similar you can share the common functionality by placing relevant functions into a third file, and compiling as a portable executable, DLL in Windows. (or shared library in Linux.) Each of these file types contain sharable, executable code, ithout the main() function, designed to be linked during compile time, and dynamically loaded into your executable at runtime.
Here is a step by step set of instructions for shared library using GCC and Linux.
Here is a step by step example for creating DLL using GCC in windows.
So I managed to achieve what I wanted thanks to the comment from #pmg:
I compile program.c into a standalone binary (gcc -o program program.c), but I also compile it into an object file with "main" renamed (gcc -c -Dmain=mainp -o program.o program.c).
I can then use this object file (that does not contain a "main" symbol anymore) to compile tests.c: gcc -o tests tests.c program.o.
Thanks #pmg, I did not know this use of the -D option.

C program links to wrong version of function

I'm trying to debug an issue where the wrong version of a function gets called causing a segfault. The code that I'm compiling is machine generated and includes a function called 'times' that does a complex multiply of it's two arguments. This code is compiled to a .o before being linked into a higher level object file.
When run this code segfaults and gdb indicates that it's in glibc's version of 'times' which doesn't even take the same number of arguments. The are no instances of '#include anywhere in this code.
Changing the name of times to times1 resolves the problem. This isn't a long term solution though due to the machine generated nature of the code and manually editing the name of this function all the time is unappealing.
The whole mess compiles cleaning with -Wall so I'm not sure where to look. Any ideas on how to resolve this?
Compile chain:
gcc -Wall -I. -g --shared -o dpd.o -fPIC *.c (mahine generated code here)
gcc -g --std=c99 -c -fpic getData.c -I/usr/local/include -L/usr/local/lib -lmatio -I/usr/local/include/iverilog -I$(MATLAB)
gcc -g -shared -o getData.vpi getData.o $(MATLAB)/dpd.o -lvpi -lmatio -L/usr/local/lib
C only uses the name of a function as an identifier, so any two (exported) functions with the same name will conflict. The normal approch is to prefix all exported names in a library with a unique prefix. The other alternative is to use C++ as "a better C" and simply build your C code using a C++ compiler, making use of C++ name mangling.
So the real answer to this one is to throw -fno-builtin-times to gcc. That avoids the problem neatly with no fuss.
This of course assumes that you can't changes the name of times to something that doesn't conflict with a glibc provided function.

Linking with GCC and -lm doesn't define ceil() on Ubuntu

I am currently using GCC to compile and I need to use <math.h>.
The problem is that it won't recognize the library.
I have also tried -lm and nothing.
The function I tried to use was ceil() and I get the following error:
: undefined reference to `ceil'
collect2: ld returned 1 exit status
I am using the latest Ubuntu and math.h is there.
I tried to use -lm on a different computer, and it worked perfectly.
How can I solve this problem?
I did include <math.h>. Also, the command I used was:
gcc -lm -o fb file.c
Take this code and put it in a file ceil.c:
#include <math.h>
#include <stdio.h>
int main(void)
{
printf("%f\n", ceil(1.2));
return 0;
}
Compile it with:
$ gcc -o ceil ceil.c
$ gcc -o ceil ceil.c -lm
One of those two should work. If neither works, show the complete error message for each compilation. Note that -lm appears after the name of the source file (or the object file if you compile the source to object before linking).
Notes:
A modern compiler might well optimize the code to pass 2.0 directly to printf() without calling ceil() at all at runtime, so there'd be no need for the maths library at all.
Rule of Thumb: list object files and source files on the command line before the libraries. This answer shows that in use: the -lm comes after the source file ceil.c. If you're building with make etc, then you typically use ceil.o on the command line (along with other object files); normally, you should list all the object files before any of the libraries.
There are occasionally exceptions to the rule of thumb, but they are rare and would be documented for the particular cases where the exception is expected/required. In the absence of explicit documentation to the contrary, apply the rule of thumb.
I just wanted to mention that Peter van der Linden's book Expert C Programming has a good treatment on this subject in chapter 5 Thinking of Linking.
Archives (static libraries) are acted upon differently than are shared objects (dynamic libraries). With dynamic libraries, all the library symbols go into the virtual address space of the output file, and all the symbols are available to all the other files in the link. In contrast, static linking only looks through the archive for the undefined symbols presently known to the loader at the time the archive is processed.
If you specify the math library (which is usually a static one) before your object files, then the linker won't add any symbols.
Try compiling like that:
gcc -Wall -g file.c -lm -o file
I had the same problem and it was solved using this command. Also if you installed your Ubuntu the same day you had the problem it might be an update problem.

Resources