comp.lang.ada
 help / color / mirror / Atom feed
* Exclude parts of a package
@ 2013-12-05 20:13 Felix Krause
  2013-12-06  1:58 ` gautier_niouzes
                   ` (6 more replies)
  0 siblings, 7 replies; 17+ messages in thread
From: Felix Krause @ 2013-12-05 20:13 UTC (permalink / raw)


In C, I have the possibility to switch parts of my code on or off with 
preprocessor defines. What would be the Ada way to do something like 
that?

I know that I can use scenario variables with gprbuild. This works well 
if I want to include or exclude whole packages (because I can include 
or exclude certain files), but it does not work if I just want to 
exclude certain subroutines from a package.

Take for example OpenCLAda: The user of the library should be able to 
choose which version of the OpenCL API he wants to use (1.0, 1.1, …). 
This choice should result in subroutines added in newer versions not 
being available.

Excluding newer functionality is vital because if the user just takes 
care about not using it, the wrapper will still link against the newer 
C functions and thus the resulting binary cannot run on a system with 
an older implementation - even though the implementation provides all 
functionality the application needs.

One approach might be to implement all functions that are not part of 
OpenCL 1.0 with "separate", place the implementation files in 
subfolders "1.1", "1.2"… and provide an implementation for older 
versions which raises an exception at runtime. But I'm not satisfacted 
with that approach because the error is already discoverable with 
knowledge available at compile-time.

Is there any better way to do it?

-- 
Felix Krause
http://flyx.org/



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-05 20:13 Exclude parts of a package Felix Krause
@ 2013-12-06  1:58 ` gautier_niouzes
  2013-12-06  7:51 ` Chris Moore
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: gautier_niouzes @ 2013-12-06  1:58 UTC (permalink / raw)


Do you want a compile-time error when the user is calling, say, a v.1.2 function X but plans to use OpenCL v.1.0 only ?
In that case you could try using, in your separate file for 1.0, either a pragma like "Unimplemented_Unit" or trigger a warning only when the function is referenced - all that might be tricky and not portable.

