Hipreme's #6 Tip of the day - Knowing when and how to use dub's Have_version
Hipreme
msnmancini at hotmail.com
Sun Nov 13 23:34:29 UTC 2022
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 :)
More information about the Digitalmars-d-learn
mailing list