GNAT GPS Could not determine target to build - ada

I'm struggling with a custom project file that will build and execute, but I get this set of warnings (or errors, I'm not sure). After a Clean All and then when I click the Build -> Project -> Build All to bring up the Build All dialog box:
[2015-01-22 23:30:39] Could not determine the target to build.
[2015-01-22 23:30:39] Could not expand argument in command line: %T
[2015-01-22 23:30:39] Build command not launched.
These show up (in red text) in the Messages window before I click Execute to begin the build. When I click Execute, the build completes successfully and the program runs.
The Build All dialog has this in the options dialog:
%builder %eL -P%PP %X -k -s -d
What does this mean and why is it doing this?
If it would help, here is the project file:
project LogBuffer01 is
for Source_Dirs use ("src", "src\utilities");
for Object_Dir use "obj";
for Exec_Dir use "exe";
for Main use ("abt_log_buffer_main_b.ada");
package Naming is
for Spec_Suffix ("ada") use "_s.ada";
for Body_Suffix ("ada") use "_b.ada";
for Spec ("abt_mirror_specs") use "abt_mirror_specs_s.ada";
for Spec ("abt_log_buffer_types") use "abt_log_buffer_types_s.ada";
for Spec ("abt_log_buffer") use "abt_log_buffer_s.ada";
for Body ("abt_log_buffer") use "abt_log_buffer_b.ada";
for Spec ("abt_log_buffer_rom_acess") use "abt_log_buffer_rom_access_s.ada";
for Body ("abt_log_buffer_rom_acess") use "abt_log_buffer_rom_access_b.ada";
for Spec ("screen_output") use "screen_output_s.ada";
for Body ("screen_output") use "screen_output_b.ada";
end Naming;
package Pretty_Printer is
for Default_Switches ("ada") use ("-i5");
end Pretty_Printer;
package Compiler is
for Default_Switches ("ada") use ("-gnat83");
end Compiler;
package Builder is
for Default_Switches ("ada") use ("");
end Builder;
package Check is
for Default_Switches ("ada") use ("-d");
end Check;
end LogBuffer01;

The meanings for the builder are defined here. There's no point in me translating your command string, suffice to say that %builder translates to gnatmake because you only compile Ada. gnatmake's switches are described here.
BTW, I have this for package Builder:
for Default_Switches ("ada") use ("-g", "-C", "-s");
but in another properly-working project I have
for Default_Switches ("ada") use ();

Related

How is Ada and GPR supposed to handle conditional compilation? [duplicate]