Or you could use the gnatprep preprocessor for that and let it spit the appropriate packages in the subfolders, one with the 1.0 functions only, one with 1.0 to 1.1, one with 1.0 to 1.2.
HTH
_________________________ 
Gautier's Ada programming 
http://sf.net/users/gdemont

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-05 20:13 Exclude parts of a package Felix Krause
  2013-12-06  1:58 ` gautier_niouzes
@ 2013-12-06  7:51 ` Chris Moore
  2013-12-06  8:04 ` playerdark
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Chris Moore @ 2013-12-06  7:51 UTC (permalink / raw)


On 05/12/2013 20:13, Felix Krause wrote:

> One approach might be to implement all functions that are not part of
> OpenCL 1.0 with "separate", place the implementation files in subfolders
> "1.1", "1.2"… and provide an implementation for older versions which
> raises an exception at runtime. But I'm not satisfacted with that
> approach because the error is already discoverable with knowledge
> available at compile-time.
>
> Is there any better way to do it?
>
Have two different spec files in those subfolders.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-05 20:13 Exclude parts of a package Felix Krause
  2013-12-06  1:58 ` gautier_niouzes
  2013-12-06  7:51 ` Chris Moore
@ 2013-12-06  8:04 ` playerdark
  2013-12-06 11:14 ` Brian Drummond
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: playerdark @ 2013-12-06  8:04 UTC (permalink / raw)


I was faced with the same problem and this here helped me solve it:
http://gcc.gnu.org/onlinedocs/gnat_ugn_unw/Preprocessing.html#Preprocessing

In short: add a switch to the compiler evocation like

-gnateDDEBUG

where "DEBUG" is the defined preprocessor value to test for, then you can write lines like the following in your code as described in that link I gave above:

     #if DEBUG or else (PRIORITY > 4) then
        bunch of declarations
     #else
        completely different bunch of declarations
     #end if; 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-05 20:13 Exclude parts of a package Felix Krause
                   ` (2 preceding siblings ...)
  2013-12-06  8:04 ` playerdark
@ 2013-12-06 11:14 ` Brian Drummond
  2013-12-06 11:14 ` Brian Drummond
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 17+ messages in thread
From: Brian Drummond @ 2013-12-06 11:14 UTC (permalink / raw)


On Thu, 05 Dec 2013 21:13:50 +0100, Felix Krause wrote:

> In C, I have the possibility to switch parts of my code on or off with
> preprocessor defines. What would be the Ada way to do something like
> that?
> 
> I know that I can use scenario variables with gprbuild. This works well
> if I want to include or exclude whole packages (because I can include or
> exclude certain files), but it does not work if I just want to exclude
> certain subroutines from a package.
> 
> Take for example OpenCLAda: The user of the library should be able to
> choose which version of the OpenCL API he wants to use (1.0, 1.1, …).
> This choice should result in subroutines added in newer versions not
> being available.

I would tend to avoid the preprocessor - even the Gnat one - if at all 
possible.

And I'm sure you will find it is possible.

The basic idea is to separate out variant functionality into different 
packages for each revision - maybe OpenCL_1_0, OpenCL_1_1, etc.

Then with/use a base package, OpenCL, in all your application code.

When you come to build the program, you have to create the package OpenCL 
appropriately : it can be as simple as:

with OpenCL_1_1;
package Open_CL renames OpenCL_1_1;

--------------------------------------------------------------------

In the MSP430 Ada compiler this approach is extended to support 450+ 
different varieties of the MSP430 embedded processor, each with a 
different set of peripherals, and the peripherals themselves vary, not 
just in register addresses but also functionality (e.g. 8 and 16 bit 
timers)

Device selection is in package CPU.ads :
with MSP.msp430g2553;
package CPU renames MSP.msp430g2553;

(Everything else - CPUs and peripherals are child packages of package MSP)
package MSP is

   pragma Pure;

   type Byte is Array(0 .. 7) of Boolean;
   Pragma Pack(Byte);
   For Byte'Size use 8;
...
end MSP;

The specific CPU package, MSP.msp430g2553; looks like

with MSP.cpu_5;
with MSP.adc10;
with MSP.port1_r_3;
...
with MSP.ta3_1;
with MSP.vectors_18;
 
package MSP.msp430g2553 is
 
   pragma Preelaborate;
 
   package cpu              renames MSP.cpu_5;
   package adc10            renames MSP.adc10;
   package port1_r          renames MSP.port1_r_3;
...
   package ta3              renames MSP.ta3_1;
   package vectors          renames MSP.vectors_18;
 
end MSP.msp430g2553;
 
as you can see, it selects the 5th variant of the CPU, the 3rd variant of 
Port 1 (a GPIO port) and the 18th variant of the interrupt vector table.
There are 450 of these in the "cpu_support/cpus" folder.

It turns out that there are 19 variants of package MSP.cpu, 5 of port1_r, 
and 84 variants of the interrupt vector table.

A vector table package looks like:

with Interfaces;  use Interfaces;    --   make unsigned_n visible 
package MSP.vectors_18 is
   pragma Preelaborate;
 
   port1_vector           : constant unsigned_16 :=    16#4#;    
   port2_vector           : constant unsigned_16 :=    16#6#;    
   adc10_vector           : constant unsigned_16 :=    16#A#;     
   timer0_a0_vector       : constant unsigned_16 :=   16#12#;   
   timer1_a1_vector       : constant unsigned_16 :=   16#18#;   
...
   nmi_vector             : constant unsigned_16 :=   16#1C#; 
   reset_vector           : constant unsigned_16 :=   16#1E#;  
 
end MSP.vectors_18;

And finally a segment of an application : 

with CPU;

procedure Watch is
   package Timer renames CPU.ta3;
   subtype TickCount is Interfaces.Unsigned_16;
   OneMinute      : constant TickCount := 1024*60;	
begin
   Timer.ccr0    := OneMinute - 1;	
... and so on.

Now I can change package CPU
with MSP.msp430g2202;
package CPU renames MSP.msp430g2202;
and recompile. 
If I have used any facilities missing in the new CPU, I find out at 
compile time. 
If the timer interrupt vector has been renamed 
   package vectors          renames MSP.vectors_28;



The upshot of this approach is that 




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-05 20:13 Exclude parts of a package Felix Krause
                   ` (3 preceding siblings ...)
  2013-12-06 11:14 ` Brian Drummond
@ 2013-12-06 11:14 ` Brian Drummond
  2013-12-06 11:41 ` Brian Drummond
  2013-12-08 20:00 ` Stephen Leake
  6 siblings, 0 replies; 17+ messages in thread
From: Brian Drummond @ 2013-12-06 11:14 UTC (permalink / raw)


On Thu, 05 Dec 2013 21:13:50 +0100, Felix Krause wrote:

