LLVM CFG for multiple files - llvm

I am trying to generate a CFG from 3 C source files using LLVM tools.
clang -emit-llvm -c a.c b.c c.c main.c
Thereafter I use llvm-link to link the bytecode together.
llvm-link -o out a.bc b.bc c.bc main.bc
However by doing this I get an unexpected CFG.
Here are my source files:
#include "m.h"
void a(){
b();
}
void b(){
c();
}
a.c
#include "m.h"
void c(){
e();
}
void d(){
f();
}
b.c
#include "m.h"
void e(){
f();
}
void f(){
d();
}
c.c
#include "m.h"
int main(){
a();
e();
return 0;
}
main.c
The m.h file has the function prototypes.
What could be the problem here?

Related

How to use extern for declaring/defining global variable in C++ and CUDA

I have the following code structure composed of one .cpp, one .cu and one .hxx
UTILITIES.hxx
#ifndef UTILITIES_HXX
#define UTILITIES_HXX
namespace B{
extern int doors;
}
FILE2.cu
#include "utilities.hxx"
namespace A {
int foo (){
switch(B::doors){
//do something
}
}
}
FILE3.cxx
#include "utilities.hxx"
namespace B{
int doors=-1;
class Vehicle{
public:
void operation() {
doors++;
A::foo();
doors++;
A::foo();
}
}
}
I am declaring the doors variable as extern in the header and I am defining it in the .cxx file. So after that, the second .cpp should be able to use it. However I am getting the following error when linking:
/usr/bin/ld: ../src/libapp.a(FILE2.cu.o): in function A::foo(void)': /MYPATH/FILE2.cu:19: undefined reference to B::doors'
What am I doing wrong? Actually the foo function in the FILE2.cu is a normal C++ function, no CUDA involved at all.
missing #endif, missing return statement, no prototype for A::foo(), missing semicolon
These changes seem to work for me:
$ cat utilities.hxx
#ifndef UTILITIES_HXX
#define UTILITIES_HXX
namespace B{
extern int doors;
}
#endif
$ cat file2.h
namespace A {
int foo ();
}
$ cat file2.cu
#include "utilities.hxx"
namespace A {
int foo (){
switch(B::doors){
//do something
}
return 0;
}
}
$ cat file3.cpp
#include "utilities.hxx"
#include "file2.h"
namespace B{
int doors=-1;
class Vehicle{
public:
void operation() {
doors++;
A::foo();
doors++;
A::foo();
}
};
}
$ nvcc -shared file2.cu file3.cpp -Xcompiler -fPIC
$ nvcc -lib file2.cu file3.cpp
$
I can only work with what you have shown.

How to write a static C++ library and link it to an executable using g++ on Windows 10?

main.cpp
#include <iostream>
int main() {
std::cout << "main()" << std::endl;
foo();
return 0;
}
foo.cpp
#include <iostream>
extern "C" {
void foo() {
std::cout << "bar" << std::endl;
}
}
Compile static library:
$ g++ foo.cpp -static
Error:
undefined reference to `WinMain'
But this compiles:
$ g++ foo.cpp -shared -o foo.lib
Now I have a static library named foo.lib (supposedly).
I try to compile an executable that links to it:
$ g++ -L -lfoo main.cpp -o main.exe
And get this error:
'foo' was not declared in this scope
But foo is declared in the static library that I'm linking with. If the link works, I don't think I need to declare it in main.cpp also. So why isn't the link working?
Update.
I added void foo(); to main.cpp so it doesn't complain that foo needs to be declared.
#include <iostream>
void foo();
int main() {
std::cout << "main()" << std::endl;
foo();
return 0;
}
So I try to compile again and I get this new error:
undefined reference to `foo()'
Why would I need to define foo in main.cpp? It's already defined in foo.cpp which is the static library.
If I have to define foo in main.cpp that defeats the entire purpose of linking to the library foo.lib.
UPDATES
Removing all the extern "C" { ... } lines doesn't make the "foo is undefined" errors go away.
What follows are the magical incantations you seek:
main.cpp
#include <iostream>
extern void foo();
int main() {
std::cout << "main()" << std::endl;
foo();
}
foo.cpp
#include <iostream>
void foo() {
std::cout << "bar" << std::endl;
}
Console commands:
$ g++ -o foo.obj -c foo.cpp
$ ar rcs foo.lib foo.obj
$ g++ main.cpp foo.lib -o main.exe
These spells conjure up the static lib foo with the executable main statically linked to it.

i cant get my program to work i keep getting undefined symbol: c