I have a Gnat/Gprbuild project with several build configurations. I have a main source file and an secondary ads file which the main source file includes:
with Secondary_File; use Secondary_File;
The problem is that in each configuration, the secondary file has a different name. For example, it may be called Secondary_File_1.ads for one config and Secondary_File_2.ads for another. This makes it impossible to use the above with statement.
In C, I would do something like this:
#ifdef BUILD_CFG_1
#include "secondary_file_1.h"
#else
#include "secondary_file_2.h"
#endif
Is there a clever way to do something like this in ADA, using the Gprbuild system?
Many purists reject the idea of preprocessing, but it’s possible using GNAT.
You can include this in a GPR-based build environment by writing your source, e.g. main.adb, like so:
with Secondary_File_$NUMBER;
procedure Main is
begin
null;
end Main;
(observe the $NUMBER) and the project file like so:
project Prj is
for Main use ("main.adb");
-- Configurations
type Config_Type is ("config_1", "config_2");
-- Which one? (default is "config_1")
Config : Config_Type := external ("CONFIG", "config_1");
package Compiler is
case Config is
when "config_1" =>
for Switches ("main.adb") use ("-gnateDNUMBER=1");
when "config_2" =>
for Switches ("main.adb") use ("-gnateDNUMBER=2");
end case;
end Compiler;
end Prj;
Compiling gives
$ gprbuild -Pprj
Compile
[Ada] main.adb
main.adb:1:06: error: file "secondary_file_1.ads" not found
gprbuild: *** compilation phase failed
(the compilation looked for secondary_file_1.ads)
$ gprbuild -Pprj -XCONFIG=config_2
Compile
[Ada] main.adb
main.adb:1:06: error: file "secondary_file_2.ads" not found
gprbuild: *** compilation phase failed
(the compilation looked for secondary_file_2.ads)
A small variation on the answer of Simon Wright is one that uses a Naming package and Spec attributes in the GPRbuild file. This variation is useful when file names are different, but package names are the same: Secondary_File. So, not sure if this works in your case.
main.adb
with Ada.Text_IO;
with Secondary_File;
procedure Main is
begin
Ada.Text_IO.Put_Line (Secondary_File.Foo);
end Main;
secondary_file_1.ads
package Secondary_File is
Foo : constant String := "Package 1";
end Secondary_File;
secondary_file_2.ads
package Secondary_File is
Foo : constant String := "Package 2";
end Secondary_File;
prj.gpr
project Prj is
for Main use ("main.adb");
for Source_Dirs use ("src/**");
for Object_Dir use "obj";
type Config_Type is ("config_1", "config_2");
Config : Config_Type := external ("CONFIG", "config_1");
package Naming is
case Config is
when "config_1" =>
for Spec ("Secondary_File") use "secondary_file_1.ads";
when "config_2" =>
for Spec ("Secondary_File") use "secondary_file_2.ads";
end case;
end Naming;
end Prj;
output (compiler)
$ gprbuild -Pprj -XCONFIG=config_1 && ./obj/main
Compile
[Ada] main.adb
[Ada] secondary_file_1.ads
Bind
[gprbind] main.bexch
[Ada] main.ali
Link
[link] main.adb
Package 1
$ gprbuild -Pprj -XCONFIG=config_2 && ./obj/main
Compile
[Ada] main.adb
[Ada] secondary_file_2.ads
Bind
[gprbind] main.bexch
[Ada] main.ali
Link
[link] main.adb
Package 2
Bouncing on Simon's answer
Many purists reject the idea of preprocessing
And a purist's answer would be: use GPR project files, they offer the "scenario variables" feature that should do exactly what you want, without having to rename files or rely on some preprocessing step.
I guess Secondary_File.ads is unique (interface/contract), so you put each Secondary_File.adb in its own folder (distinct implementations).
Then its easy to adapt the GPR source_dir/source_files list according to a scenario variable. The variable can be set in the GnatStudio IDE, in an env var, and in a command line flag.
So you could have this folder tree:
src
|-- main.adb
|-- Secondary_File.ads
|-- implA
|-- Secondary_File.adb
|-- implB
|-- Secondary_File.adb
|-- implC
|-- Secondary_File.adb
Then use this GPR file my_project.gpr:
project my_project is
-- enum value shall match folders
type Secondary_Impl is ("implA", "implB", "implC");
the_secondary_impl_val : Secondary_Impl := external("secondary_impl_env_var", "implA"); -- gprbuild will look for env var if any, otherwise defaults to implA
for Source_Dirs use ("src", "src/" & the_secondary_impl_val );
-- other useful settings : obj dir, compiler/linker switches etc.
-- ...
end my_project;
All you have to do is then build using gpr build:
# build with impl A
gprbuild -Pmy_project.gpr -Xsecondary_impl_env_var=implA
# build with impl C
gprbuild -Pmy_project.gpr -Xsecondary_impl_env_var=implC
or even :
# bash commands, syntax to set env var depends on the OS/shell
secondary_impl_env_var=implB
gprbuild -Pmy_project.gpr
Depending on your specific software, you may also consider object oriented design patterns that can help achieve a similar result in some cases.
If some of the files are different then why not have two different .gpr configuration files? You can separate the different code into different directories and have a third directory for common code and then specify in the .gpr in a block like this
for Source_Dirs use ("main_directory",
"common_code_directory");
and this
for Source_Dirs use ("secondary_directory",
"common_code_directory");
Now you have different configurations in the same project and can build either one. You can even go further and create common ada spec files (.1.ada) that contain shared functions between the two configuration but have two different ada body files (.2.ada) that behave differently.