> In C, I have the possibility to switch parts of my code on or off with
> preprocessor defines. What would be the Ada way to do something like
> that?
> 
> I know that I can use scenario variables with gprbuild. This works well
> if I want to include or exclude whole packages (because I can include or
> exclude certain files), but it does not work if I just want to exclude
> certain subroutines from a package.
> 
> Take for example OpenCLAda: The user of the library should be able to
> choose which version of the OpenCL API he wants to use (1.0, 1.1, …).
> This choice should result in subroutines added in newer versions not
> being available.

I would tend to avoid the preprocessor - even the Gnat one - if at all 
possible.

And I'm sure you will find it is possible.

The basic idea is to separate out variant functionality into different 
packages for each revision - maybe OpenCL_1_0, OpenCL_1_1, etc.

Then with/use a base package, OpenCL, in all your application code.

When you come to build the program, you have to create the package OpenCL 
appropriately : it can be as simple as:

with OpenCL_1_1;
package Open_CL renames OpenCL_1_1;

--------------------------------------------------------------------

In the MSP430 Ada compiler this approach is extended to support 450+ 
different varieties of the MSP430 embedded processor, each with a 
different set of peripherals, and the peripherals themselves vary, not 
just in register addresses but also functionality (e.g. 8 and 16 bit 
timers)

Device selection is in package CPU.ads :
with MSP.msp430g2553;
package CPU renames MSP.msp430g2553;

(Everything else - CPUs and peripherals are child packages of package MSP)
package MSP is

   pragma Pure;

   type Byte is Array(0 .. 7) of Boolean;
   Pragma Pack(Byte);
   For Byte'Size use 8;
...
end MSP;

The specific CPU package, MSP.msp430g2553; looks like

with MSP.cpu_5;
with MSP.adc10;
with MSP.port1_r_3;
...
with MSP.ta3_1;
with MSP.vectors_18;
 
package MSP.msp430g2553 is
 
   pragma Preelaborate;
 
   package cpu              renames MSP.cpu_5;
   package adc10            renames MSP.adc10;
   package port1_r          renames MSP.port1_r_3;
...
   package ta3              renames MSP.ta3_1;
   package vectors          renames MSP.vectors_18;
 
end MSP.msp430g2553;
 
as you can see, it selects the 5th variant of the CPU, the 3rd variant of 
Port 1 (a GPIO port) and the 18th variant of the interrupt vector table.
There are 450 of these in the "cpu_support/cpus" folder.

It turns out that there are 19 variants of package MSP.cpu, 5 of port1_r, 
and 84 variants of the interrupt vector table.

A vector table package looks like:

with Interfaces;  use Interfaces;    --   make unsigned_n visible 
package MSP.vectors_18 is
   pragma Preelaborate;
 
   port1_vector           : constant unsigned_16 :=    16#4#;    
   port2_vector           : constant unsigned_16 :=    16#6#;    
   adc10_vector           : constant unsigned_16 :=    16#A#;     
   timer0_a0_vector       : constant unsigned_16 :=   16#12#;   
   timer1_a1_vector       : constant unsigned_16 :=   16#18#;   
...
   nmi_vector             : constant unsigned_16 :=   16#1C#; 
   reset_vector           : constant unsigned_16 :=   16#1E#;  
 
end MSP.vectors_18;

And finally a segment of an application : 

with CPU;

procedure Watch is
   package Timer renames CPU.ta3;
   subtype TickCount is Interfaces.Unsigned_16;
   OneMinute      : constant TickCount := 1024*60;	
begin
   Timer.ccr0    := OneMinute - 1;	
... and so on.

Now I can change package CPU
with MSP.msp430g2202;
package CPU renames MSP.msp430g2202;
and recompile. 
If I have used any facilities missing in the new CPU, I find out at 
compile time. 
If the timer interrupt vector has been renamed 
   package vectors          renames MSP.vectors_28;



The upshot of this approach is that 


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-05 20:13 Exclude parts of a package Felix Krause
                   ` (4 preceding siblings ...)
  2013-12-06 11:14 ` Brian Drummond
