Thread overview
linking C++/D static library - what is "crt0.o"?
Dec 28, 2014
bitwise
Dec 29, 2014
Daniel Murphy
Dec 29, 2014
bitwise
Dec 29, 2014
Jacob Carlborg
December 28, 2014
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?

December 29, 2014
"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. 

December 29, 2014
> 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
December 29, 2014
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