How to use llvm target initialize function - build

My Host System
: Default target: x86_64-unknown-linux-gnu
: Host CPU: skylake
LLVM/Clang built with LLVM_TARGETS_TO_BUILD=all option.
How to Use another target's Initialize Function in My code?
I modifying klee (symbolic execution tool) to run cross-platform Target's IR.
#include "llvm/Support/TargetSelect.h"
int main () {
...
// llvm::InitializeAllTargets(); -> Error
llvm::InitializeNativeTargets(); -> Success
...
}
In this case, error
${LLVM}/build/include/llvm/Config/Targets.def:28: undefined reference to `LLVMInitializeARMTargetInfo'
${LLVM}/build/include/llvm/Config/Targets.def:29: undefined reference to `LLVMInitializeBPFTargetInfo'
...

The LLVMInitializexxxTargetInfo() functions are used by InitializeAllTargets(), and the error message implys that you didn't link the required LLVM libraries.
InitializeNativeTargets() succeeded, because you maybe did't include your native arch in -DLLVM_TARGETS_TO_BUILD.
You can add the following lines in your CMakeLists.txt to link LLVM Targets libraries:
set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
)
# Build your .cpp with llvm macro to use LLVM_LINK_COMPONENTS
add_llvm_xxx_macro(YourOutputFile
...
)

Related

Mixed languages link error with meson build system (Fortran/C++)

I am encountering issues when trying to compile fortran code using meson build system on an HPC cluster.
On the cluster, I am using Intel compiler suite. The meson compile command aborts at the linking step with:
ld: /usr/bin/../lib64/crt1.o: in function `_start':
(.text+0x20): undefined reference to `main'
ninja: build stopped: subcommand failed.
The interesting thing is that the link command issued by meson is something like this:
icpc -o main main.p/somefile.o ..., so it is using Intel's C++ compiler to link my fortran code. I tried to use the exact same command line, replacing icpc with ifort and adding -lstdc++. That actually worked.
So, I wonder, is there a way to force Meson to link my code with ifort, instead of icpc? Or, should I do something else?
I am afrad I cannot share the code at this moment. But, I'm open to showing bits and pieces of the meson.build file(s), if needed.
Details
The codebase consists of fortran source and a CMake C++ subproject; Essentially, the C++ subproject is a wrapper for OpenCV image plotting functions. This is why I needed to add -lstdc++ to my successful manual link command above.
Meson version: 0.55.3
Intel Fortran compiler: ifort (IFORT) 19.1.3.304 20200925
Intel C++ compiler: icpc (ICC) 19.1.3.304 20200925
The code is MPI parallelised.
The same code compiles well with GNU compilers v10 on a normal workstation.
Meson is not going to do any hand-holding when it comes to mixing languages. Here is what I found out works for Intel compilers:
fc=meson.get_compiler('fortran')
# cxx=meson.get_compiler('cpp')
...
if (fc.get_id() == 'intel')
#if (cxx.get_id() == 'intel')
...
add_global_link_arguments('-cxxlib',language : 'fortran')
add_global_link_arguments('-nofor_main', language : 'cpp')
endif
...
executable('myprog','myprog.f90', ..., link_language : 'fortran')
#executable('myprog','myprog.f90',...)

explicitly link intel icpc openmp

I have the intel compiler install at the following $HOME/tpl/intel. When I compile a simple hello_omp.cpp with openMP enabled
#include <omp.h>
#include <iostream>
int main ()
{
#pragma omp parallel
{
std::cout << "Hello World" << std::endl;
}
return 0;
}
I compile with ~/tpl/intel/bin/icpc -O3 -qopenmp hello_omp.cpp but when I run I get the following error:
./a.out: error while loading shared libraries: libiomp5.so: cannot open shared object file: No such file or directory.
I would like to explicitly link the intel compiler and the appropriate library during the make process without using the LD_LIBRARY_PATH?
You have 2 simple solutions for your problem:
Linking statically with the Intel run time libraries:
~/tpl/intel/bin/icpc -O3 -qopenmp -static_intel hello_omp.cpp
Pros: you don't have to care where the Intel run time environment is installed on the machine where you run the binary, or even having it installed altogether;
Cons: your binary becomes bigger and won't allow to select a different (more recent ideally) run time environment even when it is available.
Adding the search path for dynamic library into the binary using the linker option -rpath:
~/tpl/intel/bin/icpc -O3 -qopenmp -Wl,-rpath=$HOME/tpl/intel/lib/intel64 hello_omp.cpp
Notice the use of -Wl, to transmit the option to the linker.
I guess that is more like what you were after than the first solution I proposed so I let you devise what the pros and cons are for you in comparison.
Intel Compiler ships compilervars.sh script in the bin directory which when sourced will set the appropriate env variables like LD_LIBRARY_PATH, LIBRARY_PATH and PATH with the right directories which host OpenMP runtime library and other compiler specific libraries like libsvml (short vector math library) or libimf (more optimized version of libm).