@ 2013-12-06 11:41 ` Brian Drummond
  2013-12-06 20:48   ` Felix Krause
  2013-12-08 20:00 ` Stephen Leake
  6 siblings, 1 reply; 17+ messages in thread
From: Brian Drummond @ 2013-12-06 11:41 UTC (permalink / raw)


On Thu, 05 Dec 2013 21:13:50 +0100, Felix Krause wrote:

> In C, I have the possibility to switch parts of my code on or off with
> preprocessor defines. What would be the Ada way to do something like
> that?
> 
> I know that I can use scenario variables with gprbuild. This works well
> if I want to include or exclude whole packages (because I can include or
> exclude certain files), but it does not work if I just want to exclude
> certain subroutines from a package.
> 
> Take for example OpenCLAda: The user of the library should be able to
> choose which version of the OpenCL API he wants to use (1.0, 1.1, …).
> This choice should result in subroutines added in newer versions not
> being available.

I would tend to avoid the preprocessor - even the Gnat one - if at all 
possible.

The basic idea is to separate out variant functionality into different 
packages for each revision - maybe OpenCL_1_0, OpenCL_1_1, etc.

Then with/use a base package, OpenCL, in all your application code.

When you come to build the program, you create the package OpenCL 
appropriately : it can be as simple as:

with OpenCL_1_1;
package Open_CL renames OpenCL_1_1;

--------------------------------------------------------------------

In the MSP430 Ada compiler this approach is extended to support 450+ 
different varieties of the MSP430 embedded processor, each with a 
different set of peripherals, and the peripherals themselves vary, not 
just in register addresses but also functionality (e.g. 8 and 16 bit 
timers). If the OpenCL variants are in different categories such as math 
precision, number of cores, etc this sub-package approach may be useful.

A worked example:

Device selection is in package CPU.ads :
with MSP.msp430g2553;
package CPU renames MSP.msp430g2553;

(Everything else - CPUs and peripherals are child packages of package MSP)
package MSP is

   pragma Pure;

   type Byte is Array(0 .. 7) of Boolean;
   Pragma Pack(Byte);
   For Byte'Size use 8;
...
end MSP;

The specific CPU package, MSP.msp430g2553; looks like

with MSP.cpu_5;
with MSP.adc10;
with MSP.port1_r_3;
...
with MSP.ta3_1;
with MSP.vectors_18;
 
package MSP.msp430g2553 is
 
   pragma Preelaborate;
 
   package cpu              renames MSP.cpu_5;
   package adc10            renames MSP.adc10;
   package port1_r          renames MSP.port1_r_3;
...
   package ta3              renames MSP.ta3_1;
   package vectors          renames MSP.vectors_18;
 
end MSP.msp430g2553;
 
as you can see, it selects the 5th variant of the CPU, the 3rd variant of 
Port 1 (a GPIO port) and the 18th variant of the interrupt vector table.

It turns out that there are 19 variants of package MSP.cpu, 5 of port1_r, 
and 84 variants of the interrupt vector table. 

A vector table package looks like:

with Interfaces;  use Interfaces;    --   make unsigned_n visible 
package MSP.vectors_18 is
   pragma Preelaborate;
 
   port1_vector           : constant unsigned_16 :=    16#4#;    
   port2_vector           : constant unsigned_16 :=    16#6#;    
   adc10_vector           : constant unsigned_16 :=    16#A#;     
   timer0_a0_vector       : constant unsigned_16 :=   16#12#;   
   timer1_a1_vector       : constant unsigned_16 :=   16#18#;   
...
   nmi_vector             : constant unsigned_16 :=   16#1C#; 
   reset_vector           : constant unsigned_16 :=   16#1E#;  
 
end MSP.vectors_18;

And finally a fragment of an application : 
-----------------------------
with CPU;

procedure Watch is
   package Timer renames CPU.ta3;
   subtype TickCount is Interfaces.Unsigned_16;
   OneMinute      : constant TickCount := 1024*60;	
begin
   Timer.ccr0    := OneMinute - 1;	
... and so on.
-----------------------------

Now I can change package CPU
with MSP.msp430g2202;
package CPU renames MSP.msp430g2202;
and recompile. 

If I have used any facilities missing in the new CPU, I find out at 
compile time. 

If the timer interrupt vector has been renamed timer_a0_vector (as it has 
in some other CPUs) it is reported as undeclared.
Then the CPU package MSP.msp430g2202 tells me which variant of the 
interrupt vector package I am using, 
   package vectors          renames MSP.vectors_28;
and MSP.vectors_28 gives me the new name. 
Most packages are a page or so, so fairly easy to browse.

There are 450-odd CPU packages, and about 350 peripheral description 
packages (inc. 84 interrupt vector tables) so this gives pretty good 
reuse. 

In contrast, the C toolchain takes the preprocessor approach, and each 
CPU variant has its own #include file ranging from 500 to over 6000 
lines; not so easy!

The Ada packages are auto-generated from the original #includes, and 
simplify 60MB of #includes into 1.2MB of CPUs and under 5MB of peripheral 
packages.

I'm happy without the preprocessor.

If you're interested in the how, the complete example is at 
https://sourceforge.net/projects/msp430ada/

- Brian



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-06 11:41 ` Brian Drummond
@ 2013-12-06 20:48   ` Felix Krause
  2013-12-06 21:27     ` Shark8
  0 siblings, 1 reply; 17+ messages in thread
