Given the following function pass definition and registration:
// STL
#include <map>
#include <vector>
#include <utility>
// LLVM
#include <llvm/Pass.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Instruction.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/CFG.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/IR/InstIterator.h>
#include <llvm/IR/Constants.h>
// For older versions of llvm you may have to include instead:
// #include "llvm/Support/CFG.h"
// #include <llvm/Support/InstIterator.h>
using namespace llvm;
namespace {
class DefinitionPass : public FunctionPass {
public:
static char ID;
DefinitionPass() : FunctionPass(ID) {}
virtual void getAnalysisUsage(AnalysisUsage &au) const {
au.setPreservesAll();
}
virtual bool runOnFunction(Function &F) {
// TODO
errs() << "def-pass\n";
return false;
}
};
class FixingPass : public FunctionPass {
public:
static char ID;
FixingPass() : FunctionPass(ID){}
virtual bool runOnFunction(Function &F){
// TODO
errs() << "fix-pass\n";
return true;
}
};
} // namespace
char DefinitionPass::ID = 0;
char FixingPass::ID = 1;
// Pass registrations
static RegisterPass<DefinitionPass> X("defpass", "Reaching definitions pass");
static RegisterPass<FixingPass> Y("fixpass", "Fixing initialization pass");
I compile this given the following makefile. The compilation is successful:
CXXFLAGS = -rdynamic $(shell llvm-config --cxxflags) -g -O0 -std=c++0x
all: p34.so
%.so: %.o
$(CXX) $(CXXFLAGS) -dylib -shared -fPIC $^ -o $#
clean:
rm -f *.o *~ *.so
Then I create the bitcode file for the file I want to analyse using:
clang -O3 -emit-llvm test1.c -c -o test1.bc
And use opt in the following way:
opt -load p34.so -defpass < test1.bc > /dev/null
But opt is unable to find the function pass "defpass":
opt: Unknown command line argument '-defpass'. Try: 'opt --help'
I'm on OSX and use the homebrew installed LLVM version.
Does anbody have an idea why opt cannot find the pass?
.so Files are for Linux/Unix. On MAC you should be using p34.dylib
Quoting "https://github.com/banach-space/llvm-tutor"
"Finally, run HelloWorld with opt (use libHelloWorld.so on Linux and libHelloWorld.dylib on Mac OS):"
Related
I can't use Rcpp as a 3rd party library for C++.
My sample code is as follows:
main.cpp
#include <Rcpp.h>
#include <iostream>
using namespace Rcpp;
int main() {
std::cout << 1;
Rcpp::ListMatrix a;
system("pause");
return 0;
}
Then I compile using g++
g++ main.cpp -E -o main.i -I "D:/R-4.1.0/include" -I "D:/R-4.1.0/library/Rcpp/include"
g++ -S main.i -o main.s
g++ -c main.s -o main.o
g++ main.o -L"D:\R-4.1.0\library\Rcpp\libs\x64" -l "Rcpp" -L"D:\R-4.1.0\bin\x64" -l "R" -o main.exe
It successfully spawned main.exe.
But when I run main.exe, the program throws an exception.
It shows that these codes in Rcpp cannot run.
Vector( const Dimension& dims) {
Storage::set__( Rf_allocVector( RTYPE, dims.prod() ) ) ;
init() ;
if( dims.size() > 1 ){
AttributeProxyPolicy<Vector>::attr( "dim" ) = dims;
}
}
Then I found that when the constructors of vector in Rcpp all have functions prefixed with Rf, exceptions are thrown.
why this happen?
I try this,and it it didn't throw exception.
#include <Rcpp.h>
#include <iostream>
using namespace Rcpp;
int main() {
std::cout << 1;
Rcpp::S4 a;
system("pause");
return 0;
}
I think it may have something to do with the function prefixed with Rf.
The code examples explain the problem fairly straightforward:
Hash.h
#include <iostream>
#include <cstdint>
using namespace std;
class Hash {
public:
Hash(int64_t sz);
int64_t size;
};
Hash.cpp
#include "Hash.h"
using namespace std;
Hash::Hash(int64_t sz) : size(sz)
{
cout << "Hash int" << endl;
}
main.cpp
#include "Hash.h"
using namespace std;
int main(int argc, char *argv[])
{
Hash HashTable(12);
return 0;
}
And here is the version file, foo.map:
VER_0.1
{
global:
extern "C++" {
"Hash::Hash(int64_t)";
};
local:
*;
};
For the compilation:
$g++ -g -c -Wall -Werror -fpic Hash.cpp -std=c++0x
$g++ -shared -o Hash.so Hash.o -std=c++0x -Wl,--version-script=foo.map
$g++ -g -o prog Hash.so main.cpp -std=c++0x
The error message:
/tmp/ccd60Ulm.o: In function `main':
/remote/ltg_engine1_us03/liangwa/test/004/main.cpp:7: undefined reference to `Hash::Hash(long)'
collect2: error: ld returned 1 exit status
Then if I change all int64_t to int or long, it compiles fine. So anything special with int64_t? I am using g++ 7.3.0
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?
I have some trouble with building the part of my project. Here it is:
utility.h:
#ifndef UTILITY_H
#define UTILITY_H
#include <boost/array.hpp>
#include <boost/shared_ptr.hpp>
#include <fstream>
#include <iostream>
#include <openssl/md5.h>
#include <string>
namespace utility {
typedef boost::array<unsigned char, MD5_DIGEST_LENGTH> md5sum;
typedef boost::shared_ptr<md5sum> md5sum_ptr;
...
md5sum_ptr calculate_md5(const std::string& full_path);
};
#endif //UTILITY_H
utility.cpp:
#include "utility.h"
using namespace utility;
...
md5sum_ptr calculate_md5(const std::string& full_path) {
md5sum_ptr md5(new md5sum);
std::ifstream in(full_path);
std::string content;
in >> content;
MD5((unsigned char*)content.data(), content.size(), md5->data());
return md5;
}
cdaemon.cpp
void CTCPConnection::handle_read_filename(ECommand command, EDataType datatype,
const boost::system::error_code& ec) {
...
case ECommand::GET_MD5:
_send_container<md5sum>(*(calculate_md5(filename)));
async_write(m_socket, m_writebuf,
boost::bind(&CTCPConnection::handle_write_response, shared_from_this(),
placeholders::error));
break;
...
}
}
Makefile:
CC=g++
override CFLAGS+=-c -std=c++11 -Wall -Wextra -Werror
override LFLAGS+=-lboost_log -lpthread -lboost_system -lboost_thread -lcrypto
server: servermain.o cdaemon.o
$(CC) ../build/datatype.o ../build/utility.o build/servermain.o build/cdaemon.o -o build/frtpdaemon $(LFLAGS)
servermain.o: main.cpp
$(CC) $(CFLAGS) main.cpp -o build/servermain.o
cdaemon.o: cdaemon.cpp
$(CC) $(CFLAGS) -DBOOST_LOG_DYN_LINK cdaemon.cpp -o build/cdaemon.o
When I try to build server, I get linker error:
build/cdaemon.o: In function `CTCPConnection::handle_read_filename(utility::ECommand, utility::EDataType, boost::system::error_code const&)':
cdaemon.cpp:(.text+0x127c): undefined reference to `utility::calculate_md5(std::string const&)'
I have already tried to google the solution, but all what I could find were suggestions to change the order of ../build/utility.o and build/cdaemon.o. That didn't help me.
You don't define the function you have declared in the header. A using directive is insufficient when defining functions in a namespace. You'll either need to open the namespace before defining your function or qualify the function with the namespace, e.g.:
utility::md5sum_ptr utility::calculate_md5(const std::string& full_path) {
...
}
I wrote some c++ files and after compiling with out make file it works fine . But when using make file it pop out some errors . My codes are :
include directory files :
application.h
#ifndef APPLICATION_H
#define APPLICATION_H
#include "employee.h"
#include "employee_data.h"
#include "employee.h"
...some defintions here...
#endif
employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include "employee_data.h"
#endif
employee_data.h
#ifndef EMPLOYEE_DATA_H
#define EMPLOYEE_DATA_H
typedef struct
{
int emp_id;
char *name,
*dept,
*book,
*time;
}employeedata;
...some codes here...
#endif
library.h
#ifndef LIBRARY_H
#define LIBRARY_H
#include "employee_data.h"
#include "application.h"
using namespace std;
class Library
{
public:
virtual int addE() = 0;
virtual int deleteE() = 0;
virtual int issue() = 0 ;
virtual int returnB() = 0;
virtual int employee() = 0;
};
class implementation : public Library
{
private:
employeedata *emp; /*structure object*/
public:
int addE();
int deleteE();
int issue();
int returnB();
int employee();
};
#endif
main.h
#ifndef MAIN_H
#define MAIN_H
#include "library.h"
class message
{
public:
void errormessage(int);
};
#endif
and my src directory conatins .cpp files . It includes
main.cpp
#include "main.h"
#include "library.h"
#include "employee_data.h"
#include "application.h"
int main()
{
message msg;
/* codes here..../*
}
library_function.cpp
#include "library.h"
#include "employee.h"
#include "main.h"
#include "application.h"
#include "employee_data.h"
int implementation :: addE()
{
}
etc..
error_function.cpp
#include "main.h"
void message :: errormessage(int errno)
{
}
employee_functions.cpp
#include "employee.h"
#include "main.h"
..some code...
display.cpp
#include "employee_data.h"
#include "application.h"
..some code..
thread.cpp
#include "employee.h"
#include "application.h"
...some code..
and my make file is :
CC=g++
FLAGS=-o
CFLAGES=-c -Wall
THREAD=-lpthread
INCLUDE=../include/
SRC=../src/
OBJ=../obj/
OUTPUT=../bin/
$(OUTPUT)vkp:$(OBJ)main.o $(OBJ)library_functions.o $(OBJ)employee_functions.o $(OBJ)display.o $(OBJ)error_function.o $(OBJ)thread.o
$(CC) $(FLAGS) vkp $(OBJ)main.o $(OBJ)library_functions.o $(OBJ)employee_functions.o $(OBJ)display.o $(OBJ)error_function.o $(OBJ)thread.o $(THREAD)
mv vkp $(OUTPUT)
$(OBJ)main.o:$(SRC)main.cpp $(INCLUDE)main.h $(INCLUDE)employee_data.h $(INCLUDE)application.h
$(CC) $(CFLAGS) $(SRC)main.cpp -I $(INCLUDE)
mv main.o $(OBJ)
$(OBJ)library_functions.o:$(SRC)library_functions.cpp $(INCLUDE)library.h $(INCLUDE)employee.h $(INCLUDE)main.h $(INCLUDE)application.h $(INCLUDE)employee_data.h
$(CC) $(CFLAGS) $(SRC)library_functions.cpp -I $(INCLUDE)
mv main.o $(OBJ)
$(OBJ)employee_functions.o:$(SRC)employee_functions.cpp $(INCLUDE)employee.h $(INCLUDE)main.h
$(CC) $(CFLAGS) $(SRC)employee_functions.cpp -I $(INCLUDE)
mv main.o $(OBJ)
$(OBJ)display.o:$(SRC)display.cpp $(INCLUDE)employee_data.h $(INCLUDE)application.h
$(CC) $(CFLAGS) $(SRC)display.cpp -I $(INCLUDE)
mv main.o $(OBJ)
$(OBJ)error_function.o :$(SRC)error_function.cpp $(INCLUDE)main.h
$(CC) $(CFLAGS) $(SRC)error_function.cpp -I $(INCLUDE)
mv main.o $(OBJ)
$(OBJ)thread.o:$(SRC)thread.cpp $(INCLUDE)employee.h $(INCLUDE)application.h
$(CC) $(CFLAGS) $(SRC)thread.cpp -I $(INCLUDE)
mv main.o $(OBJ)
After runing make i got eroor like :
g++ ../src/main.cpp -I ../include/
/tmp/cc09snhj.o: In function `main':
main.cpp:(.text+0x568): undefined reference to `message::errormessage(int)'
main.cpp:(.text+0x5fb): undefined reference to `message::errormessage(int)'
main.cpp:(.text+0x6c5): undefined reference to `message::errormessage(int)'
main.cpp:(.text+0x758): undefined reference to `message::errormessage(int)'
main.cpp:(.text+0x7f3): undefined reference to `message::errormessage(int)'
/tmp/cc09snhj.o: In function `implementation::implementation()':
main.cpp:(.text._ZN14implementationC2Ev[_ZN14implementationC5Ev]+0x1f): undefined reference to `vtable for implementation'
collect2: ld returned 1 exit status
make: *** [../obj/main.o] Error 1
what is wrong on my code ? any problem in make file ? I think the problem is linking the header files . Is this correct way to link header files ? Please help me to get my make file work .
I think you just misspelled CFLAGS in CFLAGES=-c -Wall
I'm guessing this is the case since
g++ ../src/main.cpp -I ../include/
does not have the -c option