When you say 'scenario' do you mean a GPS scenario? If not, you will
have to tell us more...
The normal way of dealing with this problem is to put the alternate
codes in different directories and adjust the compiler's source path
to pick up the appropriate file.
package body Target is
..
function Get_Position (At_Time : Time) return Position is separate;
..
then (with GNAT) the separate body will be target-get_position.adb. If
your scenarios are Real and Simulated, make subdirectories Real/ and
Simulated/ and place an appropriate implementation in each. Your GPR
might then look like
type Environment is ("Real", "Simulated");
Env : Environment := external ("ENVIRONMENT");
case Env is
when "Real" => Env_Path = "Real";
when "Simulated" => Env_Path = "Simulated";
end case;
for Source_Dirs use ..... & Env_Path;
(I haven't tested this particular example ...)
package body My_Package is
procedure Calculate_Data (My_Variable : out Some_Type) is
begin
--# if TARGET
MY_Variable = 1;
--# end If TARGET
--# if HOST
MY_Variable = 2;
--# end If HOST
end Calculate_Data;
end My_Package;
so I just discover a way to set two environments, e.g., TARGET and
HOST, and compile each one according to the GPS scenario chosen.
> type Environment is ("Real", "Simulated");
> Env : Environment := external ("ENVIRONMENT");
> case Env is
> when "Real" => Env_Path = "Real";
> when "Simulated" => Env_Path = "Simulated";
> end case;
> for Source_Dirs use ..... & Env_Path;
>
> (I haven't tested this particular example ...)
Ahem. A version which works is
project T is
type Environment is ("Real", "Simulated");
Env : Environment := external ("ENVIRONMENT");
Base_Path := (".");
Real_Path := ("Real");
Sim_Path := ("Simulated");
case Env is
when "Real" => for Source_Dirs use Base_Path & Real_Path;
when "Simulated" => for Source_Dirs use Base_Path & Sim_Path;
end case;
end T;
When GPS sees this, the Scenario view (Tools > Views > Scenario offers
ENVIRONMENT with the choices Real, Simulated.
> Yes, I mean a GPS scenario. In my case it is a bit difficult to put
> files in a different folder for each scenario, due to I need to lead
> with a some thousands of files project.
But surely not all of them are scenario dependent.
> I used to have a solution with
> included a prepost compilation, a script launched before the unit
> compilation which turned up some part of the code to a commented one,
> so in "real" compilation, that part would not be compilated. I have a
> feeling that GPS has some way to do this without external scripts, a
> more ellegant solution, maybe using some compilation directives.
> My last implementation included some like this:
with Machine_Dependent_Constants;
> package body My_Package is
> procedure Calculate_Data (My_Variable : out Some_Type) is
> begin
> --# if TARGET
> MY_Variable = 1;
My_Variable := Machine_Dependent_Constants.My_Package_Constant;
> --# end If TARGET
>
> --# if HOST
> MY_Variable = 2;
> --# end If HOST
> end Calculate_Data;
> end My_Package;
You make a subdirectory for each platform and put a corresponding
implementation of Machine_Dependent_Constants.ads there. Then you go as
Simon have suggested.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Well, creating folders for each scenario is definitely not a better
solution than using a prep script, mainly in a project with high
complexity in its architecture. Even creating new packages for doing
this (or new variables which are going to be compiled with main code),
due to requirements restrictions. But thanks even though for all
responses.
> Well, creating folders for each scenario is definitely not a better
> solution than using a prep script, mainly in a project with high
> complexity in its architecture. Even creating new packages for doing
> this (or new variables which are going to be compiled with main code),
> due to requirements restrictions. But thanks even though for all
> responses.
Gosh, how many scenario variables do you have? with how many options?
I bet they don't actually affect that many actual code units,
especially if structured the way Dmitry suggests.
You could use alternately-named bodies:
project T is
type Environment is ("Real", "Simulated");
Env : Environment := external ("ENVIRONMENT");
package Naming is
case Env is
when "Real" =>
for body ("Target.Get_Position")
use "target-get_position_real.adb";
when "Simulated" =>
for body ("Target.Get_Position")
use "target-get_position_simulated.adb";
end case;
end Naming;
end T;
--S
> Well, creating folders for each scenario is definitely not a better
> solution than using a prep script, mainly in a project with high
> complexity in its architecture.
It is better in some ways, and worse in other ways. It's certainly
possible to make a real mess of things by scattering preprocessor
commands all over the place.
Anyway, GNAT comes with a preprocessor. You can find
info in the documentation.
>... Even creating new packages for doing
> this (or new variables which are going to be compiled with main code),
> due to requirements restrictions.
I don't understand what you mean by that.
>...But thanks even though for all
> responses.
- Bob
So let me explain... they are something like 5k files, each one with
some 5k code lines. Anyway (and furthermore) by my team requirement,
any optimization, even in development/coding level, even in run-time
level, cannot be done with any creation of new files of folders. I can
use gnat prepost as well, but what we already have been doing is a
prep, so the number of steps doing this would be the same, and it does
not worth doing. What I wanted is to change some directives in the
code (which I could make a bash script for doing this easily) which
already are there, but now relate them to scenarios watches, and as I
choose Scenario "Thing" and make compile/build, GPS can identify
automatically...'this part of code do not belong to this scenario
"Thing", so I should not compile/build it with the whole project', and
just ignore it: the idea is as we were hiding the prep phase, but the
text codes do not change actually.
package Compiler is
for Default_Switches ("ada") use
("-gnateDDUMB=" & Dumb);
end Compiler;
end Fools ;
------------------------------------------------
package Fools is
#if DUMB= """Idiot""" then
a : Integer := 100;
#else
a : integer := 20;
#end if;
b : constant String := $DUMB;
end Fools ;
------------------------------------------------
with ada.Text_IO;
procedure Fools.main is
begin
Ada.Text_IO.Put_Line(B & " -> "&a'img);
end Fools.main;
------------------------------------------------
/Ugly but it works
/Per
LOL!! It was exactly what I wanted!! Thanks very much, Per.
As you say! live & learn ..
> /Ugly but it works
One thing I noticed is that GNAT doesn't see a change to the
environment variables as triggering a recompilation (well, there may
be more flags):
$ gnatmake -Pfools fools-main
gcc -c -gnateDDUMB="Fool" -I- -gnatA /Users/simon/tmp/target/fools-
main.adb
gcc -c -gnateDDUMB="Fool" -I- -gnatA /Users/simon/tmp/target/fools.ads
gnatbind -I- -x /Users/simon/tmp/target/fools-main.ali
gnatlink /Users/simon/tmp/target/fools-main.ali -o /Users/simon/tmp/
target/fools-main
$
$ gnatmake -Pfools -XDUMB="\"Idiot\"" fools-main
gnatmake: "/Users/simon/tmp/target/fools-main" up to date.
'(' <conditional statement> ')'
Mostly undocumented in the GNAT.
I have not used this type of statement. And personally I think its to close of
C-like statement instead of Ada.
-- Comes from line 565 .. 572 in "A-Text_IO.adb" for GNAT GPL 2009
if ch = EOF then
raise End_Error;
else
Item :=
(if not Is_Start_Of_Encoding (Character'Val (ch), File.WC_Method)
then Character'Val (ch)
else Get_Upper_Half_Char_Immed (Character'Val (ch), File));
end if;
or in the project file
package builder is
for Default_Switches("Ada") use ("-s");
end builder;
-------------------------------------
/Per