From: Felix Krause @ 2013-12-06 20:48 UTC (permalink / raw)


On 2013-12-06 11:41:50 +0000, Brian Drummond said:
> 
> I would tend to avoid the preprocessor - even the Gnat one - if at all
> possible.
> 
> The basic idea is to separate out variant functionality into different
> packages for each revision - maybe OpenCL_1_0, OpenCL_1_1, etc.
> 
> Then with/use a base package, OpenCL, in all your application code.
> 
> When you come to build the program, you create the package OpenCL
> appropriately : it can be as simple as:
> 
> with OpenCL_1_1;
> package Open_CL renames OpenCL_1_1;
> 
> [snip]

This is an interesting approach, but in my case, that would lead to 
massive code duplication because I don't really have child packages to 
choose from (same goes for having multiple spec files). I rather need 
to add or exclude subroutines of one package. Moving it to a child 
package will not work because it needs to be a primitive operation of a 
tagged type defined in the original package.

Pragma Unimplemented_Unit is interesting, using gnatprep seems to be 
even cleaner to me because it actually strips the declaration from the 
package specification. As gnatprep is pretty independent from the GNAT 
compiler, I think this is a good compromise between portability and 
clean code.

Thanks everyone!


-- 
Felix Krause
http://flyx.org/

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-06 20:48   ` Felix Krause
@ 2013-12-06 21:27     ` Shark8
  2013-12-07  8:41       ` Felix Krause
  0 siblings, 1 reply; 17+ messages in thread
From: Shark8 @ 2013-12-06 21:27 UTC (permalink / raw)


On Friday, December 6, 2013 1:48:43 PM UTC-7, Felix Krause wrote:
> 
> This is an interesting approach, but in my case, that would lead to 
> massive code duplication because I don't really have child packages to 
> choose from (same goes for having multiple spec files). I rather need 
> to add or exclude subroutines of one package. Moving it to a child 
> package will not work because it needs to be a primitive operation of a 
> tagged type defined in the original package.

Easy enough solution:
1) Define everything [all of OpenGL, or at least portion-X (X : Types, Functions, etc)] in one big package; for the current version (4.3, IIRC).*
2) Define version-packages which repeat the spec of the appropriate functions and use renames in their body.
3) Use the rename technique given by Brian.

Ex:
--------------------------------------------------

Package Main_Stuff is
  Procedure Bob;  -- Introduced in v.1.
  Procedure Tim;  -- Introduced in v.1.2.
  Procedure Dave; -- Introduced in v.1.3.
  Procedure Bill; -- Introduced in v.1.3.

private
  -- Stubs, to avoid having to provide a body.
  Procedure Bob  is null;
  Procedure Tim  is null;
  Procedure Dave is null;
  Procedure Bill is null;
end Main_Stuff.

-- Def v.1.
private with Main_Stuff;
Package Stuff_1_1 is
  Procedure Bob;
private
  Procedure Bob renames Main_stuff.Bob;
end Stuff_1_1;


-- Def v.1.2.
private with Main_Stuff;
Package Stuff_1_2 is
  Procedure Bob;
  Procedure Tim;
private
  Procedure Bob renames Main_stuff.Bob;
  Procedure Tim renames Main_Stuff.Tim;
end Stuff_1_2;

---- Brian's renaming trick:
with Stuff_1_2;
package Stuff renames Stuff_1_2;

---- Client code:
with Stuff;
procedure Do_Stuff is --....

-------------------------------------------------------------------
* In my OpenGL binding TAO-GL my plan was/is similar to this except
  the bingings query opengl for parameters and build the types from
  the results (ie NUMBER_OF_LIGHTS) via generic instantiation, then
  that would instantiate the functions (ensuring the functions) are
  not called w/ inappropriate parameters.

* TAO-GL: https://github.com/OneWingedShark/TAO-GL
  NOTE:   GitHub version at the state *before* I decided
          to make the Functions package generic.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-06 21:27     ` Shark8
