Thread overview
How to compile and link simple application?
Apr 08, 2019
4544fa8d
Apr 08, 2019
Adam D. Ruppe
Apr 08, 2019
4544fa8d
Apr 08, 2019
Julian
Apr 08, 2019
Julian
Apr 08, 2019
4544fa8d
Apr 08, 2019
Julian
Apr 08, 2019
Julian
Apr 08, 2019
Julian
April 08, 2019
Hello,

I have "hello world" application. I imported std.file, executed thisExePath() and now I have this error:

----------------------------------------------------------------
dmd -m64 -of=../../bin/manager -release ./src/manager.d
/usr/include/dmd/phobos/std/file.d(3252): Error: readlink cannot be interpreted at compile time, because it has no available source code
/usr/include/dmd/phobos/std/file.d(3253):        called from here: delegate () => readlink(linkz.ptr(), & buffer, 2048LU)()
/usr/include/dmd/phobos/std/file.d(3433):        called from here: readLink("/proc/self/exe")
./src/manager.d(8):        called from here: thisExePath()
./src/manager.d(8):        called from here: dirName(thisExePath())
makefile:2: recipe for target 'all' failed
----------------------------------------------------------------

Whats going on? Why I cant build my executable file?
April 08, 2019
On Monday, 8 April 2019 at 18:38:58 UTC, 4544fa8d wrote:
>
> Whats going on? Why I cant build my executable file?

Did you put your code inside a main() function?
April 08, 2019
On Monday, 8 April 2019 at 18:38:58 UTC, 4544fa8d wrote:
> Hello,
>
> I have "hello world" application. I imported std.file, executed thisExePath() and now I have this error:
>
> ----------------------------------------------------------------
> dmd -m64 -of=../../bin/manager -release ./src/manager.d
> /usr/include/dmd/phobos/std/file.d(3252): Error: readlink cannot be interpreted at compile time, because it has no available source code
> /usr/include/dmd/phobos/std/file.d(3253):        called from here: delegate () => readlink(linkz.ptr(), & buffer, 2048LU)()
> /usr/include/dmd/phobos/std/file.d(3433):        called from here: readLink("/proc/self/exe")
> ./src/manager.d(8):        called from here: thisExePath()
> ./src/manager.d(8):        called from here: dirName(thisExePath())
> makefile:2: recipe for target 'all' failed
> ----------------------------------------------------------------
>
> Whats going on? Why I cant build my executable file?

The error message is telling you that dmd is trying to run readlink
at compile-time. But this is probably an extern (C) symbol that isn't
resolved except by the linker to some code in libc, which can only
happen after any compile-time computation's done.

Are you trying to get the /proc/self/exe of dmd itself?
April 08, 2019
On Monday, 8 April 2019 at 18:41:00 UTC, Adam D. Ruppe wrote:
> Did you put your code inside a main() function?

I want to make constant with path to directory containing executable. This line is above main():
-----------------------------
const ROOT_DIR = dirName(thisExePath());
-----------------------------

This is not allowed? :O
April 08, 2019
On Monday, 8 April 2019 at 18:47:42 UTC, 4544fa8d wrote:
> On Monday, 8 April 2019 at 18:41:00 UTC, Adam D. Ruppe wrote:
>> Did you put your code inside a main() function?
>
> I want to make constant with path to directory containing executable. This line is above main():
> -----------------------------
> const ROOT_DIR = dirName(thisExePath());
> -----------------------------
>
> This is not allowed? :O

That would give you dmd's path, if it worked.

This is allowed:

  #! /usr/bin/env rdmd
  import std.stdio, std.path, std.file;

  @property
  string root_dir() {
      static string cache;
      static bool isInit = false;
      if (!isInit) {
          isInit = true;
          cache = dirName(thisExePath());
      }
      return cache;
  }

  void main() {
      writeln(root_dir);
  }

April 08, 2019
On Monday, 8 April 2019 at 18:54:10 UTC, Julian wrote:
>   @property
>   string root_dir() {
>       static string cache;
>       static bool isInit = false;
>       if (!isInit) {
>           isInit = true;
>           cache = dirName(thisExePath());
>       }
>       return cache;
>   }

Shorter:

  string root_dir() {
      static string cache;
      return cache ? cache : (cache = dirName(thisExePath()));
  }

This might spam readlink() syscalls if they somehow return the empty string,
but how would that even happen...
April 08, 2019
On Monday, 8 April 2019 at 19:05:33 UTC, Julian wrote:
> Shorter:
>   string root_dir() {
>       static string cache;
>       return cache ? cache : (cache = dirName(thisExePath()));
>   }
> This might spam readlink() syscalls if they somehow return the

It's really not possible to call functions in modules like in any other languages? :S

---------------------------------------------------------------
import std.file;
import std.path;
import std.stdio;

//const ROOT_DIR = dirName(thisExePath());
int someInt = 0;
string someString = "sfgsdgdf";
writeln("one");

void main(){
	writeln("two");
}
---------------------------------------------------------------

April 08, 2019
On Monday, 8 April 2019 at 19:29:33 UTC, 4544fa8d wrote:
> It's really not possible to call functions in modules like in any other languages? :S

What some other languages do is collect all of those calls into an
implicit function that's called before main(). What D does is run
that code at compile-time. Silly example:

  import std.stdio;

  T twice(T)(T n) { return 2 * n; }

  auto x = twice(5);

  void main() {
      writeln(x);
  }

Take a look at the compiled result: https://godbolt.org/z/8vLsv9

There's a twice() that's compiled in, but if you look at x it's
already the result of a call to twice():

  int example.x:
          .long   10

and the (unoptimized) main just fetches that number to print.

April 08, 2019
On Monday, 8 April 2019 at 19:43:11 UTC, Julian wrote:
> On Monday, 8 April 2019 at 19:29:33 UTC, 4544fa8d wrote:
>> It's really not possible to call functions in modules like in any other languages? :S
>
> What some other languages do is collect all of those calls into an
> implicit function that's called before main(). What D does is run
> that code at compile-time.

Another way, from https://dlang.org/spec/module.html#staticorder

In thisexe.d:

  import std.stdio, std.path, std.file;

  public string root_dir;

  shared static this() {
      root_dir = dirName(thisExePath());
  }

In thisexe_ex.d:

  #! /usr/bin/env rdmd
  import thisexe, std.stdio;

  void main() {
      writeln(root_dir);
  }

does what you'd expect.