www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Using the llvm D-bindings

reply Manuel =?ISO-8859-1?B?S/ZuaWc=?= <manuelk89 gmx.net> writes:
Hi,

did anyone have success using the llvm-2.7 D-bindings from the bindings
project http://www.dsource.org/projects/bindings on x86_64 linux? I
tried so far with ldc, but the compiler chokes about a mere 3570 lines
of unresolved symbols when linking with ldc, compiling works fine.

Short version:
==============

I think the question boils down to "How do I create a D library and
link it into a c++ program on x86_64 linux using ldc (or gdc or
<any_other_D_compiler>)".

Long version:
=============
Here's a snip of the linker error messages I get from ldc:

// -- file main.d
import llvm.c.Core;

void main()
{
    auto context = LLVMGetGlobalContext();
}
// --

$ ldc -I=/path/to/llvm-2.7 \
-L=/usr/local/lib/libLLVM{Core,Support,System}.a main.d
/usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMContextCreate':
Core.cpp:(.text+0x57): undefined reference to `operator new(unsigned
long)'
/usr/local/lib/libLLVMCore.a(Core.o): In function
`LLVMModuleCreateWithName':
Core.cpp:(.text+0x13a): undefined reference to `operator new(unsigned
long)'
/usr/local/lib/libLLVMCore.a(Core.o): In function
`LLVMModuleCreateWithNameInContext':
Core.cpp:(.text+0x195): undefined reference to `operator new(unsigned
long)'
/usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMSetDataLayout':
Core.cpp:(.text+0x240): undefined reference to `std::basic_string<char,
std::char_traits<char>, std::allocator<char> >::basic_string(char
const*, unsigned long, std::allocator<char> const&)'
Core.cpp:(.text+0x24f): undefined reference to `std::basic_string<char,
std::char_traits<char>, std::allocator<char>
::assign(std::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&)'
Core.cpp:(.text+0x25e): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char>
::_Rep::_S_empty_rep_storage'
Core.cpp:(.text+0x294): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char>
::_Rep::_M_destroy(std::allocator<char> const&)'
 [...]
After scanning over the error messages, I think it's only operator, delete and std::* symbols that are missing. I also get the same error messages when I try to compile an equivalent C program that uses the llvm-c/* headers with gcc, but it works with g++, so I'm quite sure the problem is the missing c++ runtime, which is nonexistent in ldc. I think there are only two ways to solve this: (1) link the c++ runtime to ldc (I have no clue how to do that or if it's possible) (2) Write a D library using the llvm D-bindings, define a semi-main function as extern(C), and write a c++ wrapper program that links to the D library and does nothing more than calling the semi-main function. The llvm symbols and c++ runtime will then be linked in using g++. Option (2) seems easy, but ldc does not seem to have a linker swith to build libraries, and doing ar -cq myprog.a myprog.o to generate a library from the object file doesn't work because there are still undefined symbols to the main function or the module ctors in there, even when myprog.d doesn't define a main function. I could try to hack those missing functions back in by defining them in the C program, but there must be some simpler way to generate libraries, or am I at a loosing front here? I also consider using other compilers than ldc as an option, but afaik the only other usable compiler might be gdc (is that stable by now?).
Oct 06 2010
parent reply "Denis Koroskin" <2korden gmail.com> writes:
On Wed, 06 Oct 2010 16:20:41 +0400, Manuel K=C3=B6nig <manuelk89 gmx.net=
 wrote:
 Hi,

 did anyone have success using the llvm-2.7 D-bindings from the binding=
s
 project http://www.dsource.org/projects/bindings on x86_64 linux? I
 tried so far with ldc, but the compiler chokes about a mere 3570 lines=
 of unresolved symbols when linking with ldc, compiling works fine.

 Short version:
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

 I think the question boils down to "How do I create a D library and
 link it into a c++ program on x86_64 linux using ldc (or gdc or
 <any_other_D_compiler>)".

 Long version:
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 Here's a snip of the linker error messages I get from ldc:

 // -- file main.d
 import llvm.c.Core;

 void main()
 {
     auto context =3D LLVMGetGlobalContext();
 }
 // --

 $ ldc -I=3D/path/to/llvm-2.7 \
 -L=3D/usr/local/lib/libLLVM{Core,Support,System}.a main.d
 /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMContextCreate':=
 Core.cpp:(.text+0x57): undefined reference to `operator new(unsigned
 long)'
 /usr/local/lib/libLLVMCore.a(Core.o): In function
 `LLVMModuleCreateWithName':
 Core.cpp:(.text+0x13a): undefined reference to `operator new(unsigned
 long)'
 /usr/local/lib/libLLVMCore.a(Core.o): In function
 `LLVMModuleCreateWithNameInContext':
 Core.cpp:(.text+0x195): undefined reference to `operator new(unsigned
 long)'
 /usr/local/lib/libLLVMCore.a(Core.o): In function `LLVMSetDataLayout':=
 Core.cpp:(.text+0x240): undefined reference to `std::basic_string<char=