@ 2013-12-07  8:41       ` Felix Krause
  2013-12-07 11:55         ` Brian Drummond
  0 siblings, 1 reply; 17+ messages in thread
From: Felix Krause @ 2013-12-07  8:41 UTC (permalink / raw)


On 2013-12-06 21:27:53 +0000, Shark8 said:

> On Friday, December 6, 2013 1:48:43 PM UTC-7, Felix Krause wrote:
>> 
>> This is an interesting approach, but in my case, that would lead to
>> massive code duplication because I don't really have child packages to
>> choose from (same goes for having multiple spec files). I rather need
>> to add or exclude subroutines of one package. Moving it to a child
>> package will not work because it needs to be a primitive operation of a
>> tagged type defined in the original package.
> 
> Easy enough solution:
> 1) Define everything [all of OpenGL, or at least portion-X (X : Types, 
> Functions, etc)] in one big package; for the current version (4.3, 
> IIRC).*
> 2) Define version-packages which repeat the spec of the appropriate 
> functions and use renames in their body.
> 3) Use the rename technique given by Brian.
> 
> Ex:
> --------------------------------------------------
> 
> Package Main_Stuff is
>   Procedure Bob;  -- Introduced in v.1.
>   Procedure Tim;  -- Introduced in v.1.2.
>   Procedure Dave; -- Introduced in v.1.3.
>   Procedure Bill; -- Introduced in v.1.3.
> 
> private
>   -- Stubs, to avoid having to provide a body.
>   Procedure Bob  is null;
>   Procedure Tim  is null;
>   Procedure Dave is null;
>   Procedure Bill is null;
> end Main_Stuff.
> 
> -- Def v.1.
> private with Main_Stuff;
> Package Stuff_1_1 is
>   Procedure Bob;
> private
>   Procedure Bob renames Main_stuff.Bob;
> end Stuff_1_1;
> 
> 
> -- Def v.1.2.
> private with Main_Stuff;
> Package Stuff_1_2 is
>   Procedure Bob;
>   Procedure Tim;
> private
>   Procedure Bob renames Main_stuff.Bob;
>   Procedure Tim renames Main_Stuff.Tim;
> end Stuff_1_2;
> 
> ---- Brian's renaming trick:
> with Stuff_1_2;
> package Stuff renames Stuff_1_2;
> 
> ---- Client code:
> with Stuff;
> procedure Do_Stuff is --....
> 
> -------------------------------------------------------------------
> * In my OpenGL binding TAO-GL my plan was/is similar to this except
>   the bingings query opengl for parameters and build the types from
>   the results (ie NUMBER_OF_LIGHTS) via generic instantiation, then
>   that would instantiate the functions (ensuring the functions) are
>   not called w/ inappropriate parameters.
> 
> * TAO-GL: https://github.com/OneWingedShark/TAO-GL
>   NOTE:   GitHub version at the state *before* I decided
>           to make the Functions package generic.

But this would compile all implementation code regardless of the 
version the user requested. Let's say in your example, the actual 
implementation of Tim imports a C function. Even if I compile for 
version 1., the body of Tim will still be compiled, so the resulting 
binary would still link against the backend C function that is wrapped 
by Tim. So to execute the binary, I'd need C library version that 
supports Tim even though I don't use it. Or do I see this wrong?

Side note: I'm talking about OpenCL, not OpenGL. In OpenGL, it is 
possible to query pointers to all functions introduced in 1.2 or later 
at runtime, so you can react to a situation where required 
functionality isn't available (disable features or display an error 
message). This is what I do in my OpenGL binding. In OpenCL however, 
this is not possible.

-- 
Felix Krause
http://flyx.org/



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-07  8:41       ` Felix Krause
@ 2013-12-07 11:55         ` Brian Drummond
  0 siblings, 0 replies; 17+ messages in thread
From: Brian Drummond @ 2013-12-07 11:55 UTC (permalink / raw)


On Sat, 07 Dec 2013 09:41:33 +0100, Felix Krause wrote:

> On 2013-12-06 21:27:53 +0000, Shark8 said:
> 
>> On Friday, December 6, 2013 1:48:43 PM UTC-7, Felix Krause wrote:
>>> 
>>> This is an interesting approach, but in my case, that would lead to
>>> massive code duplication 