How to use standard library with Clang and LibTooling

I want to use Clang and LibTooling to create some C++ source analysis and transformation tools. I've built Clang and LibTooling following this tutorial, and I've been able to run and create some analysis tools and compile C++ programs using the Clang binary I built. However, if I include headers from the standard library (in either source files or my tools), I run into issues when compiling or running the source files/tools. For instance, if I run clang-check on the following C++ source file:
#include <iostream>
int main() {
std::cout << "Hello";
return 0;
}
I get "fatal error: 'iostream' file not found". (Note: I can compile C++ programs, e.g. ones with user-defined classes, just not C++ programs using the standard library.) In an attempt to resolve the issue, I built libc++ (following this guide, building it in the llvm/project directory where I built LLVM and Clang), but I'm still having trouble getting Clang and the tools to use libc++. Now, if I try to compile a test file using:
export CPLUS_INCLUDE_PATH="~/clang-llvm/llvm/projects/libcxx/include"
export LD_LIBRARY_PATH="~/clang-llvm/llvm/projects/libcxx/lib"
~/clang-llvm/llvm/build/bin/clang++ ~/Documents/main.cpp
Then I get "fatal error: 'unistd.h' file not found". So my question is this: how do I properly point Clang and my tools to use libc++?
I am running OS X Yosemite 10.10 and using Clang 3.6.0.
Clang comes with some custom includes. So usually you have clang in
/usr/bin/clang++
and the includes in
/usr/lib/clang/3.6.1/include
but clang looks for them as a relative path:
../lib/clang/3.6.1/include
so make sure this relative path is accessible from either the clang++ binary, or your libtooling application.
Include your tool into this:
#include "clang/Tooling/CommonOptionsParser.h" // For reading compiler switches from the command line
#include "clang/Tooling/Tooling.h"
static cl::OptionCategory MyToolCategory("SearchGlobalSymbols");
static cl::extrahelp MoreHelp("\nMore help text..."); // Text that will be appended to the help text. You can leave out this line.
/* Your code (definition of your custom RecursiveASTVisitor and ASTConsumer) */
/* Define class MyASTFrontendAction here, derived from ASTFrontendAction */
int main(int argc, const char **argv)
{
/* Your code */
CommonOptionsParser op(argc, argv, MyToolCategory); // Parse the command-line arguments
ClangTool Tool(op.getCompilations(), op.getSourcePathList()); // Create a new Clang Tool instance (a LibTooling environment)
return Tool.run(newFrontendActionFactory<MyASTFrontendAction>().get()); // Run custom Frontendaction
}
The CommonOptionsParser allows you to read commands from the command line that are passed to the compiler.
For example, you can now call your tool like this:
your-tool yoursourcefile.c -- -nostdinc -I"path/to/your/standardlibrary"
Everything after the double dash will be passed to the compiler. Possible flags are described here:
http://clang.llvm.org/docs/CommandGuide/clang.html
-nostdinc tells the Preprocessor not to look for standard include paths. You can specify you own paths instead after -I.
Hope it helped someone :) Ask me if I wasn't specific enough.
Did you move/rename any of the parent directories after building/installing? The compiler should have been configured to know where to look for its standard libraries without having to specify the environment variable paths.
Use homebrew and install llvm using the command
brew install llvm
Your problem should be solved.

Link error while compiling llvm with a new optimization pass

