Although I really don't like many things about how dub does, it brings many facilities. Imagine the following project structure:

Project A is using library B

Now, imagine that our `module b` has the following code:

```d
module b;

void print(string s){imported!"std.stdio".writeln(s);}

else version(Have_A)
{
void printA(string s){imported!"std.stdio".writeln("Printing from A!");}
}
```

Now, using the project A:

```d
module a;

void main()
{
  import b;
  printA("Printing from my project");
}
```

Now, do try to build it.

It compiles! But then you get a linker error! `Unresolved external function printA`. Now, do you understand why this just happened? If you execute `dub --verbose` You will be able to understand what just happened:

Build command for B: `dmd b.d -lib`
Build command for A: `-Imodule/b -version=Have_A b.lib a.d`


So: Your function printA does not get included in the process! As when the `b.lib` was built, there wasn't any version for doing the implementation, but when A imported B, it basically imports B as:

```d
void print(string s);
void printA(string s);
```

So, it won't be actually implementing your function, it just knows about the symbol existence, so, why should you ever use Have_version?

The following code for B would have worked:
```d
module b;
//Same thin above void print(string s)...

version(Have_A)
{
   public import a.print_a_implementation;
}
```

That way `module a.print_a_implementation` and then, you can guarantee that your code will be included (if print_a_implementation.d exists in your project)!

So, the key way to think about this is by when thinking about using `version(Have_LibraryNameHere)`, you will need to think about a 2 compiler passes, one for implementing the functions, another for including them. If you remember that, you won't do the same mistake as me :)

Reply via email to