>> Easy enough solution:
>> 1) Define everything [all of OpenGL, or at least portion-X (X : Types,
>> Functions, etc)] in one big package; for the current version (4.3,
>> IIRC).*
>> 2) Define version-packages which repeat the spec of the appropriate
>> functions and use renames in their body.
>> 3) Use the rename technique given by Brian.

>> Package Main_Stuff is
>>   Procedure Bob;  -- Introduced in v.1.
>>   Procedure Tim;  -- Introduced in v.1.2.
>>   Procedure Dave; -- Introduced in v.1.3.
>>   Procedure Bill; -- Introduced in v.1.3.

> But this would compile all implementation code regardless of the version
> the user requested. Let's say in your example, the actual implementation
> of Tim imports a C function. Even if I compile for version 1., the body
> of Tim will still be compiled, so the resulting binary would still link
> against the backend C function that is wrapped by Tim. So to execute the
> binary, I'd need C library version that supports Tim even though I don't
> use it. Or do I see this wrong?

As I understand it, they would all be compiled, but (unless the linker is 
completely brain-dead) only the ones you use would be linked.

So Tim's functions would be verified as syntactically correct (or you'd 
have to fix them!) even though your latest changes were only to upgrade 
v1. And I see that as a Good Thing since it reduces surprises for v1.2 
users of the package...

But Tim shouldn't be linked into the executable; therefore its dependency 
on the C library should also be eliminated. 
(This may require some linker options in the project file)

If the linker really can't do it, then I would 
(a) be surprised, and
(b) suggest refactoring the variants into different packages such that
v1_pkg is base_pkg,
v1.1_pkg is composed of base_pkg and v1.1_diff_pkg
and so on. 

- Brian

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-05 20:13 Exclude parts of a package Felix Krause
                   ` (5 preceding siblings ...)
  2013-12-06 11:41 ` Brian Drummond
@ 2013-12-08 20:00 ` Stephen Leake
  2013-12-12 14:30   ` Marius Amado-Alves
  6 siblings, 1 reply; 17+ messages in thread
From: Stephen Leake @ 2013-12-08 20:00 UTC (permalink / raw)


Felix Krause <usenet@flyx.org> writes:

> Take for example OpenCLAda: The user of the library should be able to
> choose which version of the OpenCL API he wants to use (1.0, 1.1, …).
> This choice should result in subroutines added in newer versions not
> being available.

Use a configuration management system (I recommend monotone) to maintain
versions of the Ada code that match the versions of OpenCL.

When you fix a bug in version 1.0, propagate the changes to 1.1 ...

That mimics the actual development of OpenCL; that's what CM systems are
for.

This is "massive code duplication", but it is manageable with any
decent CM system.

-- 
-- Stephe


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-08 20:00 ` Stephen Leake
@ 2013-12-12 14:30   ` Marius Amado-Alves
  2013-12-13 13:16     ` Felix Krause
  2013-12-13 16:17     ` Stephen Leake
  0 siblings, 2 replies; 17+ messages in thread
From: Marius Amado-Alves @ 2013-12-12 14:30 UTC (permalink / raw)


> When you fix a bug in version 1.0, propagate the changes to 1.1 ...

Somehow I find this strange. Potential regressive effects in 1.1 Usually the bugs are fixed in the last version. What am I missing? Any pointers, maybe to literature, appreciated.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-12 14:30   ` Marius Amado-Alves
@ 2013-12-13 13:16     ` Felix Krause
  2013-12-13 16:17     ` Stephen Leake
  1 sibling, 0 replies; 17+ messages in thread
From: Felix Krause @ 2013-12-13 13:16 UTC (permalink / raw)


On 2013-12-12 14:30:11 +0000, Marius Amado-Alves said:

>> 
>> When you fix a bug in version 1.0, propagate the changes to 1.1 ...
> 
> Somehow I find this strange. Potential regressive effects in 1.1 
> Usually the bugs are fixed in the last version. What am I missing? Any 
> pointers, maybe to literature, appreciated.

It's a wrapper library. A bug in the wrapper may affect the branch 
linking to OpenCL v1.0, or the one linking to v1.1, or both. These 
versions belong to OpenCL API; the wrapper library is independently 
versioned.

The suggestion of using VCS to handle the problem is really good. I 
might just do that. Thanks!

-- 
Felix Krause
http://flyx.org/



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-12 14:30   ` Marius Amado-Alves
  2013-12-13 13:16     ` Felix Krause
@ 2013-12-13 16:17     ` Stephen Leake
  2014-01-02 15:06       ` Marius Amado-Alves
  2014-01-02 15:07       ` Marius Amado-Alves
  1 sibling, 2 replies; 17+ messages in thread