Ada Gnat project which includes differently-named files for different build configurations

I have a Gnat/Gprbuild project with several build configurations. I have a main source file and an secondary ads file which the main source file includes:
with Secondary_File; use Secondary_File;
The problem is that in each configuration, the secondary file has a different name. For example, it may be called Secondary_File_1.ads for one config and Secondary_File_2.ads for another. This makes it impossible to use the above with statement.
In C, I would do something like this:
#ifdef BUILD_CFG_1
#include "secondary_file_1.h"
#else
#include "secondary_file_2.h"
#endif
Is there a clever way to do something like this in ADA, using the Gprbuild system?
Many purists reject the idea of preprocessing, but it’s possible using GNAT.
You can include this in a GPR-based build environment by writing your source, e.g. main.adb, like so:
with Secondary_File_$NUMBER;
procedure Main is
begin
null;
end Main;
(observe the $NUMBER) and the project file like so:
project Prj is
for Main use ("main.adb");
-- Configurations
type Config_Type is ("config_1", "config_2");
-- Which one? (default is "config_1")
Config : Config_Type := external ("CONFIG", "config_1");
package Compiler is
case Config is
when "config_1" =>
for Switches ("main.adb") use ("-gnateDNUMBER=1");
when "config_2" =>
for Switches ("main.adb") use ("-gnateDNUMBER=2");
end case;
end Compiler;
end Prj;
Compiling gives
$ gprbuild -Pprj
Compile
[Ada] main.adb
main.adb:1:06: error: file "secondary_file_1.ads" not found
gprbuild: *** compilation phase failed
(the compilation looked for secondary_file_1.ads)
$ gprbuild -Pprj -XCONFIG=config_2
Compile
[Ada] main.adb
main.adb:1:06: error: file "secondary_file_2.ads" not found
gprbuild: *** compilation phase failed
(the compilation looked for secondary_file_2.ads)
A small variation on the answer of Simon Wright is one that uses a Naming package and Spec attributes in the GPRbuild file. This variation is useful when file names are different, but package names are the same: Secondary_File. So, not sure if this works in your case.
main.adb
with Ada.Text_IO;
with Secondary_File;
procedure Main is
begin
Ada.Text_IO.Put_Line (Secondary_File.Foo);
end Main;
secondary_file_1.ads
package Secondary_File is
Foo : constant String := "Package 1";
end Secondary_File;
secondary_file_2.ads
package Secondary_File is
Foo : constant String := "Package 2";
end Secondary_File;
prj.gpr
project Prj is
for Main use ("main.adb");
for Source_Dirs use ("src/**");
for Object_Dir use "obj";
type Config_Type is ("config_1", "config_2");
Config : Config_Type := external ("CONFIG", "config_1");
package Naming is
case Config is
when "config_1" =>
for Spec ("Secondary_File") use "secondary_file_1.ads";
when "config_2" =>
for Spec ("Secondary_File") use "secondary_file_2.ads";
end case;
end Naming;
end Prj;
output (compiler)
$ gprbuild -Pprj -XCONFIG=config_1 && ./obj/main
Compile
[Ada] main.adb
[Ada] secondary_file_1.ads
Bind
[gprbind] main.bexch
[Ada] main.ali
Link
[link] main.adb
Package 1
$ gprbuild -Pprj -XCONFIG=config_2 && ./obj/main
Compile
[Ada] main.adb
[Ada] secondary_file_2.ads
Bind
[gprbind] main.bexch
[Ada] main.ali
Link
[link] main.adb
Package 2
Bouncing on Simon's answer
Many purists reject the idea of preprocessing
And a purist's answer would be: use GPR project files, they offer the "scenario variables" feature that should do exactly what you want, without having to rename files or rely on some preprocessing step.
I guess Secondary_File.ads is unique (interface/contract), so you put each Secondary_File.adb in its own folder (distinct implementations).
Then its easy to adapt the GPR source_dir/source_files list according to a scenario variable. The variable can be set in the GnatStudio IDE, in an env var, and in a command line flag.
So you could have this folder tree:
src
|-- main.adb
|-- Secondary_File.ads
|-- implA
|-- Secondary_File.adb
|-- implB
|-- Secondary_File.adb
|-- implC
|-- Secondary_File.adb
Then use this GPR file my_project.gpr:
project my_project is
-- enum value shall match folders
type Secondary_Impl is ("implA", "implB", "implC");
the_secondary_impl_val : Secondary_Impl := external("secondary_impl_env_var", "implA"); -- gprbuild will look for env var if any, otherwise defaults to implA
for Source_Dirs use ("src", "src/" & the_secondary_impl_val );
-- other useful settings : obj dir, compiler/linker switches etc.
-- ...
end my_project;
All you have to do is then build using gpr build:
# build with impl A
gprbuild -Pmy_project.gpr -Xsecondary_impl_env_var=implA
# build with impl C
gprbuild -Pmy_project.gpr -Xsecondary_impl_env_var=implC
or even :
# bash commands, syntax to set env var depends on the OS/shell
secondary_impl_env_var=implB
gprbuild -Pmy_project.gpr
Depending on your specific software, you may also consider object oriented design patterns that can help achieve a similar result in some cases.
If some of the files are different then why not have two different .gpr configuration files? You can separate the different code into different directories and have a third directory for common code and then specify in the .gpr in a block like this
for Source_Dirs use ("main_directory",
"common_code_directory");
and this
for Source_Dirs use ("secondary_directory",
"common_code_directory");
Now you have different configurations in the same project and can build either one. You can even go further and create common ada spec files (.1.ada) that contain shared functions between the two configuration but have two different ada body files (.2.ada) that behave differently.

