I tried to compile the Telegram Android program locally, and I want to use LLVMPass in the NDK.
mypass.cpp
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
using namespace llvm;
namespace {
struct SkeletonPass : public FunctionPass {
static char ID;
SkeletonPass() : FunctionPass(ID) {}
virtual bool runOnFunction(Function &F) {
errs() << "I saw a function called " << F.getName() << "!\n";
return false;
}
};
}
char SkeletonPass::ID = 0;
static void registerSkeletonPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
PM.add(new SkeletonPass());
}
static RegisterStandardPasses
RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible,
registerSkeletonPass);
I used it successfully on simple HelloWorld.
HelloWorld.cpp
#include<iostream>
using namespace std;
void test_IRVMP(){
printf("HelloWorld!\n");
return;
}
int main(){
test_IRVMP();
return 0;
}
This is my output using Pass via clang:
$ clang++ -Xclang -load -Xclang ~/Download/llvm-8.0.0-build/lib/LLVMmypass.so ./HelloWorld.cpp -o HelloWorld -g ✔
I saw a function called __cxx_global_var_init!
I saw a function called _Z10test_IRVMPv!
I saw a function called main!
I saw a function called _GLOBAL__sub_I_HelloWorld.cpp!
But if I use the Pass in Android Studio, I get the following warning:
……
C/C++: /home/mzflrx/AndroidStudioProjects/Telegram/TMessagesProj/jni/tgnet/Datacenter.cpp:199:62: warning: '&&' within '||' [-Wlogical-op-parentheses]
C/C++: /home/mzflrx/AndroidStudioProjects/Telegram/TMessagesProj/jni/tgnet/Datacenter.cpp:199:62: note: place parentheses around the '&&' expression to silence this warning
C/C++: /home/mzflrx/AndroidStudioProjects/Telegram/TMessagesProj/jni/tgnet/Datacenter.cpp:257:62: warning: '&&' within '||' [-Wlogical-op-parentheses]
C/C++: /home/mzflrx/AndroidStudioProjects/Telegram/TMessagesProj/jni/tgnet/Datacenter.cpp:257:62: note: place parentheses around the '&&' expression to silence this warning
C/C++: /home/mzflrx/AndroidStudioProjects/Telegram/TMessagesProj/jni/tgnet/Datacenter.cpp:377:62: warning: '&&' within '||' [-Wlogical-op-parentheses]
C/C++: /home/mzflrx/AndroidStudioProjects/Telegram/TMessagesProj/jni/tgnet/Datacenter.cpp:377:62: note: place parentheses around the '&&' expression to silence this warning
C/C++: /home/mzflrx/AndroidStudioProjects/Telegram/TMessagesProj/jni/tgnet/Datacenter.cpp:445:62: warning: '&&' within '||' [-Wlogical-op-parentheses]
C/C++: /home/mzflrx/AndroidStudioProjects/Telegram/TMessagesProj/jni/tgnet/Datacenter.cpp:445:62: note: place parentheses around the '&&' expression to silence this warning
C/C++: clang-8: warning: argument unused during compilation: '-Xclang -load -Xclang /home/mzflrx/Download/llvm-8.0.0-build/lib/LLVMmypass.so' [-Wunused-command-line-argument]
C/C++: clang-8: warning: argument unused during compilation: '-Xclang -load -Xclang /home/mzflrx/Download/llvm-8.0.0-build/lib/LLVMmypass.so' [-Wunused-command-line-argument]
C/C++: clang-8: warning: argument unused during compilation: '-Xclang -load -Xclang /home/mzflrx/Download/llvm-8.0.0-build/lib/LLVMmypass.so' [-Wunused-command-line-argument]
C/C++: clang-8: warning: argument unused during compilation: '-Xclang -load -Xclang /home/mzflrx/Download/llvm-8.0.0-build/lib/LLVMmypass.so' [-Wunused-command-line-argument]
……
I don't know why clan doesn't use pass in Android studio, but if you compile a simple cpp file with clang alone, the function name is printed.
This is part of the CmakeLists .txt settings in Android Studio:
SET(clang_llvm_dir /home/mzflrx/下载/llvm-8.0.0-build)
set(CMAKE_C_COMPILER ${clang_llvm_dir}/bin/clang)
set(CMAKE_CXX_COMPILER ${clang_llvm_dir}/bin/clang++)
SET(LLVM_DIR ${clang_llvm_dir}/lib/cmake/llvm)
SET(CMAKE_PREFIX_PATH /${clang_llvm_dir}/lib/cmake)
SET(OBFUSCATOR_FLAGS "-Xclang -load -Xclang /home/mzflrx/Download/llvm-8.0.0-build/lib/LLVMmypass.so")
set(CMAKE_CXX_FLAGS "-std=c++14 -DANDROID -g ${OBFUSCATOR_FLAGS}")
set(CMAKE_C_FLAGS "-w -std=c11 -DANDROID -D_LARGEFILE_SOURCE=1 -g ${OBFUSCATOR_FLAGS}")
...
#tgnet
add_library(tgnet STATIC
tgnet/ApiScheme.cpp
tgnet/BuffersStorage.cpp
tgnet/ByteArray.cpp
tgnet/ByteStream.cpp
tgnet/Connection.cpp
tgnet/ConnectionSession.cpp
tgnet/ConnectionsManager.cpp
tgnet/ConnectionSocket.cpp
tgnet/Datacenter.cpp
tgnet/EventObject.cpp
tgnet/FileLog.cpp
tgnet/MTProtoScheme.cpp
tgnet/NativeByteBuffer.cpp
tgnet/Request.cpp
tgnet/Timer.cpp
tgnet/TLObject.cpp
tgnet/ProxyCheckInfo.cpp
tgnet/Handshake.cpp
tgnet/Config.cpp)
target_compile_options(tgnet PUBLIC
-Wall -frtti -finline-functions -ffast-math -Os ${OBFUSCATOR_FLAGS})
...
Related
I am trying to porting lttng on xilinx mpsoc with linux OS, I have write a demo as same as lttng "Record user application events", it runs on Ubuntu perfectly
g++ -c -I. hello-tp.c
g++ -c hello.c
g++ -o hello hello-tp.o hello.o -llttng-ust -ldl
but when I compile it on arm linux platform I got errors:
aarch64-xilinx-linux-g++ -mcpu=cortex-a72.cortex-a53 -march=armv8-a+crc -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/home/david/project/zcu102/images/linux/sdk/sysroots/cortexa72-cortexa53-xilinx-linux -O2 -pipe -g -feliminate-unused-debug-types -c -I. hello-tp.c
In file included from hello-tp.c:4:
hello-tp.h:16:27: error: expected constructor, destructor, or type conversion before ‘(’ token
16 | LTTNG_UST_TRACEPOINT_EVENT(hello_world, my_first_tracepoint, LTTNG_ARGS, LTTNG_FIELDS)
| ^
make: *** [Makefile:14: hello-tp.o] Error 1
here is the code
hello-tp.h:
#undef LTTNG_UST_TRACEPOINT_PROVIDER
#define LTTNG_UST_TRACEPOINT_PROVIDER hello_world
#undef LTTNG_UST_TRACEPOINT_INCLUDE
#define LTTNG_UST_TRACEPOINT_INCLUDE "./hello-tp.h"
#if !defined(_HELLO_TP_H) || defined(LTTNG_UST_TRACEPOINT_HEADER_MULTI_READ)
#define _HELLO_TP_H
#include <lttng/tracepoint.h>
#define LTTNG_ARGS LTTNG_UST_TP_ARGS(int, my_integer_arg, char *, my_string_arg)
#define LTTNG_FIELDS LTTNG_UST_TP_FIELDS(lttng_ust_field_string(my_string_field, my_string_arg) lttng_ust_field_integer(int, my_integer_field, my_integer_arg))
LTTNG_UST_TRACEPOINT_EVENT(hello_world, my_first_tracepoint, LTTNG_ARGS, LTTNG_FIELDS)
#endif /* _HELLO_TP_H */
#include <lttng/tracepoint-event.h>
hello-tp.c
#define LTTNG_UST_TRACEPOINT_CREATE_PROBES
#define LTTNG_UST_TRACEPOINT_DEFINE
#include "hello-tp.h"
hello.c
#include <stdio.h>
#include "hello-tp.h"
int main(int argc, char *argv[])
{
unsigned int i;
puts("Hello, World!\nPress Enter to continue...");
/*
* The following getchar() call only exists for the purpose of this
* demonstration, to pause the application in order for you to have
* time to list its tracepoints. You don't need it otherwise.
*/
getchar();
/*
* An lttng_ust_tracepoint() call.
*
* Arguments, as defined in `hello-tp.h`:
*
* 1. Tracepoint provider name (required)
* 2. Tracepoint name (required)
* 3. `my_integer_arg` (first user-defined argument)
* 4. `my_string_arg` (second user-defined argument)
*
* Notice the tracepoint provider and tracepoint names are
* C identifiers, NOT strings: they're in fact parts of variables
* that the macros in `hello-tp.h` create.
*/
lttng_ust_tracepoint(hello_world, my_first_tracepoint, 23,
"hi there!");
for (i = 0; i < argc; i++) {
lttng_ust_tracepoint(hello_world, my_first_tracepoint,
i, argv[i]);
}
puts("Quitting now!");
lttng_ust_tracepoint(hello_world, my_first_tracepoint,
i * i, "i^2");
return 0;
}
Makefile
APP = hello
# Add any other object files to this list below
APP_OBJS = hello-tp.o hello.o
all: build
build: $(APP)
$(APP): $(APP_OBJS)
$(CXX) -o $# $(APP_OBJS) $(LDFLAGS) -llttng -ldl
hello-tp.o : hello-tp.c hello-tp.h
$(CXX) $(CXXFLAGS) -c -I. $<
hello.o : hello.c
$(CXX) $(CXXFLAGS) -c $<
clean:
rm -f $(APP) *.o
Is there anyone met such issue? I guess the problem is caused by complier but I don't find any clue...
I just ran into this problem. Check your LTTNG version. The 2.13 release (current) uses LTTNG_UST_TRACEPOINT_PROVIDER. However, older releases uses TRACEPOINT_PROVIDER. The prefix LTTNG_UST has been added all over the place. See https://lttng.org/man/3/lttng-ust/v2.13/#doc-_compatibility_with_previous_apis
In my ubuntu 14.xx, I try to compile lsnes emulator to use the mario-ai script from aleju/mario-ai, and I've tried to google many solutions to solve the problem below:
Here is the output from the console:
make[3]: __all__.files' is up to date.
make[3]: Leaving directory/home/pengsuyu/software/lsnes/sourcecode/src/platform/macosx'
make[2]: Leaving directory /home/pengsuyu/software/lsnes/sourcecode/src/platform'
g++ -o lsnescat all_common.files all_platform.files-pthread -lboost_iostreams -lboost_filesystem -lboost_system -lz -lgcrypt -lgpg-error -L/usr/lib/x86_64-linux-gnu -lcurl -rdynamic -ldlcat core/all.ldflags lua/all.ldflags fonts/all.ldflags library/all.ldflags interface/all.ldflags video/all.ldflags emulation/all.ldflags cmdhelp/all.ldflags platform/all.ldflags
core/multitrack.o: In functionlua::state::get_string(int, std::string const&)':
/home/pengsuyu/software/lsnes/sourcecode/src/core/../../include/library/lua-base.hpp:317: undefined reference to lua_tolstring'
core/multitrack.o: In functionlua::state::get_bool(int, std::string const&)':
/home/pengsuyu/software/lsnes/sourcecode/src/core/../../include/library/lua-base.hpp:334: undefined reference to lua_toboolean'
core/multitrack.o: In functionlua::state::type(int)':
.
.
/home/pengsuyu/software/lsnes/sourcecode/src/library/lua.cpp:536: undefined reference to lua_close'
library/lua.o: In functionlua::state::pushcfunction(int ()(lua_State))':
/home/pengsuyu/software/lsnes/sourcecode/src/library/../../include/library/lua-base.hpp:504: undefined reference to lua_pushcclosure'
library/lua.o: In functionlua::state::getfield(int, char const*)':
/home/pengsuyu/software/lsnes/sourcecode/src/library/../../include/library/lua-base.hpp:506: undefined reference to lua_getfield'
library/lua.o: In functionlua::state::insert(int)':
/home/pengsuyu/software/lsnes/sourcecode/src/library/../../include/library/lua-base.hpp:509: undefined reference to lua_insert'
collect2: error: ld returned 1 exit status
make[1]: *** [lsnes] Error 1
make[1]: Leaving directory/home/pengsuyu/software/lsnes/sourcecode/src'
make: *** [src/all_files] Error 2
==================================
At the beginning, I think, the linker cannot find my lua library. So I tried to compile my main.cpp with test.lua.
main.cpp:
#include <stdio.h>
#include <iostream>
//extern "C"
//{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
//} // liblua5.1-c++.a
lua_State * L;
int main ()
{
L = lua_open();
luaL_openlibs(L);
luaL_dofile(L, "d:\\test.lua");
return 0;
}
test.lua:
print("Hello World");
I write a MakeFile to generate the executable file "main":
main:main.o
gcc -o $# $< -llua5.1 -lstdc++
main.o:
gcc -c main.cpp
clean:
-rm *.o
It works when I add the compile option "-llua5.1" and "-lstdc++" otherwise it throws the same error as I compiled lsnes
I am not familiar with gcc and Makefile. Please help me to solve this problem.
I've solved my question
The way to solve this problem is just to change one line in the file named "options.build".
1. find the line "LUA=lua" in options.build
2. change this line to "LUA=lua5.1"
because the needed library is 5.1, so if you want to build it successfully, you must use the "lua5.1" library however the default configuration is "lua" not "lua5.1"
I tried a sample opencv program to run on cuda. I have doownloaded opencv and compiled it and as last step run make install and it went successfull.
I tried the following program
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/gpu/gpu.hpp"
int main (int argc, char* argv[])
{
try
{
cv::Mat src_host = cv::imread("file.png", CV_LOAD_IMAGE_GRAYSCALE);
cv::gpu::GpuMat dst, src;
src.upload(src_host);
cv::gpu::threshold(src, dst, 128.0, 255.0, CV_THRESH_BINARY);
cv::Mat result_host = dst;
cv::imshow("Result", result_host);
cv::waitKey();
}
catch(const cv::Exception& ex)
{
std::cout << "Error: " << ex.what() << std::endl;
}
return 0;
}
Saved this as test.cu and compiled. The output is
# nvcc test.cu
/tmp/tmpxft_000018a4_00000000-13_test.o: In function `main':
tmpxft_000018a4_00000000-1_test.cudafe1.cpp:(.text+0x53): undefined reference to `cv::imread(std::string const&, int)'
tmpxft_000018a4_00000000-1_test.cudafe1.cpp:(.text+0xf7): undefined reference to `cv::gpu::GpuMat::upload(cv::Mat const&)'
tmpxft_000018a4_00000000-1_test.cudafe1.cpp:(.text+0xfc): undefined reference to `cv::gpu::Stream::Null()'
tmpxft_000018a4_00000000-1_test.cudafe1.cpp:(.text+0x130): undefined reference to `cv::gpu::threshold(cv::gpu::GpuMat const&, cv::gpu::GpuMat&, double, double, int, cv::gpu::Stream&)'
....................
.....................
.......................
Then I run
# nvcc test.cu -lopencv_gpu
/usr/bin/ld: /tmp/tmpxft_000018df_00000000-13_test.o: undefined reference to symbol '_ZTIN2cv9ExceptionE'
/usr/bin/ld: note: '_ZTIN2cv9ExceptionE' is defined in DSO /usr/local/lib/libopencv_core.so.2.4 so try adding it to the linker command line
/usr/local/lib/libopencv_core.so.2.4: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status
and
# nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2012 NVIDIA Corporation
Built on Thu_Apr__5_00:24:31_PDT_2012
Cuda compilation tools, release 4.2, V0.2.1221
UPDATE
# nvcc test.cu -lm -lopencv_core -lopencv_highgui
/tmp/tmpxft_00001c51_00000000-13_test.o: In function `main':
tmpxft_00001c51_00000000-1_test.cudafe1.cpp:(.text+0xfc): undefined reference to `cv::gpu::Stream::Null()'
tmpxft_00001c51_00000000-1_test.cudafe1.cpp:(.text+0x130): undefined reference to `cv::gpu::threshold(cv::gpu::GpuMat const&, cv::gpu::GpuMat&, double, double, int, cv::gpu::Stream&)'
collect2: error: ld returned 1 exit status
I gave
# nvcc test.cu -lm -lopencv_core -lopencv_highgui -lopencv_gpu
and its working fine.
Now I m getting following error when running
# ./a.out
OpenCV Error: Gpu API call (invalid configuration argument) in call, file /home/cuda/helloworld/Downloads/OpenCV/opencv-2.4.5/modules/gpu/include/opencv2/gpu/device/detail/transform_detail.hpp, line 361
Error: /home/cuda/helloworld/Downloads/OpenCV/opencv-2.4.5/modules/gpu/include/opencv2/gpu/device/detail/transform_detail.hpp:361: error: (-217) invalid configuration argument in function call
Add " -lm -lopencv_core -lopencv_highgui " options to your comile code
I think you got error because of library linking error.So try
As
nvcc test.cu `pkg-config --cflags --libs opencv` -lopencv_gpu
Or
nvcc test.cu -lm -lopencv_core -lopencv_highgui -lopencv_gpu.
I have one .cu file that contains my cuda kernel, and a wrapper function that calls the kernel. I have a bunch of .c files as well, one of which contains the main function. One of these .c files calls the wrapper function from the .cu to invoke the kernel.
I compile these files as follows:
LIBS=-lcuda -lcudart
LIBDIR=-L/usr/local/cuda/lib64
CFLAGS = -g -c -Wall -Iinclude -Ioflib
NVCCFLAGS =-g -c -Iinclude -Ioflib
CFLAGSEXE =-g -O2 -Wall -Iinclude -Ioflib
CC=gcc
NVCC=nvcc
objects := $(patsubst oflib/%.c,oflib/%.o,$(wildcard oflib/*.c))
table-hash-gpu.o: table-hash.cu table-hash.h
$(NVCC) $(NVCCFLAGS) table-hash.cu -o table-hash-gpu.o
main: main.c $(objects) table-hash-gpu.o
$(CC) $(CFLAGSEXE) $(objects) table-hash-gpu.o -o udatapath udatapath.c $(LIBS) $(LIBDIR)
So far everything is fine. table-hash-gpu.cu calls a function from one of the .c files. When linking for main, I get the error that the function is not present. Can someone please tell me what is going on?
nvcc compiles both device and host code using the host C++ compiler, which implies name mangling. If you need to call a function compiled with a C compiler in C++, you must tell the C++ compiler that it uses C calling conventions. I presume that the errors you are seeing are analogous to this:
$ cat cfunc.c
float adder(float a, float b, float c)
{
return a + 2.f*b + 3.f*c;
}
$ cat cumain.cu
#include <cstdio>
float adder(float, float, float);
int main(void)
{
float result = adder(1.f, 2.f, 3.f);
printf("%f\n", result);
return 0;
}
$ gcc -m32 -c cfunc.c
$ nvcc -o app cumain.cu cfunc.o
Undefined symbols:
"adder(float, float, float)", referenced from:
_main in tmpxft_0000b928_00000000-13_cumain.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Here we have code compiled with nvcc (so the host C++ compiler) trying to call a C function and getting a link error, because the C++ code expects a mangled name for adder in the supplied object file. If the main is changed like this:
$ cat cumain.cu
#include <cstdio>
extern "C" float adder(float, float, float);
int main(void)
{
float result = adder(1.f, 2.f, 3.f);
printf("%f\n", result);
return 0;
}
$ nvcc -o app cumain.cu cfunc.o
$ ./app
14.000000
It works. Using extern "C" to qualify the declaration of the function to the C++ compiler, it will not use C++ mangling and linkage rules when referencing adder and the resulting code links correctly.
I tried to link my executable program with 2 static libraries using g++. The 2 static libraries have the same function name. I'm expecting a "multiple definition" linking error from the linker, but I did not received. Can anyone help to explain why is this so?
staticLibA.h
#ifndef _STATIC_LIBA_HEADER
#define _STATIC_LIBA_HEADER
int hello(void);
#endif
staticLibA.cpp
#include "staticLibA.h"
int hello(void)
{
printf("\nI'm in staticLibA\n");
return 0;
}
output:
g++ -c -Wall -fPIC -m32 -o staticLibA.o staticLibA.cpp
ar -cvq ../libstaticLibA.a staticLibA.o
a - staticLibA.o
staticLibB.h
#ifndef _STATIC_LIBB_HEADER
#define _STATIC_LIBB_HEADER
int hello(void);
#endif
staticLibB.cpp
#include "staticLibB.h"
int hello(void)
{
printf("\nI'm in staticLibB\n");
return 0;
}
output:
g++ -c -Wall -fPIC -m32 -o staticLibB.o staticLibB.cpp
ar -cvq ../libstaticLibB.a staticLibB.o
a - staticLibB.o
main.cpp
extern int hello(void);
int main(void)
{
hello();
return 0;
}
output:
g++ -c -o main.o main.cpp
g++ -o multipleLibsTest main.o -L. -lstaticLibA -lstaticLibB -lstaticLibC -ldl -lpthread -lrt
The linker does not look at staticLibB, because by the time staticLibA is linked, there are no unfulfilled dependencies.
That's an easy one. An object is only pulled out of a library if the symbol referenced hasn't already been defined. Only one of the hellos are pulled (from A). You'd get errors if you linked with the .o files.
When the linker tries to link main.o into multipleLibsTest and sees that hello() is unresolved, it starts searching the libraries in the order given on the command line. It will find the definition of hello() in staticLibA and will terminate the search.
It will not look in staticLibB or staticLibC at all.
If staticLibB.o contained another symbol not in staticLibA and that was pulled into the final executable, you then get a multiple definition of hello error, as individual .o files are pulled out of the library and two of them would have hello(). Reversing the order of staticLibA and staticLibB on the link command line would then make that error go away.