,
 std::char_traits<char>, std::allocator<char> >::basic_string(char
 const*, unsigned long, std::allocator<char> const&)'
 Core.cpp:(.text+0x24f): undefined reference to `std::basic_string<char=
,
 std::char_traits<char>, std::allocator<char>
 ::assign(std::basic_string<char, std::char_traits<char>,
 std::allocator<char> > const&)'
Core.cpp:(.text+0x25e): undefined reference to `std::basic_string<char=
,
 std::char_traits<char>, std::allocator<char>
 ::_Rep::_S_empty_rep_storage'
Core.cpp:(.text+0x294): undefined reference to `std::basic_string<char=
,
 std::char_traits<char>, std::allocator<char>
 ::_Rep::_M_destroy(std::allocator<char> const&)'
 [...]
After scanning over the error messages, I think it's only operator, delete and std::* symbols that are missing. I also get the same error messages when I try to compile an equivalent C program that uses the llvm-c/* headers with gcc, but it works with g++, so I'm quite sure th=
e
 problem is the missing c++ runtime, which is nonexistent in ldc.

 I think there are only two ways to solve this:

 (1) link the c++ runtime to ldc (I have no clue how to do that or if
     it's possible)
 (2) Write a D library using the llvm D-bindings, define a semi-main
     function as extern(C), and write a c++ wrapper program that links
     to the D library and does nothing more than calling the semi-main
     function. The llvm symbols and c++ runtime will then be linked in
     using g++.

 Option (2) seems easy, but ldc does not seem to have a linker swith to=
 build libraries, and doing


 ar -cq myprog.a myprog.o

 to generate a library from the object file doesn't work because there
 are still undefined symbols to the main function or the module ctors
 in there, even when myprog.d doesn't define a main function. I could
 try to hack those missing functions back in by defining them in the C
 program, but there must be some simpler way to generate libraries,
 or am I at a loosing front here?

 I also consider using other compilers than ldc as an option, but afaik=
 the only other usable compiler might be gdc (is that stable by now?).
You should probably ask LDC guys (irc://irc.freenode.net/ldc)
Oct 06 2010
parent reply Manuel =?ISO-8859-1?B?S/ZuaWc=?= <manuelk89 gmx.net> writes:
Am Wed, 06 Oct 2010 16:27:11 +0400
schrieb "Denis Koroskin" <2korden gmail.com>:

 On Wed, 06 Oct 2010 16:20:41 +0400, Manuel K=F6nig <manuelk89 gmx.net>
 wrote:
=20
 Hi,

 did anyone have success using the llvm-2.7 D-bindings from the
 bindings project http://www.dsource.org/projects/bindings on x86_64
 linux? I tried so far with ldc, but the compiler chokes about a
 mere 3570 lines of unresolved symbols when linking with ldc,
 compiling works fine.

 Short version:
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

 I think the question boils down to "How do I create a D library and
 link it into a c++ program on x86_64 linux using ldc (or gdc or
 <any_other_D_compiler>)".

 Long version:
 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 Here's a snip of the linker error messages I get from ldc:

 // -- file main.d
 import llvm.c.Core;

 void main()
 {
     auto context =3D LLVMGetGlobalContext();
 }
 // --

 $ ldc -I=3D/path/to/llvm-2.7 \
 -L=3D/usr/local/lib/libLLVM{Core,Support,System}.a main.d
 /usr/local/lib/libLLVMCore.a(Core.o): In function
 `LLVMContextCreate': Core.cpp:(.text+0x57): undefined reference to
 `operator new(unsigned long)'
 /usr/local/lib/libLLVMCore.a(Core.o): In function
 `LLVMModuleCreateWithName':
 Core.cpp:(.text+0x13a): undefined reference to `operator
 new(unsigned long)'
 /usr/local/lib/libLLVMCore.a(Core.o): In function
 `LLVMModuleCreateWithNameInContext':
 Core.cpp:(.text+0x195): undefined reference to `operator
 new(unsigned long)'
 /usr/local/lib/libLLVMCore.a(Core.o): In function
 `LLVMSetDataLayout': Core.cpp:(.text+0x240): undefined reference to
 `std::basic_string<char, std::char_traits<char>,
 std::allocator<char> >::basic_string(char const*, unsigned long,
 std::allocator<char> const&)' Core.cpp:(.text+0x24f): undefined
 reference to `std::basic_string<char, std::char_traits<char>,
 std::allocator<char>
 ::assign(std::basic_string<char, std::char_traits<char>,
 std::allocator<char> > const&)'
Core.cpp:(.text+0x25e): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char>
 ::_Rep::_S_empty_rep_storage'