Ada gprbuild hangs on initialization

I have no idea why suddenly my gprbuild is getting stuck. Here's a pretty straightforward way to replicate what I'm seeing:
mkdir test
mkdir build
printf 'with Ada.Text_IO; use Ada.Text_IO;\nprocedure Main is begin Put_Line ("Hello, World!"); end Main;' > test/main.adb
printf 'project Test is\n for Source_Dirs use ("test");\n for Object_Dir use "build";\n for Exec_Dir use ".";\n for Main use ("main.adb");\n package Builder is\n for Executable ("main.adb") use "host";\n end Builder;\nend Test;' > test.gpr
gprbuild -Ptest # This hangs forever
Contents of files after executing:
test/main.adb
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is begin Put_Line ("Hello, World!"); end Main;
test.gpr
project Test is
for Source_Dirs use ("test");
for Object_Dir use "build";
for Exec_Dir use ".";
for Main use ("main.adb");
package Builder is
for Executable ("main.adb") use "host";
end Builder;
end Test;
The result is no output whatsoever and the process has to be killed with ^C.
I ran it again with the -v flag and found that it hanged on gprconfig --batch -o /some/directory/src/build/GNAT-TEMP-000001.TMP --target=x86_64-linux --config=ada,,. The results of env are:
HADOOP_LOG_DIR=/tmp/hadoop/log
LANG=en_CA.utf8
DISPLAY=:0
COLORTERM=truecolor
LCLIMPORTDIR=/usr/share/splint/imports
MOZ_PLUGIN_PATH=/usr/lib/mozilla/plugins
HADOOP_SLAVES=/etc/hadoop/slaves
TERMINAL=xfce4-terminal
XDG_VTNR=1
XDG_SESSION_ID=c1
USER=user
GRADLE_HOME=/usr/share/java/gradle
PWD=/home/user
HOME=/home/user
HADOOP_CONF_DIR=/etc/hadoop
SPARK_HOME=/opt/apache-spark
arch=x86_64
MAIL=/var/spool/mail/user
VISUAL=gvim
WINDOWPATH=1
TERM=xterm-termite
SHELL=/bin/bash
VTE_VERSION=4803
HADOOP_PID_DIR=/tmp/hadoop/run
XDG_SEAT=seat0
SHLVL=3
WINDOWID=71303171
LOGNAME=user
DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
XDG_RUNTIME_DIR=/run/user/1000
XAUTHORITY=/home/user/.Xauthority
ANT_HOME=/usr/share/apache-ant
LARCH_PATH=/usr/share/splint/lib
PATH=/home/user/bin:/usr/lib/hardening-wrapper/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/opt/android-sdk/platform-tools:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/home/user/.gem/ruby/2.4.0/bin
_=/usr/bin/env
I'm wondering if something is wrong with my GPR install? or perhaps my environment variables.
It turns out the problem was having too much in my PATH. gprbuild was looking through all the directories and trying some long running commands to see if they were the correct compilers.
Thanks to Jean-François Fabre for suggesting it.

