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 1DMD 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 theactualfiles 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 toseerdmd 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 thinkofa 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 ratherthanappend to the default. And that's just silly.
Oct 28 2011