www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - linking C++/D static library - what is "crt0.o"?

reply "bitwise" <bitwise.pvt gmail.com> writes:
Hi, just wondering if someone can help me out.
I'm trying to mix C++ and D code using ldc2 and clang++.

I'm using ldc 0.14.0, and the version of clang which came with 
Xcode(Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 
3.5svn))

I have two files:

<main.d>
module main;

import std.stdio;
import std.conv;

extern(C) int add(int a, int b);

void main() {
	int ret = add(1, 2);
	writeln("1 + 2 = " ~ to!string(ret));
}
</main.d>

<native.cpp>
extern "C" int add(int a, int b) {
	return a + b;
}
</native.cpp>


When I compile the above two files as executable, everything 
compiles and runs fine:

 ldc2 -c -od/.../test_exec/obj/Debug main.d
 clang++ -c -working-directory /.../test_exec/obj/Debug 
 ../../native.cpp
 clang++  -working-directory /.../test_exec 
 /.../test_exec/obj/Debug/main.o 
 /.../test_exec/obj/Debug/native.o /.../libdruntime-ldc.a 
 /.../libphobos2-ldc.a -obin/Debug/test_exec
the resulting executable outputs: "1 + 2 = 3" However, when I try to make a static library with the above files, it fails:
 ldc2 -c -od/.../test_lib/obj/Debug main.d
 clang++ -c -working-directory /.../test_lib/obj/Debug 
 ../../native.cpp
 clang++ -static -working-directory /.../test_lib 
 /.../test_lib/obj/Debug/main.o /.../test_lib/obj/Debug/native.o 
 -obin/Debug/libtest_lib.a
 ld: library not found for -lcrt0.o
 clang: error: linker command failed with exit code 1 (use -v to 
 see invocation)
So what is "-lcrt0.o" and why is clang trying to automatically add it to my static library?
Dec 28 2014
parent reply "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"bitwise"  wrote in message news:ckjqktzsmonjdcrhkhfg forum.dlang.org...

 However, when I try to make a static library with the above files, it 
 fails:

 ldc2 -c -od/.../test_lib/obj/Debug main.d
 clang++ -c -working-directory /.../test_lib/obj/Debug ../../native.cpp
 clang++ -static -working-directory /.../test_lib 
 /.../test_lib/obj/Debug/main.o 
 /.../test_lib/obj/Debug/native.o -obin/Debug/libtest_lib.a
IIRC passing -static to gcc/clang means 'statically link with C runtime libraries' not 'make a static library'. To create a static lib you need to create object files with -c and use 'ar' to create the static library. http://www.adp-gmbh.ch/cpp/gcc/create_lib.html
 ld: library not found for -lcrt0.o
 clang: error: linker command failed with exit code 1 (use -v to see 
 invocation)
So what is "-lcrt0.o" and why is clang trying to automatically add it to my static library?
crt0.o contains the code to call C's main and a few other things. It is automatically added when building an executable. The error possibly means your system isn't set up for statically linking the cruntime.
Dec 28 2014
next sibling parent "bitwise" <bitwise.pvt gmail.com> writes:
 IIRC passing -static to gcc/clang means 'statically link with C 
 runtime libraries' not 'make a static library'.  To create a 
 static lib you need to create object files with -c and use 'ar' 
 to create the static library.
Ah! That makes sense ;) I had actually tried ar, but misunderstood the error I was getting. After re-checking my usage, it works as expected. In the mean time, I've continued to work on this problem and found that ldc can be used to link as well:
 ldc2 -lib obj/Debug/main.o obj/Debug/native.o 
 -ofbin/Debug/libtest_lib.a
and
ldc2  obj/Debug/main.o obj/Debug/native.o 
-L/usr/lib/libc++.dylib -ofbin/Debug/test_exec
I can't think of any reason to use one over the other, so I'm inclined to go with the second option. Thanks
Dec 28 2014
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2014-12-29 05:55, Daniel Murphy wrote:

 crt0.o contains the code to call C's main and a few other things.  It is
 automatically added when building an executable.  The error possibly
 means your system isn't set up for statically linking the cruntime.
Yeah, OS X doesn't support static linking of the C runtime. -- /Jacob Carlborg
Dec 29 2014