From: Stephen Leake @ 2013-12-13 16:17 UTC (permalink / raw)


Marius Amado-Alves <amado.alves@gmail.com> writes:

>> When you fix a bug in version 1.0, propagate the changes to 1.1 ...
>
> Somehow I find this strange. Potential regressive effects in 1.1
> Usually the bugs are fixed in the last version. What am I missing? Any
> pointers, maybe to literature, appreciated.

I assume _all_ software has bugs.

You stated that you want to distribute multiple versions of a package,
some older than others.

So you are going to get bug reports on 1.0.

You can say "upgrade to 1.x, where this is fixed". But you have to
assume there are strong reasons they have not _already_ upgraded to 1.x,
so that's not likely to be a good solution.

So you should be prepared to release 1.0.x, with bug fixes. For example,
Debian supports security releases of the most recent old Debian release;
they include fixes for security-related bugs.

Any bugs that are found in version 1.0 after 1.1 ... are released may
still exist in 1.1, or they may have been fixed.

So 1.1 ... should be examined to see if the bug is still there. In order
to avoid completely re-implementing the fix, use the CM tools to
propagate the bug fix, along with the test fix for it.

(my solution to this issue for my packages is to simply not support old
versions in any way)

-- 
-- Stephe

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-13 16:17     ` Stephen Leake
@ 2014-01-02 15:06       ` Marius Amado-Alves
  2014-01-02 15:07       ` Marius Amado-Alves
  1 sibling, 0 replies; 17+ messages in thread
From: Marius Amado-Alves @ 2014-01-02 15:06 UTC (permalink / raw)


On Friday, 13 December 2013 16:17:25 UTC, Stephen Leake  wrote:
> Marius Amado-Alves <amado.alves@gmail.com> writes:
> >> When you fix a bug in version 1.0, propagate the changes to 1.1 ...
> > Somehow I find this strange. Potential regressive effects in 1.1
> > Usually the bugs are fixed in the last version. What am I missing? Any
> > pointers, maybe to literature, appreciated.
> You stated that you want to distribute multiple versions of a package,...

I did not state that, but no worries. I understand now what was meant with "When you fix a bug in version 1.0, propagate the changes to 1.1", thanks.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Exclude parts of a package
  2013-12-13 16:17     ` Stephen Leake
  2014-01-02 15:06       ` Marius Amado-Alves
@ 2014-01-02 15:07       ` Marius Amado-Alves
  1 sibling, 0 replies; 17+ messages in thread
From: Marius Amado-Alves @ 2014-01-02 15:07 UTC (permalink / raw)


Stephen Leake  wrote: 
> Marius Amado-Alves writes: 
> >> When you fix a bug in version 1.0, propagate the changes to 1.1 ... 
> > Somehow I find this strange. Potential regressive effects in 1.1 
> > Usually the bugs are fixed in the last version. What am I missing? Any 
> > pointers, maybe to literature, appreciated. 
> You stated that you want to distribute multiple versions of a package,... 

I did not state that, but no worries. I understand now what was meant with "When you fix a bug in version 1.0, propagate the changes to 1.1", thanks. 

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2014-01-02 15:07 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-05 20:13 Exclude parts of a package Felix Krause
2013-12-06  1:58 ` gautier_niouzes
2013-12-06  7:51 ` Chris Moore
2013-12-06  8:04 ` playerdark
2013-12-06 11:14 ` Brian Drummond
2013-12-06 11:14 ` Brian Drummond
2013-12-06 11:41 ` Brian Drummond
2013-12-06 20:48   ` Felix Krause
2013-12-06 21:27     ` Shark8
2013-12-07  8:41       ` Felix Krause
2013-12-07 11:55         ` Brian Drummond
2013-12-08 20:00 ` Stephen Leake
2013-12-12 14:30   ` Marius Amado-Alves
2013-12-13 13:16     ` Felix Krause
2013-12-13 16:17     ` Stephen Leake
2014-01-02 15:06       ` Marius Amado-Alves
2014-01-02 15:07       ` Marius Amado-Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox