Runtime library for clang on windows - c++

I have built clang with VS9 following manual.
I have compiled code:
void foo()
{
try
{
throw 1;
}
catch(int)
{}
}
to object file. It has external dependencies:
___cxa_allocate_exception
__ZTIi
___cxa_throw
I guess that these comes from runtime library. But which one should I use? Should I build libc++? Is it stable?
PS: I don't want to have any dependency on cygwin/mingw
PPS: but seems like mingw is what I need... is it only viable option?

You need C++ ABI library. libc++ won't help you here. You need either libc++abi or libsupc++ or something similar.

Related

llvm JIT add library to module

I am working on a JIT that uses LLVM. The language has a small run-time written in C++ which I compile down to LLVM IR using clang
clang++ runtime.cu --cuda-gpu-arch=sm_50 -c -emit-llvm
and then load the *.bc files, generate additional IR, and execute on the fly. The reason for the CUDA stuff is that I want to add some GPU acceleration to the runtime. However, this introduces CUDA specific external functions which gives errors such as:
LLVM ERROR: Program used external function 'cudaSetupArgument' which could not be resolved!
As discussed here, this is usually solved by including the appropriate libraries when compiling the program:
g++ main.c cmal.o -L/usr/local/cuda/lib64 -lcudart
However, I am not sure how to include libraries in JITed modules using LLVM. I found this question which suggested that is used to be possible to add libraries to modules in the JIT like this:
[your module]->addLibrary("m");
Unfortunately, this has been deprecated. Can anyone tell me the best way to do this now? Let me know if I need to provide more information!
Furthermore, I am not really sure if this is the best way to be incorporating GPU offloading into my JIT, so if anyone can point me to a better method then please do :)
Thanks!
EDIT: I am using LLVM 5.0 and the JIT engine I am using is from llvm/ExecutionEngine/ExecutionEngine.h, more specifically I create it like this:
EngineBuilder EB(std::move(module));
ExecutionEngine *EE = EB.create(targetMachine);
You need to teach your JIT engine about other symbols explicitly.
If they are in a dynamic library (dylib, so, dll) then you can just call
sys::DynamicLibrary::LoadLibraryPermanently("path_to_some.dylib")
with a path to the dynamic library.
If the symbols are in an object file or an archive, then it requires a bit more work: you would need to load them into memory and add to the ExecutionEngine using its APIs.
Here is an example for an object file:
std::string objectFileName("some_object_file.o");
ErrorOr<std::unique_ptr<MemoryBuffer>> buffer =
MemoryBuffer::getFile(objectFileName.c_str());
if (!buffer) {
// handle error
}
Expected<std::unique_ptr<ObjectFile>> objectOrError =
ObjectFile::createObjectFile(buffer.get()->getMemBufferRef());
if (!objectOrError) {
// handle error
}
std::unique_ptr<ObjectFile> objectFile(std::move(objectOrError.get()));
auto owningObject = OwningBinary<ObjectFile>(std::move(objectFile),
std::move(buffer.get()));
executionEngine.addObjectFile(std::move(owningObject));
For archives replace template types ObjectFile with Archive, and call
executionEngine.addArchive(std::move(owningArchive));
at the end.

BOOST_MESSAGE undefined

I have installed boost_1_54 on windows by checkout from svn and then
bootstrap
.\b2
QuantLib library dependent on boost compiles well all but one project: test-suite which uses BOOST_MESSAGE. this is undefined. I can see that there is no BOOST_MESSAGE in my version of boost.
Therefore is this QuantLib incompatibility or have I missed something?
On my linux boost version the same thing applies to BOOST_MESSAGE - it is undefined
I have seen this but I am not sure how to interpret this.
I'm afraid you gave us more credit than we deserved :)
We haven't compiled QuantLib against Boost svn yet. The latest I've tried is Boost 1.53 (the latest released version) in which BOOST_MESSAGE was still available.
Thanks for the heads-up, though. I'll patch the library so that it's ready for next version. As mentioned in the comments, it should be as simple as adding
#if BOOST_VERSION > 105300
#define BOOST_MESSAGE(msg) BOOST_TEST_MESSAGE(msg)
#endif
to test-suite/utilities.hpp.
on linux I had to add
libboost_unit_test_framework.so
to the Linker->Libraries and
#include <boost/test/unit_test.hpp>
#define BOOST_MESSAGE( M ) BOOST_TEST_MESSAGE( M )
is already present in test/test_tools.hpp.
on windows I have different #defines and this is not present, so I added it to the
unit_test_log.hpp
where BOOST_TEST_MESSAGE is defined (in boost files to avoid same issue again in the case of other applications using BOOST_MESSAGE).
BOOST_MESSAGE issue resolved but still can't disambiguate
const void* = boost::test_tools::check_is_close
and
const void* = boost::test_tools::check_is_small
because these are templates. so the solution is to remove it (test-suite compiles well) or use appropriate pointers to function templates
on Windows, after romoval or function
_use_check
in utilities.hpp
changed to not have pointers to TEMPLATE functions as default, so changed to:
void _use_check(
const void*,
const void*) const {}
there were still errors while building test-suite project. unresolved externals: fdmhestonfwdop, fdmblackscholesfwdop, fdmsquarerootfwdop. obviously this classes (headers+source) I had to add to Quantlib project, build library QuantLib-vc110-mt-gd.lib again and rebuild test-suite project then.
after pleasure with VS linker error "lnk1210 exceeded internal ilk size limit link with incremental no" (it really likes RAM, but on windows I have this resource quite limited), it is OK. compiled. : p

How to compile a C++ program in LLVM using clang++?

There is a tutorial - http://llvm.org/docs/GettingStartedVS.html Example done in pure C. I can compile and link it. Without problem, really. But I need C++, not pure C. And here the difficulties begin.
For clang++ I use string like
"C:\..> clang++ -c hello.cpp -emit-llvm -o hello.bc"
then:
"C:\..> llc -filetype=obj hello.bc"
and
"C:\..> link hello.obj -defaultlib:libcmt -out:hello.exe"
there I get 14 errors LNK2001: unresolved external symbol
So, I need some tips. What I do wrong?
//-----------------
hello.cpp:
#include < iostream >
int main()
{
std::cout << "TEST\n" << std::endl;
return 0;
}
//-----------------
OS: Windows7.
UPD: Main question: how from .bc get .exe? (LLVM, Windows7)
You can use my GCC and Clang packages:
Download and extract them to the same directory. Clang will use GCC 4.6.3's libstdc++ and MinGW-w64's CRT. Call it like you would gcc.
Clang/LLVM cannot currently work with MSVC's C++ library, due to ABI issues. GCC's libstdc++ works quite well, though it has holes in surprising places (like std::to_string, <regex>, and <thread>).
Clang's Windows support is OK, but far from complete. You cannot for example dllexport whole C++ classes, unfortunately. And Win64 code generation is also not good enough to have a working C++ install (even in combination with GCC, like for 32-bit).

calling C++ function from fortran not C

is it possible to call a C++ function from FORTRAN such as
#include <iostream.h>
extern "C"
{
void single_cell(void)
{
cout<<"Hi from C++";
}
}
So when I am using C it is working fine but with the C++ function it gives errors like
Undefined error to cout etc
Both g++ and gfortran, used as linkers, bring in extra libraries. That is why the Fortran/C++ combination is trickier than the Fortran/C combination ... just using the correct compiler as the linker won't work, you need to add a libary. Already suggested is to link with gfortran and specify the C++ runtime libraries. You can also link with g++ and specify the Fortran runtime libraries. See Linking fortran and c++ binaries using gcc for the details of both approaches.
Assuming you could have your Fortran code call into a C function, the problem is not the code but rather how you are linking. When you're linking C++ objects you need to also pull in the C++ runtime. If using GCC, link with the g++ command and it will pull in the parts you need.

How to use the boost library (including shared_ptr) with the Android NDK and STLport

This is more of an answer than a question, because I've figured it out, at least as far as cleanly compiling the library. The main issue for me was to get shared_ptr working.
Ingredients:
Boost v. 1.45.0
The version of STLport at http://www.anddev.org/viewtopic.php?p=29939.
Version r4b of the NDK.
Directions:
In your Android.mk file add:
LOCAL_CFLAGS += -DBOOST_EXCEPTION_DISABLE -D_STLP_NO_EXCEPTIONS -DOS_ANDROID -D_STLP_USE_SIMPLE_NODE_ALLOC
Remove the call to __stl_throw_length_error at line 613 of stlport/stl/_string.h. You can use _STLP_NO_EXCEPTIONS if you like.
Edit boost/boost/smart_ptr/shared_ptr.hpp after line 261 to get rid of the call to boost::throw_exception in the shared_ptr constructor. I used #ifndef BOOST_EXCEPTION_DISABLE around the entire body of the method. (But see the answer below.)
Next you need to supply some missing pieces. Create a header file with the following:
#ifdef OS_ANDROID
#include <exception>
namespace std
{
struct bad_alloc : public exception { bad_alloc operator()(){}};
}
#endif
and a source file with a stripped-down exception class to support bad_alloc:
#ifdef OS_ANDROID
#include <exception>
namespace std
{
exception::exception() {}
exception::~exception() {}
const char* exception::what() const {}
}
#endif
Include the header wherever you're including boost/shared_ptr.hpp. Compile the source and add it to your library.
It turned out that this approach does not entirely work when compiling a debuggable library. The release library is compiled with -O2 which optimizes out some infelicities, but the debug library is done with -O0 which reveals some additional problems. Furthermore, I wasn't too happy about having to edit the boost files. So with some additional study, I've come up with the following solution.
First, don't edit any of the boost files. Instead add the following to the header within the std namespace:
struct bad_cast : public exception {bad_cast operator()(){}};
Next add the following to the source file:
namespace boost
{
void throw_exception(std::exception const&) {}
}
This now compiles and links into the application even with android:debuggable="true" in AndroidManifest.xml. It doesn't run in the emulator, but then it wasn't doing that before I included this library either.
Notably, NDK r5 comes with STLport, and the GNU STL, and so the hacks here are no longer going to be necessary now that there is a) STL support b) exception support in the NDK C++ compiler.
Another workaround for shared_ptr in particular is to use boost::intrusive_ptr instead. This is not always possible, but worked for my situation.
The current version of Android NDK (r9) now supports exceptions.
The capabilities of the various runtimes vary. See this table:
C++ C++ Standard
Exceptions RTTI Library
system no no no
gabi++ yes yes no
stlport yes yes yes
gnustl yes yes yes
stlport can get used in non-GPL binarys. It's still flagged as experimantal, but you can use it with clang and gcc.
See http://developer.android.com/tools/sdk/ndk/