Core.cpp:(.text+0x294): undefined reference to `std::basic_string<char, std::char_traits<char>, std::allocator<char>
 ::_Rep::_M_destroy(std::allocator<char> const&)'
 [...]
After scanning over the error messages, I think it's only operator, delete and std::* symbols that are missing. I also get the same error messages when I try to compile an equivalent C program that uses the llvm-c/* headers with gcc, but it works with g++, so I'm quite sure the problem is the missing c++ runtime, which is nonexistent in ldc. I think there are only two ways to solve this: (1) link the c++ runtime to ldc (I have no clue how to do that or if it's possible) (2) Write a D library using the llvm D-bindings, define a semi-main function as extern(C), and write a c++ wrapper program that links to the D library and does nothing more than calling the semi-main function. The llvm symbols and c++ runtime will then be linked in using g++. Option (2) seems easy, but ldc does not seem to have a linker swith to build libraries, and doing ar -cq myprog.a myprog.o to generate a library from the object file doesn't work because there are still undefined symbols to the main function or the module ctors in there, even when myprog.d doesn't define a main function. I could try to hack those missing functions back in by defining them in the C program, but there must be some simpler way to generate libraries, or am I at a loosing front here? I also consider using other compilers than ldc as an option, but afaik the only other usable compiler might be gdc (is that stable by now?).
=20 You should probably ask LDC guys (irc://irc.freenode.net/ldc)
Thanks, I'll try. But I think the development of LDC was put on hold due to lack of time and interest, let's see if I can find someone there :)
Oct 06 2010
parent reply Manuel =?ISO-8859-1?B?S/ZuaWc=?= <manuelk89 gmx.net> writes:
Am Wed, 6 Oct 2010 14:36:16 +0200
schrieb Manuel K=F6nig <manuelk89 gmx.net>:

=20
 You should probably ask LDC guys (irc://irc.freenode.net/ldc)
=20 Thanks, I'll try. But I think the development of LDC was put on hold due to lack of time and interest, let's see if I can find someone there :) =20
Well, the channel was actually full of people, and the problem was solved quickly. Actually the solution was method (1), linking in the stdc++ lib. For the record, here are some usage instructions for the llvm bindings. I will commit them to the repositority later, but I'll wait a bit and see if you have something to add. Initial setup: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D (1) checkout from svn (2) cd /path/to/llvm-2.7 (3) run prebuild.sh, this builds Target.o and Ext.o which have to be passed to the linker. For convenience, these *.o files are also merged into a single library libllvm-c-ext.a. Note: Target.o and Ext.o are usually not needed for the regular llvm c interface. But the D bindings add some extra bindings, because the official c interface just doesn't expose all functionality from the c++ interface. These are implemented as a "c++ to c to d" bridge (c++ to c is Target.cpp and Ext.cpp, c to d is Target.d and Ext.d). Building your application: =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D To compile and link a file main.d, run LLVMD=3D/path/to/llvm-dbindings LLVM_LIBS=3D`llvm-config --libs | sed 's/-l/-L-l'` ldc -I=3D$LLVMD \ -L=3D$LLVMD/{Target,Ext}.o \ $LLVM_LIBS \ -L-ldl -L-lstdc++ -relocation-model=3Dpic \ main.d Parameters: LLVM_LIBS a list of all llvm libraries, formatted for ldc -L=3D$LLVMD/{Target,Ext}.o only needed when you use Target.d or Ext.d -L-lstdc++ links in the c++ standard library (llvm at it's core is c++) -relocation-model=3Dpic necessary for calling code in your app from inside of the llvm vm
Oct 06 2010
parent reply Manuel =?ISO-8859-1?B?S/ZuaWc=?= <manuelk89 gmx.net> writes:
The previous "Initial setup" description didn't pass the "copy paste"
test, now it's more instructive. The same should work for llvm 2.6 and
2.8, too (yes, 2.8 was just released and the bindings are already
there :)

Initial setup:
==============

svn co http://svn.dsource.org/projects/bindings/trunk/llvm-2.7
cd llvm-2.7
./prebuild.sh

prebuild.sh builds Target.o and Ext.o which have to be passed
to the linker. For convenience, these *.o files are also merged
into a single library libllvm-c-ext.a.

Target.o and Ext.o are usually not needed for the regular
llvm c interface. But the D bindings add some extra bindings,
because the official c interface just doesn't expose all
functionality from the c++ interface. These are implemented as a
"c++ to c to d" bridge (c++ to c is Target.cpp and Ext.cpp, c to
d is Target.d and Ext.d).

Building your application:
==========================

To compile and link a file main.d, run

LLVMD=/path/to/llvm-dbindings
LLVM_LIBS=`llvm-config --libs | sed 's/-l/-L-l'`
ldc -I=$LLVMD \
    $LLVM_LIBS \
    -L=$LLVMD/libllvm-c-ext.a \
    -L-ldl -L-lstdc++ -relocation-model=pic \
    main.d 
    
Parameters:
LLVM_LIBS                 a list of all llvm libraries, formatted for
ldc -L=$LLVMD/libllvm-c-ext.a only needed when you use Target.d or Ext.d
-L-lstdc++                links in the c++ standard library (llvm at
it's core is c++) -relocation-model=pic     necessary for calling code
in your app from inside of the llvm vm
Oct 06 2010
parent mwarning <moritzwarning web.de> writes:
On Wed, 06 Oct 2010 16:57:09 +0200, Manuel König wrote:

 LLVM_LIBS=`llvm-config --libs | sed 's/-l/-L-l'`
typo detected, you need: sed 's/-l/-L-l/g' :)
Oct 06 2010