digitalmars.D - D packages, include directories, and rdmd
- Andrew Pennebaker (20/20) Oct 27 2011 I've got a single-file D module,
- Nick Sabalausky (19/39) Oct 27 2011 I guess DFLAGS isn't an env var (which actually surprises me, it probabl...
- Andrew Pennebaker (20/66) Oct 27 2011 In addition, I can't even use a naked -I directive without all the
- Nick Sabalausky (20/36) Oct 27 2011 DMD found it as an import, you're just getting linker errors because you...
- Jesse Phillips (3/10) Oct 27 2011 Just a theory but I suspect that DFLAGS in dmd.conf just override the en...
- Andrew Pennebaker (15/29) Oct 27 2011 Nick, thanks for the info. I'm upgrading my Homebrew D installation now.
- Nick Sabalausky (59/71) Oct 27 2011 It has to do with D's C/C++ legacy, and the traditional C/C++ build mode...
- Andrew Pennebaker (52/134) Oct 28 2011 Nick, thanks for the in-depth explanation of compilation with C and D.
I've got a single-file D module, dashcheck.d<https://github.com/mcandre/dashcheck>, that I'd like to install as a local package. In other words, I'd like to be able to "import dashcheck;" from any directory. I put dashcheck.d in ~/.d/, and I put export DFLAGS=-I~/.d in ~/.profile, but when I try to run example.d from another directory, I get: $ ./example.d ./example.d(3): Error: module dashcheck is in file 'dashcheck.d' which cannot be read import path[0] = /usr/local/Cellar/dmd/2.051/src/phobos import path[1] = /usr/local/Cellar/dmd/2.051/src/druntime/importCheers, It appears that rdmd ignores $DFLAGS. I get: $ ./example.d sh: -I~/.d.d.deps: No such file or directory So I'm not using import directives correctly. How do I generate dashcheck.d.deps? Andrew Pennebaker www.yellosoft.us
Oct 27 2011
"Andrew Pennebaker" <andrew.pennebaker gmail.com> wrote in message news:mailman.543.1319752640.24802.digitalmars-d puremagic.com...I've got a single-file D module, dashcheck.d<https://github.com/mcandre/dashcheck>, that I'd like to install as a local package. In other words, I'd like to be able to "import dashcheck;" from any directory. I put dashcheck.d in ~/.d/, and I put export DFLAGS=-I~/.d in ~/.profile, but when I try to run example.d from another directory, I get: $ ./example.d ./example.d(3): Error: module dashcheck is in file 'dashcheck.d' which cannot be read import path[0] = /usr/local/Cellar/dmd/2.051/src/phobos import path[1] = /usr/local/Cellar/dmd/2.051/src/druntime/importCheers, It appears that rdmd ignores $DFLAGS.I guess DFLAGS isn't an env var (which actually surprises me, it probably should be, is there already an enhancement request in bugzilla for that? Is is there some deliberate reason for this?). DFLAGS is normally set in your dmd.conf file (sc.ini on Windows). Do a "which dmd" to see where your dmd binary is, and your dmd.conf will be in the same directory (at least if you used the .zip releases or DVM, I don't know where the distros will put dmd.conf). Another approach that many of us use is to just pass the -Ipath option to dmd or rdmd in your buildscript to tell dmd/rdmd where to look for look for imports (sort of the D counterpart to Java's classpaths).$DFLAGS, I get: $ ./example.d sh: -I~/.d.d.deps: No such file or directory So I'm not using import directives correctly. How do I generate dashcheck.d.deps?Part of the problem here is the same as above, DFLAGS needs to be set in dmd.conf, not an env var. But also, when you use rdmd as a shebang, you should use the --shebang option (always as the first argument), ie: Apperently, shebangs tend to mess up the params that get sent to rdmd, and the --shebang makes it use an alternate approach made specifically for that situation.
Oct 27 2011
In addition, I can't even use a naked -I directive without all the
dmd.conf/DFLAGS stuff.
My module code is in ~/Desktop/src/dashcheck. But even with the -Ipath
directive, dmd still can't find it.
$ dmd example.d -I~/Desktop/src/dashcheck
Undefined symbols for architecture i386:
"_D9dashcheck12__ModuleInfoZ", referenced from:
_D7example12__ModuleInfoZ in example.o
"_D9dashcheck9genStringFZAya", referenced from:
anon in example.o
"_D9dashcheck6genIntFZi", referenced from:
anon in example.o
_D7example7genEvenFZi in example.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
--- errorlevel 1
Cheers,
Andrew Pennebaker
www.yellosoft.us
On Thu, Oct 27, 2011 at 6:28 PM, Nick Sabalausky <a a.a> wrote:
"Andrew Pennebaker" <andrew.pennebaker gmail.com> wrote in message
news:mailman.543.1319752640.24802.digitalmars-d puremagic.com...
I've got a single-file D module,
dashcheck.d<https://github.com/mcandre/dashcheck>,
that I'd like to install as a local package. In other words, I'd like to
be
able to "import dashcheck;" from any directory.
I put dashcheck.d in ~/.d/, and I put export DFLAGS=-I~/.d in ~/.profile,
but when I try to run example.d from another directory, I get:
$ ./example.d
./example.d(3): Error: module dashcheck is in file 'dashcheck.d' which
cannot be read
import path[0] = /usr/local/Cellar/dmd/2.051/src/phobos
import path[1] = /usr/local/Cellar/dmd/2.051/src/druntime/importCheers,
It appears that rdmd ignores $DFLAGS.
I guess DFLAGS isn't an env var (which actually surprises me, it probably
should be, is there already an enhancement request in bugzilla for that? Is
is there some deliberate reason for this?).
DFLAGS is normally set in your dmd.conf file (sc.ini on Windows). Do a
"which dmd" to see where your dmd binary is, and your dmd.conf will be in
the same directory (at least if you used the .zip releases or DVM, I don't
know where the distros will put dmd.conf).
Another approach that many of us use is to just pass the -Ipath option to
dmd or rdmd in your buildscript to tell dmd/rdmd where to look for look for
imports (sort of the D counterpart to Java's classpaths).
$DFLAGS,
I get:
$ ./example.d
sh: -I~/.d.d.deps: No such file or directory
So I'm not using import directives correctly. How do I generate
dashcheck.d.deps?
Part of the problem here is the same as above, DFLAGS needs to be set in
dmd.conf, not an env var. But also, when you use rdmd as a shebang, you
should use the --shebang option (always as the first argument), ie:
Apperently, shebangs tend to mess up the params that get sent to rdmd, and
the --shebang makes it use an alternate approach made specifically for that
situation.
Oct 27 2011
"Andrew Pennebaker" <andrew.pennebaker gmail.com> wrote in message
news:mailman.545.1319755391.24802.digitalmars-d puremagic.com...
In addition, I can't even use a naked -I directive without all the
dmd.conf/DFLAGS stuff.
My module code is in ~/Desktop/src/dashcheck. But even with the -Ipath
directive, dmd still can't find it.
$ dmd example.d -I~/Desktop/src/dashcheck
Undefined symbols for architecture i386:
"_D9dashcheck12__ModuleInfoZ", referenced from:
_D7example12__ModuleInfoZ in example.o
"_D9dashcheck9genStringFZAya", referenced from:
anon in example.o
"_D9dashcheck6genIntFZi", referenced from:
anon in example.o
_D7example7genEvenFZi in example.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
--- errorlevel 1
DMD found it as an import, you're just getting linker errors because you
didn't tell DMD to actually compile dashcheck.d as well. For better or
worse, DMD only compiles the files you give it, just like any old C/C++
compiler:
dmd example.d ~/Desktop/src/dashcheckdashcheck.d -I~/Desktop/src/dashcheck
RDMD, on the other hand, will actually go ahead and compile all the
necessary .d files:
rdmd --buildonly -I~/Desktop/src/dashcheck example.d
(Note that RDMD requires the .d file to be the last parameter. Run rdmd with
no args for more details.)
There's one more thing though: I noticed from your OP that you're using DMD
2.051. The RDMD included in that is riddled with fairly major bugs that have
all since been fixed. You're going to have a hard time getting that old RDMD
to work right. So you should grab the rdmd binary from the latest release
(2.056): http://ftp.digitalmars.com/dmd.2.056.zip
You can just replace your existing rdmd binary with the one in there. It
should still work with DMD 2.051. Of course, DMD 2.051 itself is getting a
bit old too, so you may want to think about just simply upgrading to 2.056.
Oct 27 2011
Andrew Pennebaker Wrote:I've got a single-file D module, dashcheck.d<https://github.com/mcandre/dashcheck>, that I'd like to install as a local package. In other words, I'd like to be able to "import dashcheck;" from any directory. I put dashcheck.d in ~/.d/, and I put export DFLAGS=-I~/.d in ~/.profile, but when I try to run example.d from another directory, I get:Just a theory but I suspect that DFLAGS in dmd.conf just override the environment you specify. You should be able to specify -I yourself but ~ may not be resolved. Also you must have a library and specify the library path -L-L or place it in a known location like /usr/local/lib
Oct 27 2011
Nick, thanks for the info. I'm upgrading my Homebrew D installation now. What's the point of -Ipath for dmd if you still have to specify the actual files in the path? I'm not sure if this is the right mailing list, but I'd really like to see rdmd using the $DFLAGS environment variable like dmd does. For now, I'll use your handy shebang tip. Can future versions of rdmd turn on --shebang by default? I can't think of a reason to give coders the ability to not support shebang options. Jesse, aye, DFLAGS in dmd.conf appears to override the default rather than append to the default. And that's just silly. Cheers, Andrew Pennebaker www.yellosoft.us On Thu, Oct 27, 2011 at 7:17 PM, Jesse Phillips <jessekphillips+D gmail.com>wrote:Andrew Pennebaker Wrote:I've got a single-file D module, dashcheck.d<https://github.com/mcandre/dashcheck>, that I'd like to install as a local package. In other words, I'd like tobeable to "import dashcheck;" from any directory. I put dashcheck.d in ~/.d/, and I put export DFLAGS=-I~/.d in ~/.profile, but when I try to run example.d from another directory, I get:Just a theory but I suspect that DFLAGS in dmd.conf just override the environment you specify. You should be able to specify -I yourself but ~ may not be resolved. Also you must have a library and specify the library path -L-L or place it in a known location like /usr/local/lib
Oct 27 2011
"Andrew Pennebaker" <andrew.pennebaker gmail.com> wrote in message news:mailman.550.1319767813.24802.digitalmars-d puremagic.com...Nick, thanks for the info. I'm upgrading my Homebrew D installation now. What's the point of -Ipath for dmd if you still have to specify the actual files in the path?It has to do with D's C/C++ legacy, and the traditional C/C++ build model. In C/C++, you can compile difference sources separately, and *then* link them together - in fact, that's the old traditional way to do it: (I might not have these commands correct, I don't use gcc much) in ~/ and ~/zlib with pre-built zlib D retains that ability: in ~/ and ~/zlib with pre-built zlib And as a shortcut, modern C/C++ and D compilers offer the ability to simplify that all into one command: above statements But the old way is still possible becuause sometimes it can be useful (for instance, if a b and c are all in different languages, or if you want them each compiled with different settings, or to speed up long C/C++ compile times by compiling different parts on different machines). So that leads to this: Regardless of whether you do that in C/C++ or D: Suppose 'a' imports 'b', and inside 'a' you call a function from 'b'. If you've told it to *only* compile 'a' and not 'b' (because you intend to do it all separately) how does the compiler know that function you're using actually exists if you've only given it 'a'? Or if 'a' uses a class defined in 'b', how does the compiler know what members the class has if you only told it to compile 'a'? It has to find 'b', open it, and check. That's what -Ipath is for, so it knows where to find 'b' so it can find out what's in 'b', so that it can compile 'a' regardless of whether or not it's actually compiling 'b' as well. Of course, in most cases with D, all of that "one at a time" junk is just a pointless PITA, so fortunately we have RDMD to find all the .d files and just shove them all off to be compiled. So this: $ dmd -ofapp -I~/zlib a.d ~/b.d ~/c.d ~/zlib/zlib.lib Becomes this: $ rdmd --build-only -ofapp -I~/zlib ~/zlib/zlib.lib a.d Note that ~/b.d and ~/c.d were omitted because RDMD will just find them itself, thanks to the -Ipath, and pass them all off to DMD to be compiled. Why can't DMD just do this itself, even just as an option? It could, and many people here wish it did. Maybe it even will someday. But right now it doesn't, so we have RDMD for that.I'm not sure if this is the right mailing list, but I'd really like to see rdmd using the $DFLAGS environment variable like dmd does.Yea, that would be nice.For now, I'll use your handy shebang tip. Can future versions of rdmd turn on --shebang by default? I can't think of a reason to give coders the ability to not support shebang options.If it did that, then it won't work on the commandline anymore. :( IIRC, the problem is that with shebang scripts, all the args get passed in together as *one* large arg. But maybe there's a way to detect what's happening that isn't too unreliable...? Hell, other Unix apps don't seem to have this sort of problem, how the heck to they handle it?Jesse, aye, DFLAGS in dmd.conf appears to override the default rather than append to the default. And that's just silly.
Oct 27 2011
Nick, thanks for the in-depth explanation of compilation with C and D.
Other shebanged languages *do* have the argument limitation problem. One way
to deal with it is to use multiline
shebangs<http://rosettacode.org/wiki/Multiline_shebang>.
They're especially helpful for doing scripted
main<http://rosettacode.org/wiki/Scripted_Main>,
running main() when the script is run, but not when the code is imported by
other code.
For example, since Clojure is in Java Land, it expects a class name rather
than a filename, so you have to do shell trickery just to get the basename.
Clojure
":";exec clj -m `basename $0 .clj` $0 ${1+"$ "}
":";exit
The CLISP implementation of Common Lisp drops the program name as an
argument, so you have to forcibly add it back. Unfortunately, each CL
implementation has its own program name, *and* command line semantics, so
you have to rewrite this one for the particular CL implementation on your
machine.
Common Lisp
exec clisp -q -q $0 $0 ${1+"$ "}
exit
Chicken Scheme
exec csi -ss $0 ${1+"$ "}
exit
Emacs Lisp
:;exec emacs -batch -l $0 -f main $*
Smalltalk
"exec" "gst" "-f" "$0" "$0" "$ "
"exit"
The trick is to find a way to comment the shebang lines so that sh sees them
but not your programming language. But the real trouble is discovering the
secret syntax for this; when you have to resort to multiline shebangs,
that's an indication that scripting/CLI/POSIX is an incredibly low priority,
so developers A) don't know such obscure syntax and B) don't understand why
anyone would want to script on the command line. Common Lispers tell you
"there's no reason to use bash when you've got the CL repl". Smalltalkers
say "just use the Squeak VM GUI." And Free Pascalers remark "Scripting? You
kids get off my lawn!"
Language-specific IDEs are neat, but I like using a language-agnostic
development environment: a text editor and a shell, and I like being able to
dot-slash my scripts: ./script if at all possible.
So three cheers for rdmd!
Cheers,
Andrew Pennebaker
www.yellosoft.us
On Thu, Oct 27, 2011 at 11:17 PM, Nick Sabalausky <a a.a> wrote:
"Andrew Pennebaker" <andrew.pennebaker gmail.com> wrote in message
news:mailman.550.1319767813.24802.digitalmars-d puremagic.com...
Nick, thanks for the info. I'm upgrading my Homebrew D installation now.
What's the point of -Ipath for dmd if you still have to specify the
actual
files in the path?
It has to do with D's C/C++ legacy, and the traditional C/C++ build model.
In C/C++, you can compile difference sources separately, and *then* link
them together - in fact, that's the old traditional way to do it:
(I might not have these commands correct, I don't use gcc much)
in ~/ and ~/zlib
with pre-built zlib
D retains that ability:
in ~/ and ~/zlib
with pre-built zlib
And as a shortcut, modern C/C++ and D compilers offer the ability to
simplify that all into one command:
above statements
But the old way is still possible becuause sometimes it can be useful (for
instance, if a b and c are all in different languages, or if you want them
each compiled with different settings, or to speed up long C/C++ compile
times by compiling different parts on different machines).
So that leads to this:
Regardless of whether you do that in C/C++ or D: Suppose 'a' imports 'b',
and inside 'a' you call a function from 'b'. If you've told it to *only*
compile 'a' and not 'b' (because you intend to do it all separately) how
does the compiler know that function you're using actually exists if you've
only given it 'a'? Or if 'a' uses a class defined in 'b', how does the
compiler know what members the class has if you only told it to compile
'a'?
It has to find 'b', open it, and check. That's what -Ipath is for, so it
knows where to find 'b' so it can find out what's in 'b', so that it can
compile 'a' regardless of whether or not it's actually compiling 'b' as
well.
Of course, in most cases with D, all of that "one at a time" junk is just a
pointless PITA, so fortunately we have RDMD to find all the .d files and
just shove them all off to be compiled. So this:
$ dmd -ofapp -I~/zlib a.d ~/b.d ~/c.d ~/zlib/zlib.lib
Becomes this:
$ rdmd --build-only -ofapp -I~/zlib ~/zlib/zlib.lib a.d
Note that ~/b.d and ~/c.d were omitted because RDMD will just find them
itself, thanks to the -Ipath, and pass them all off to DMD to be compiled.
Why can't DMD just do this itself, even just as an option? It could, and
many people here wish it did. Maybe it even will someday. But right now it
doesn't, so we have RDMD for that.
I'm not sure if this is the right mailing list, but I'd really like to
see
rdmd using the $DFLAGS environment variable like dmd does.
Yea, that would be nice.
For now, I'll use
your handy shebang tip.
Can future versions of rdmd turn on --shebang by default? I can't think
of
a
reason to give coders the ability to not support shebang options.
If it did that, then it won't work on the commandline anymore. :( IIRC,
the
problem is that with shebang scripts, all the args get passed in together
as
*one* large arg.
But maybe there's a way to detect what's happening that isn't too
unreliable...?
Hell, other Unix apps don't seem to have this sort of problem, how the heck
to they handle it?
Jesse, aye, DFLAGS in dmd.conf appears to override the default rather
than
append to the default. And that's just silly.
Oct 28 2011









"Nick Sabalausky" <a a.a> 