I have written a new LLVM optimization pass. I have added this pass by making a new directory at following location:
llvm/lib/Transform/AddSub
I am following the steps as mentioned in the llvm documentation:
http://llvm.org/docs/WritingAnLLVMPass.html
But while compiling I am getting linking errors. May be my build and makefile settings are not correct.
relocation R_X86_64_PC32 against undefined symbol `_ZTVN12_GLOBAL__N_18AddSubE' can not be used when making a shared object; recompile with -fPIC
If I have written an independent llvm pass and added it in a new directory inside llvm at:
llvm/lib/Transform/
what Makefile or build changes do I need to make while writing an independent pass?
I ran into this same error when I was trying to follow the Writing An LLVM Pass guide. For me, the fix was adding a line like this:
char MyPassName::ID = 0;
(I had skipped over that step in the directions.)

Qt Plugin with OpenMP Support on MinGW: Undefined reference?

I am developing a "Qt Plugin" which uses OpenMP (OpenMP support can be enabled/disabled using CMake parameter). I use MinGW and CMake as development environment.
This is how I enable/disable OpenMP in the code:
#ifdef OPENMP_ENABLE
#pragma omp parallel for
#endif for(int i=0; i<volumeData->getZSize(); i++){ .
I have enabled OpenMP in CMake file as follows:
OPTION (OPENMP_SUPPORT "Build with OpenMP parallaization enabled")
IF (OPENMP_SUPPORT)
FIND_PACKAGE( OpenMP )
SET(CMAKE_CXX_FLAGS "${OpenMP_CXX_FLAGS}")
IF ( OpenMP_CXX_FLAGS )
MESSAGE("------- Adding compiler parameter for OpenMP")
ADD_DEFINITIONS(-DOPENMP_ENABLE)
ENDIF()
ENDIF()
and to build Qt plugin, I have configured CMake as follows:
ADD_DEFINITIONS(-DQT_PLUGIN)
ADD_DEFINITIONS(-DQT_SHARED)
This configuration compiles fine with Linux.
In Windows it compiles fine WITHOUT OpenMP support.
But when build with OpenMP support, it gives the error
c:/mingw4/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/bin/ld.exe:
warning:auto-importing has been
activated without --enable-auto-import
specified on the command line. This
should work unless it involves
constant data structures referencing
symbol from auto-imported DLLs.
CMakeFiles\RinzoDLPluginIPThreshold.dir\ui\dialogthresholdconfig.cpp.obj:C:/svnosaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/imageprocplugins/thresholdPlgin/ui/dialogthresholdconfig.cpp:221:
undefined reference to
GOMP_parallel_stat'
CMakeFiles\RinzoDLPluginIPThreshold.dir\ui\dialogthresholdconfig.cpp.obj:C:/svnosaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/imageprocplugins/thresholdPlgin/ui/dialogthresholdconfig.cpp:221:
undefined reference to
GOMP_parallel_end
CMakeFiles\RinzoDLPluginIPThreshold.dir\ui\dialogthresholdconfig.cpp.obj:
In function
ZN21DialogThresholdConfig9slotApplyEv.omp_fn.0':
C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/imageprocplugins/threholdPlugin/ui/dialogthresholdconfig.cpp:223:
undefined reference to
omp_get_nu_threads'
C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/imageprocplugins/threholdPlugin/ui/dialogthresholdconfig.cpp:223:
undefined reference to
omp_get_thead_num'
C:/svn/osaka3d/trunk/osaka3d/rinzo-platform/src/dlplugins/imageprocplugins/threholdPlugin/ui/dialogthresholdconfig.cpp:233:
undefined reference to
omp_get_thead_num' collect2: ld
returned 1 exit status make[2]: *
[dist/plugins/libRinzoDLPluginIPThreshold.dll]
Error 1
Here is my complete CMake file:
http://www.keepandshare.com/doc/view.php?id=2552392&da=y
Any tip?
OpenMP requires a runtime library (called libgomp in case of gcc), which must be linked into the created executable. It is therefore not sufficient to add the OpenMP flags to the compilation flags, they must also be added to the link flags:
set_target_properties(<target_name> LINK_FLAGS "${OpenMP_CXX_FLAGS}")
Of course, you need to replace <target_name> with the actual name of your target.
And by the way, and extra definition like OPENMP_ENABLE is superfluous. If OpenMP is enabled, the macro _OPENMP is implicitly defined to contain the supported version of OpenMP (more precisely, the release date of the supported standard). You can use this macro to test for OpenMP support in the source code:
#if defined(_OPENMP)
// use openmp
#endif