digitalmars.D - Cross module version specs
- James Miller (15/15) Apr 26 2012 I'm trying to write a binding that has conditional sections where
- Jonathan M Davis (21/25) Apr 26 2012 They can't be. The only time that versions apply to your entire program ...
- James Miller (11/25) Apr 26 2012 Is there any reason for that limitation? Seems like an arbitrary
- Steven Schveighoffer (34/56) Apr 26 2012 No, it would not be nice, it would be horrible. C's preprocessor is one...
- James Miller (9/53) Apr 26 2012 [snip]
- bcs (5/8) Apr 26 2012 Versions should be defined for the *entire program*, not just for
- Marco Leise (16/28) Apr 27 2012 You would need to modify the linker (optlink/ld) to understand that two ...
- bcs (2/27) Apr 26 2012
- Marco Leise (5/6) Apr 27 2012 Take a look at the GtkD sources, more specifically the files in gtkc/ :-...
- Matt Peterson (8/8) Apr 27 2012 What about a templated module?
- Dmitry Olshansky (7/15) Apr 27 2012 I would rather see this as import test with specified version identifier...
- Matt Peterson (5/10) Apr 27 2012 This is inconsistent with the syntax and the way templates work
- Walter Bright (5/15) Apr 26 2012 This is quite deliberate behavior.
- Paulo Pinto (7/33) Apr 26 2012 I would be with Walter on this.
I'm trying to write a binding that has conditional sections where some features have to be enabled. I am using version statements for this. I have a list of version specs in a module by themselves. When I try to compile another module that imports this module, it acts as if the version was never specified. I have tried wrapping the specs inside a version block, then setting that from the command but that doesn't work. Setting the version manually works as expected. I have also tried including the versions file on the command line. All I can think is that version specifiers aren't carried across modules, which pretty much makes them completely useless unless you only use the built-in versions. -- James Miller
Apr 26 2012
On Thursday, April 26, 2012 12:09:19 James Miller wrote:All I can think is that version specifiers aren't carried across modulesThey can't be. The only time that versions apply to your entire program is if they're built-in or they're specified on the command line.which pretty much makes them completely useless unless you only use the built-in versions.That's not true at all. It just means that versions are either useful for something within a module or they're intended for your program as a whole and passed on the command line (e.g. StdDdoc is used by Phobos, and it's not standard at all; the makefile adds it to the list of compiler flags). But yes, it's true that if you want to define a version in one module which affects another, you can't do it. The closest that you would be able to do would be something along the lines of having a function in the imported module which returned the version statements as a string which the module doing the importing mixed in. Another option would be to just use static ifs, since they'd be affected by whatever variables or enums where defined in the imported modules. e.g. static if(is(myVersionEnum1)) { } else static if(is(myVersionEnum2)) { } - Jonathan M Davis
Apr 26 2012
On Thursday, 26 April 2012 at 10:20:37 UTC, Jonathan M Davis wrote:On Thursday, April 26, 2012 12:09:19 James Miller wrote:Is there any reason for that limitation? Seems like an arbitrary limit to me. The library I am binding to uses ifdefs to let the compiler see the appropriate declarations in the header files. It would be nice in general for D to be able to mimic that capability, as it means you can have a "configuration" file with a list of specs that can be generated at build-time by something like autoconf. -- James Millerwhich pretty much makes them completely useless unless you only use the built-in versions.That's not true at all. It just means that versions are either useful for something within a module or they're intended for your program as a whole and passed on the command line (e.g. StdDdoc is used by Phobos, and it's not standard at all; the makefile adds it to the list of compiler flags). But yes, it's true that if you want to define a version in one module which affects another, you can't do it.
Apr 26 2012
On Thu, 26 Apr 2012 06:32:58 -0400, James Miller <james aatch.net> wrote:On Thursday, 26 April 2012 at 10:20:37 UTC, Jonathan M Davis wrote:No, it would not be nice, it would be horrible. C's preprocessor is one of the main reasons I sought out something like D. The fact that you can include files in a different order and get a completely different result is not conducive to understanding code or keeping code sane. The correct thing to use for something like this is enums and static ifs. They work because enums are fully qualified within the module they are defined, and you can't define and use the same unqualified enums in multiple places. I'll give you some examples: module1.d: version = abc; module2.d: version(abc) int x; else double x; module3.d: import module1; import module2; pragma(msg, typeof(x).stringof); // int or double? module4.d: import module3; version(abc) int y; else double y; pragma(msg, typeof(y).stringof); // int or double? Now, what happens? Should module2 be affected by module1's versions? What about module4? What if module4 doesn't know that module3 indirectly declares abc as a version? What if module3 didn't import module1 at the time module4 was written, but added it later? These kinds of decoupled effects are what kills me when I ever read a heavily #ifdef'd header file. versions should be defined for the *entire program*, not just for certain files. And if they are defined just for certain files, define them in the file itself. -SteveOn Thursday, April 26, 2012 12:09:19 James Miller wrote:Is there any reason for that limitation? Seems like an arbitrary limit to me. The library I am binding to uses ifdefs to let the compiler see the appropriate declarations in the header files. It would be nice in general for D to be able to mimic that capability, as it means you can have a "configuration" file with a list of specs that can be generated at build-time by something like autoconf.which pretty much makes them completely useless unless you only use the built-in versions.That's not true at all. It just means that versions are either useful for something within a module or they're intended for your program as a whole and passed on the command line (e.g. StdDdoc is used by Phobos, and it's not standard at all; the makefile adds it to the list of compiler flags). But yes, it's true that if you want to define a version in one module which affects another, you can't do it.
Apr 26 2012
On Thursday, 26 April 2012 at 12:37:44 UTC, Steven Schveighoffer wrote:On Thu, 26 Apr 2012 06:32:58 -0400, James Miller <james aatch.net> wrote:[snip]On Thursday, 26 April 2012 at 10:20:37 UTC, Jonathan M Davis wrote:No, it would not be nice, it would be horrible. C's preprocessor is one of the main reasons I sought out something like D. The fact that you can include files in a different order and get a completely different result is not conducive to understanding code or keeping code sane. The correct thing to use for something like this is enums and static ifs. They work because enums are fully qualified within the module they are defined, and you can't define and use the same unqualified enums in multiple places.On Thursday, April 26, 2012 12:09:19 James Miller wrote:Is there any reason for that limitation? Seems like an arbitrary limit to me. The library I am binding to uses ifdefs to let the compiler see the appropriate declarations in the header files. It would be nice in general for D to be able to mimic that capability, as it means you can have a "configuration" file with a list of specs that can be generated at build-time by something like autoconf.which pretty much makes them completely useless unless you only use the built-in versions.That's not true at all. It just means that versions are either useful for something within a module or they're intended for your program as a whole and passed on the command line (e.g. StdDdoc is used by Phobos, and it's not standard at all; the makefile adds it to the list of compiler flags). But yes, it's true that if you want to define a version in one module which affects another, you can't do it.These kinds of decoupled effects are what kills me when I ever read a heavily #ifdef'd header file. versions should be defined for the *entire program*, not just for certain files. And if they are defined just for certain files, define them in the file itself. -SteveI didn't think about it like that, thanks. I'm planning on just using enums and static ifs in this case now, since it certainly makes more sense and I can achieve the same effect. Thanks all -- James Miller
Apr 26 2012
On 04/26/2012 05:37 AM, Steven Schveighoffer wrote:versions should be defined for the *entire program*, not just for certain files. And if they are defined just for certain files, define them in the file itself.Versions should be defined for the *entire program*, not just for whatever you happen to be compiling right now. Is there any way to make different modules complain if you link object files built with diffident versions set?
Apr 26 2012
Am Thu, 26 Apr 2012 21:24:46 -0700 schrieb bcs <bcs example.com>:On 04/26/2012 05:37 AM, Steven Schveighoffer wrote:You would need to modify the linker (optlink/ld) to understand that two object files compiled by a D compiler include a section that informs it about enabled version tags, or maybe abuse existing systems to the end that the poor programmer mixing versions up gets a generic error message that doesn't make any sense. But more importantly, you can bundle up object files into .a archives aka static _libraries_ with yet another tool, I think ar is its name. It would not work out if e.g. GtkD compiled its static libraries with one set of versions and you compile your app with another set. Or in contrast, you would have to enable versions like 'cairo_new_backend', 'druntime_use_old_gc', 'whatever_any_other_object_file_was_compiled_with' for your program, even if you don't need them. To sort that mess out again, the compiler would have to create a list of versions that affect the currently compiled module at all. It would then find out that for your program 'druntime_use_old_gc' is irrelevant and exclude it from the version check. my_app GtkD Phobos <conflicts?> my_ver on - - no unused off - - no cairo_new_backend - on - no druntime_use_old_gc - - off no debug on off off yes X86_64 on - on no In this case the linker would complain only about a version named 'debug' that was enabled in your application, but not for the object files of GtkD and Phobos. -- Marco P.S.: Can I have a software patent on this?versions should be defined for the *entire program*, not just for certain files. And if they are defined just for certain files, define them in the file itself.Versions should be defined for the *entire program*, not just for whatever you happen to be compiling right now. Is there any way to make different modules complain if you link object files built with diffident versions set?
Apr 27 2012
On 04/26/2012 03:20 AM, Jonathan M Davis wrote:On Thursday, April 26, 2012 12:09:19 James Miller wrote:One monster of a string mixin?All I can think is that version specifiers aren't carried across modulesThey can't be. The only time that versions apply to your entire program is if they're built-in or they're specified on the command line.which pretty much makes them completely useless unless you only use the built-in versions.That's not true at all. It just means that versions are either useful for something within a module or they're intended for your program as a whole and passed on the command line (e.g. StdDdoc is used by Phobos, and it's not standard at all; the makefile adds it to the list of compiler flags). But yes, it's true that if you want to define a version in one module which affects another, you can't do it. The closest that you would be able to do would be something along the lines of having a function in the imported module which returned the version statements as a string which the module doing the importing mixed in. Another option would be to just use static ifs, since they'd be affected by whatever variables or enums where defined in the imported modules. e.g. static if(is(myVersionEnum1)) { } else static if(is(myVersionEnum2)) { } - Jonathan M Davis
Apr 26 2012
Am Thu, 26 Apr 2012 21:22:46 -0700 schrieb bcs <bcs example.com>:One monster of a string mixin?Take a look at the GtkD sources, more specifically the files in gtkc/ :-) -- Marco
Apr 27 2012
What about a templated module? module test(bool option1, T); Imported like this: import test!(true, Foo); It could act like the entire module was wrapped in a template, and the import would become: import test; mixin test.test_template!(true, Foo);
Apr 27 2012
On 28.04.2012 0:22, Matt Peterson wrote:What about a templated module? module test(bool option1, T); Imported like this: import test!(true, Foo); It could act like the entire module was wrapped in a template, and the import would become: import test; mixin test.test_template!(true, Foo);I would rather see this as import test with specified version identifiers. import test!(some_version); //imports module but treats it contents as if with "version = some_version;" added at the top of it -- Dmitry Olshansky
Apr 27 2012
On Friday, 27 April 2012 at 20:26:38 UTC, Dmitry Olshansky wrote:I would rather see this as import test with specified version identifiers. import test!(some_version); //imports module but treats it contents as if with "version = some_version;" added at the top of itThis is inconsistent with the syntax and the way templates work in the rest of the language, as well as being a lot less flexible. It wouldn't be hard to mixin a string built from a list of identifiers passed in to set those versions.
Apr 27 2012
On 4/26/2012 3:09 AM, James Miller wrote:I'm trying to write a binding that has conditional sections where some features have to be enabled. I am using version statements for this. I have a list of version specs in a module by themselves. When I try to compile another module that imports this module, it acts as if the version was never specified. I have tried wrapping the specs inside a version block, then setting that from the command but that doesn't work. Setting the version manually works as expected. I have also tried including the versions file on the command line. All I can think is that version specifiers aren't carried across modules, which pretty much makes them completely useless unless you only use the built-in versions.This is quite deliberate behavior. Aside from the rationale and other solutions given in this thread, the one I prefer is to define features as functions, and then implement those functions or not depending on the configuration.
Apr 26 2012
On Friday, 27 April 2012 at 05:51:36 UTC, Walter Bright wrote:On 4/26/2012 3:09 AM, James Miller wrote:I would be with Walter on this. This is the usual behavior in any other module based language with conditional compilation support. Developers picking up D would be confused, if the behavior would be different here. -- PauloI'm trying to write a binding that has conditional sections where some features have to be enabled. I am using version statements for this. I have a list of version specs in a module by themselves. When I try to compile another module that imports this module, it acts as if the version was never specified. I have tried wrapping the specs inside a version block, then setting that from the command but that doesn't work. Setting the version manually works as expected. I have also tried including the versions file on the command line. All I can think is that version specifiers aren't carried across modules, which pretty much makes them completely useless unless you only use the built-in versions.This is quite deliberate behavior. Aside from the rationale and other solutions given in this thread, the one I prefer is to define features as functions, and then implement those functions or not depending on the configuration.
Apr 26 2012