SBT: Add dependencies to project at runtime

There is sbt project declaration
lazy val myProject = (Project("myProject", file("someRoot"))
enablePlugins ...
settings (...)
It has taskKey that extracts some dependencies to file system.
My problem is that for the moment of loading SBT I can't determine all the dependencies, it could be done only after private Command Alias is executed
addCommandAlias("resolveDependencies", "; resolveDependenciesTask; TODO: update myProject dependencies and reload it")
Is there anyway to do that?
Actually, disregard my comment on your question. You can use a command to modify the state of the build, so after you run it, the changes it made stay.
Something along these lines:
// in your build.sbt
commands += Command.command("yourCustomCommand")(state =>
Project.extract(state).append(
Seq(libraryDependencies += // settings you want to modify
"com.lihaoyi" % "ammonite-repl" % "0.5.7" cross CrossVersion.full),
state))
Then call it with sbt yourCustomCommand.
The state instance you return from the command becomes the new state of the build, i.e. if you've added some dependencies, the build will see them.

Import GLFW function to Ada

How to import GLFW function to Ada?
Using GNAT GPS as compiler and have the following folder structure:
test.adb
test.gpr
bin
obj
libglfw3.a
lib
libglfw3.a
test.gpr
project test is
for Source_Dirs use ("");
for Main use ("test.adb");
for Object_Dir use "obj";
for Library_Dir use "lib";
for Exec_Dir use "bin";
end test;
test.adb
with Interfaces.C;
with Ada.Text_IO;
procedure test is
pragma Linker_Options("-lglfw3");
pragma Linker_Options("-lgdi32");
pragma Linker_Options("-lopengl32");
function Init return Interfaces.C.int;
pragma Import(C,Init,"glfwInit");
success : Interfaces.C.int;
begin
success := Init;
Ada.Text_IO.Put_Line(success'Img);
end test;
Compiling with gprbuild -P test.gpr and outputs:
p:/gnat/2014/bin/../libexec/gcc/i686-pc-mingw32/4.7.4/ld.exe: cannot find -lglfw3
So I was thinking when gdi32, winmm, opengl32 is found is because they are already installed on my PC. I don't know if they are needed, but just to be on the safe side. The glfw3 lib is not found so I don't know if I'm using the Linker_Option the right way or where to put the libglfw3.a file. Is there a good way to link to c libraries?
pragma Linker_Options("-lglfw3dll");
Is a bad method, It should be like below:
pragma Linker_Options("-lglfw3");
To tell the linker to use library file libglfw3.a
To check libglfw3.a is in the object path used by GNAT, type the command
gnatls -v
Complete Ada binding to both GLFW2 and GLFW3 with GPR project files are available at OpenGLAda currently at Github.

Resources