I'm trying to load all the libraries, and call a function from each one, to create a file and shate the fiddle thru the pointer, and write stuff in the main program with them, the close them.
This is my main function:
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
char LIBA[]="./LIBA.SO";
char LIBB[]="./LIBB.SO";
char LIBC[]="./LIBC.SO";
typedef void (*FUNC_T)(int*);
FUNC_T FUNC[2];
void ifnull(void *detect)
{
if (detect == NULL)
{
cout << "ERROR:" << dlerror() << endl;
exit(-1);
}
}
void ifnull2(FUNC_T detect)
{
if (detect == NULL)
{
cout << "ERROR:" << dlerror() << endl;
exit(-1);
}
}
int main()
{
void *handle[2];
int FD[2];
handle[0]=dlopen(LIBA, RTLD_LAZY); ifnull(handle[0]);
handle[1]=dlopen(LIBB, RTLD_NOW); ifnull(handle[1]);
handle[2]=dlopen(LIBC, RTLD_NOW); ifnull(handle[2]);
FUNC[0]=(void(*)(int*))dlsym(handle[0], "c"); ifnull2(FUNC[0]);
FUNC[1]=(void(*)(int*))dlsym(handle[1], "c"); ifnull2(FUNC[1]);
FUNC[2]=(void(*)(int*))dlsym(handle[2], "c"); ifnull2(FUNC[2]);
FUNC[0](&FD[0]); FUNC[1](&FD[1]); FUNC[2](&FD[2]);
return 0;
}
This is inside the libs:
#include <stdio.h>
void c(int *fd)
{
printf("ok A\n");
}
I keep getting
ERROR:./LIBA.SO: undefined symbol: c
please help
C++ mungs function names because it can have multiple functions with the same name.
So, for
#include <stdio.h>
void c(int *fd)
{
printf("ok A\n");
}
we get
$ g++ -Wall -Wextra -pedantic -c -fPIC liba.cpp -o liba.so
liba.cpp: In function ‘void c(int*)’:
liba.cpp:3:13: warning: unused parameter ‘fd’ [-Wunused-parameter]
void c(int *fd)
^~
$ nm liba.so
U _GLOBAL_OFFSET_TABLE_
U puts
0000000000000000 T _Z1cPi
As you can see, the function exists as _Z1cPi. I'm not sure if that's safe to use. What you can do, however, is use extern "C".
For
#include <stdio.h>
extern "C" void c(int *fd)
{
printf("ok A\n");
}
we get
$ g++ -Wall -Wextra -pedantic -c -fPIC liba.cpp -o liba.so
liba.cpp: In function ‘void c(int*)’:
liba.cpp:3:24: warning: unused parameter ‘fd’ [-Wunused-parameter]
extern "C" void c(int *fd)
^~
$ nm liba.so
0000000000000000 T c
U _GLOBAL_OFFSET_TABLE_
U puts

Linking shared libraries with executables

I have a small doubt in the compilation of a c++ code along with a shared library.
So I have two files main.cpp and sample.cpp.
main.cpp
#include <iostream>
using namespace std;
#include "sample.h"
myStruct obj;
void populateData() {
obj.s = "hello world";
}
myStruct giveData() {
cout << "Inside main: " << obj.s << endl;
return obj;
}
int main() {
populateData();
}
sample.h
#ifndef SAMPLE_H
#define SAMPLE_H
#include <string>
struct myStruct {
std::string s;
void populateData();
};
myStruct giveData();
#endif
sample.cpp
#include "sample.h"
#include <iostream>
#include <boost/python.hpp>
using namespace std;
void myStruct :: populateData() {
cout << giveData().s;
}
BOOST_PYTHON_MODULE(boosts) {
using namespace boost::python;
class_<myStruct>("struct")
.add_property("s", &myStruct::s)
.def("populateData", &myStruct::populateData)
;
}
I compile the program using
g++ -c -fPIC sample.cpp
g++ -c -fPIC main.cpp
g++ -shared -Wl,-soname,boosts.so -o boosts.so sample.o main.o -lpython2.7 -lboost_python
g++ -o main main.o
./main
Now, when I run the main, it populates the string inside the obj. But when I run a python script, that imports the boosts.so, the obj.s is empty.
I am guessing it is because the library boosts.so is not properly linked with the executable main.
How do I fix this?

Using extern and linking files

So I am supposed to link these 3 files but when I run use.cpp and it tells me there is a problem with print_foo and print so there must be a problem with my linking or declarations;(FYI I am using Xcode to compile)
This is the header file
// my.h (HEADER FILE)
extern int foo;
void print_foo();
void print(int);
This is my.cpp
// my.cpp
#include "my.h"
#include "std_lib_facilities_5.h"
void print_foo() {
cout << foo;
}
void print(int i) {
cout << i;
}
int main() {
return 0;
}
And this is use.cpp
// use.cpp
#include "my.h" /* Declaration made available here */
int foo;
int main() {
foo = 7;
print_foo();
print(99);
return 0;
}
You did not mention how you are compiling them, on unix like systems you can do
$ gcc my.cpp use.cpp -o my
to compile
You must delete the main in
my.cpp
You can't have two main.