On Saturday, 12 March 2016 at 22:34:19 UTC, Voitech wrote:
At beginning I want to say that I'm Java devloper so most of
linking, joining, dependent classes, libs could be solve with
simple 3 click in eclipse so please be patient with me :).
I'm using Mono-D under Ubuntu 14.04 to create my project it
would be a library for further development process, but I'm a
guy who don't want to invite wheel again and again, so i wanted
to use Tango-D2 (for now HashMap implemenetation).
Anything wrong with the built in associative arrays that cause
you not to use them?
From what i red you cant import one static library with another
but somehow import o. files, or just copy sources .d to proper
folder and use them as yours (with proper license of course).
Tango-D2 by itself compiles nicely with bob and produces many
.o files. How to use them though ?
Forget the word 'import' for a minute. There are two basic steps
to concern yourself with: compiling and linking. D's approach is
the traditional C approach. We can loosely define the terms like
so:
compile: take source files as input and generate object files as
output
link: take object files as input and generate executables (or
shared libraries, but let's not confuse things) as output.
In order to compile, the compiler needs to be aware of every
symbol that is visible and usable in the source module it is
currently compiling. As an example, consider the following two
files:
main.d something.d
When compiling main.d, all of the symbols inside main.d are
visible by default. In order for main.d to use the symbols in
something.d, it must 'import' something.d.
import something;
void main() { aFunctionInSomething(); }
Assuming the implementation of aFunctionInSomething lives in
something.d, it is now visible inside main.d because of the
import. Take away the import, and you get a /compiler error/. The
compiler doesn't know about that function, so you can't use it.
Assuming both files live in the same directory, they can be
compiled with this command:
Once the object files are generated, they are passed to the
linker. The important thing to understand here is that the
'import' statement in the source code above has absolutely no
bearing on the link stage. It is exclusively for the compiler.
The linker will never, ever, see it. All the linker cares about
are symbols in the object files. To fully appreciate that, try
this experiment.
Take the main.d source as it is above. Then implement something.d
like so:
module something;
import std.stdio;
void aFunctionInSomething() { writeln("Something"); }
Next, cd to the directory where you saved the files and compile
them both:
dmd -c main.d
dmd -c something.d
The -c option tells the compiler to only generate the object
files and do not pass them to the linker. The result is that you
will now have two object files. If you next take the following
step (assuming Windows -- change .obj to .o elsehwere):
dmd main.obj something.obj
The compiler will recognize you've passed it object files and
will hand them off to the linker. However, try this:
dmd main.obj
Using the default linker on Windows (OPTLINK -- passing
-m32mscoff or -m64 uses the Microsoft linker if you have it
installed, but the source must be compiled with the same flag)
yields the following output:
OPTLINK (R) for Win32 Release 8.00.17
Copyright (C) Digital Mars 1989-2013 All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
main.obj(main)
Error 42: Symbol Undefined _D9something20aFunctionInSomethingFZv
main.obj(main)
Error 42: Symbol Undefined _D9something12__ModuleInfoZ
--- errorlevel 2
These are linker errors. You can know this because of two things:
the big OPTLINK in the first line and the error type 'Symbol
Undefined'. The Microsoft linker produces this:
main.obj : error LNK2001: unresolved external symbol
_D9something12__ModuleInfoZ
main.obj : error LNK2019: unresolved external symbol
_D9something20aFunctionInSomethingFZv referenced in function
_Dmain
main.exe : fatal error LNK1120: 2 unresolved externals
You can know these are linker errors because of the Microsoft
erro codes containing the 'LNK' prefix and because of 'unresolved
external symbol', which is the equivalent of OPTLINK's 'Symbol
Undefined'. It's important to be able to distinguish linker
errors from compiler errors.
When you pass both objects on the command line, the linker is
then able to find the symbol it needs.
A static library is one or more object files bundled into a
single file:
dmd lib something.d
This will create a static library called something.lib. Then you
can do this:
dmd main.d something.lib
In this particular case, it's exactly equivalent to the following:
dmd -c something.d
dmd main.d something.obj
The benefit of static libraries is when you have multiple object
files:
dmd lib foo.d bar.d baz.d
dmd main.d foo.lib
Much more convenient to deal with one library than three