Skip to content

Commit f3b26c3

Browse files
committed
Merge branch 'leo/152-setup_shared' into 'master'
Do not build a shared version of gnatcov_rts if there is no shared Ada runtime available See merge request eng/das/cov/gnatcoverage!322 We generally do not provide a shared version of the runtime for light runtimes, even though the platform might support it (native, qnx). As such, relying on the `Library_Support` attribute is not enough to determine whether we can actually build a shared `gnatcov_rts`. Instead, look for the presence of a shared Ada runtime to determine if we should attempt it. Part of eng/das/cov/gnatcoverage#152
2 parents 348b95a + b4b1651 commit f3b26c3

File tree

5 files changed

+229
-15
lines changed

5 files changed

+229
-15
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
with Ada.Text_IO; use Ada.Text_IO;
2+
3+
procedure Main is
4+
begin
5+
Put_Line ("Hello world!");
6+
end Main;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
!native DEAD Test requires both shared lib support and available light runtime
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
"""
2+
Check that "gnatcov setup" does not try to build a shared version of the
3+
coverage runtime when the Ada runtime is not available as a shared library.
4+
5+
This is the case for all of our light runtimes: even though the platform might
6+
support them, we generally don't build the shared version of the runtime.
7+
"""
8+
9+
import os
10+
11+
from SCOV.instr import xcov_convert_base64, xcov_instrument
12+
from SCOV.minicheck import check_xcov_reports
13+
from SUITE.context import thistest
14+
from SUITE.control import env
15+
from SUITE.cutils import Wdir, contents_of
16+
from SUITE.tutils import (
17+
exepath_to,
18+
gprfor,
19+
run_and_log,
20+
run_cov_program,
21+
xcov,
22+
)
23+
from SUITE.gprutils import GPRswitches
24+
25+
tmp = Wdir("tmp_")
26+
27+
# Name of the installed runtime project, to avoid conflict with the one setup
28+
# by the testing infrastructure.
29+
rt_prj = "rt_prj"
30+
31+
# Installation directory for the instrumentation runtime project and directory
32+
# for the project path.
33+
rt_install_dir = os.path.abspath("install")
34+
rt_path_dir = os.path.join(rt_install_dir, "share", "gpr")
35+
36+
prj = gprfor(
37+
mains=["main.adb"],
38+
objdir="obj",
39+
srcdirs=[".."],
40+
extra=' for Runtime ("Ada") use "light";',
41+
)
42+
43+
gprsw = GPRswitches(root_project=prj)
44+
45+
light_log = "setup_light.log"
46+
47+
# Setup the coverage runtime for a light Ada runtime. Disable the automatic
48+
# passing of --config / --target / --rts as we are doing something custom.
49+
xcov(
50+
[
51+
"setup",
52+
"--RTS=light",
53+
f"--install-name={rt_prj}",
54+
f"--prefix={rt_install_dir}",
55+
"-v",
56+
],
57+
out=light_log,
58+
auto_target_args=False,
59+
auto_config_args=False,
60+
)
61+
62+
thistest.fail_if(
63+
"Library support: STATIC_ONLY" not in contents_of(light_log),
64+
"Incorrect library support for light runtime",
65+
)
66+
67+
# Make this install available to GPR tools
68+
env.add_search_path("GPR_PROJECT_PATH", rt_path_dir)
69+
70+
# As we want to override the config generated for the testsuite, we have to
71+
# manually re-do all the coverage workflow to ensure no "--config" argument is
72+
# used in the process.
73+
74+
xcov_instrument(
75+
gprsw,
76+
covlevel="stmt",
77+
dump_channel="base64-stdout",
78+
dump_trigger="main-end",
79+
runtime_project=rt_prj,
80+
auto_config_args=False,
81+
auto_target_args=False,
82+
)
83+
84+
build_log = "gprbuild.log"
85+
86+
p = run_and_log(
87+
cmds=[
88+
"gprbuild",
89+
f"-P{prj}",
90+
f"--implicit-with={rt_prj}",
91+
"--src-subdirs=gnatcov-instr",
92+
],
93+
output=build_log,
94+
env=env.environ,
95+
)
96+
97+
thistest.fail_if(p.status != 0, "GPRbuild exit in error")
98+
99+
run_log = "run.log"
100+
101+
# Ignore exit status as there's no way with a light runtime to set the exit
102+
# status to 0.
103+
run_cov_program(
104+
exepath_to ("main"),
105+
out=run_log,
106+
register_failure=False,
107+
)
108+
109+
main_srctrace = "main.srctrace"
110+
111+
xcov_convert_base64(run_log, main_srctrace)
112+
113+
xcov(
114+
[
115+
"coverage",
116+
f"-P{prj}",
117+
"-cstmt",
118+
"-axcov",
119+
main_srctrace,
120+
]
121+
)
122+
123+
check_xcov_reports("*.xcov", {"main.adb.xcov": {"+": {5}}}, cwd="obj")
124+
125+
thistest.result()

tools/gnatcov/setup_rts.adb

Lines changed: 92 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ with GPR2.Containers;
3232
with GPR2.Log;
3333
with GPR2.Path_Name;
3434
with GPR2.Project.Attribute;
35+
with GPR2.Project.Attribute_Index;
3536
with GPR2.Project.Configuration;
3637
with GPR2.Project.Registry.Attribute;
3738
with GPR2.Project.Tree;
@@ -169,6 +170,11 @@ package body Setup_RTS is
169170
-- project to install. Use a filename that will match the Install'Artifacts
170171
-- attribute in the runtime project file.
171172

173+
function Has_Shared_Lib
174+
(RTS_Dir : String; Shared_Lib_Ext : String) return Boolean;
175+
-- Return whether there is any file with extension Shared_Lib_Ext in the
176+
-- directory RTS_Dir/adalib.
177+
172178
------------------
173179
-- Load_Project --
174180
------------------
@@ -491,23 +497,64 @@ package body Setup_RTS is
491497
end;
492498
end if;
493499

494-
-- Query the support for libraries in this configuration. When GPRconfig
495-
-- fails to find the toolchain for the requested target/RTS, it only
496-
-- emits warnings (no Invalid_Project exception raised in the call to
497-
-- Load above). In this case, we reach this point and have an empty
498-
-- string for the Library_Support attribute.
500+
-- First, determine what kind of library is supported by the current
501+
-- target / RTS configuration. If we have full library support, still
502+
-- try to determine if we have access to a shared Ada runtime as it is
503+
-- not always available.
504+
--
505+
-- To do this, we search in the <Runtime_Dir>/adalib directory any file
506+
-- with a <Shared_Library_Suffix> extension. If we can't find anything
507+
-- then assume only static libraries are supported.
508+
--
509+
-- If GPRconfig fails to find a toolchain, it only emits warnings (no
510+
-- Invalid_Project exception raise in the call to Load above), so when
511+
-- reaching this point, assume empty strings for all the attributes,
512+
-- (and thus no library support).
499513

500514
declare
501-
Attr_Id : constant GPR2.Q_Attribute_Id :=
502-
GPR2.Project.Registry.Attribute.Library_Support;
503-
Attr : constant GPR2.Project.Attribute.Object :=
504-
Prj.Configuration.Corresponding_View.Attribute (Attr_Id);
505-
LS : constant String :=
506-
(if Attr.Is_Defined
507-
then String (Attr.Value.Text)
508-
else "");
515+
function Config_Attribute
516+
(Id : GPR2.Q_Attribute_Id;
517+
Index : GPR2.Project.Attribute_Index.Object :=
518+
GPR2.Project.Attribute_Index.Undefined) return String;
519+
-- Return the string value for the attribute denoted by Id, at Index.
520+
-- If the attribute value is not defined, return the empty string.
521+
522+
----------------------
523+
-- Config_Attribute --
524+
----------------------
525+
526+
function Config_Attribute
527+
(Id : GPR2.Q_Attribute_Id;
528+
Index : GPR2.Project.Attribute_Index.Object :=
529+
GPR2.Project.Attribute_Index.Undefined) return String
530+
is
531+
Attr : constant GPR2.Project.Attribute.Object :=
532+
Prj.Configuration.Corresponding_View.Attribute (Id, Index);
533+
begin
534+
return (if Attr.Is_Defined then String (Attr.Value.Text) else "");
535+
end Config_Attribute;
536+
537+
Lib_Support_Str : constant String :=
538+
Config_Attribute (GPR2.Project.Registry.Attribute.Library_Support);
539+
540+
RTS_Dir : constant String :=
541+
Config_Attribute
542+
(GPR2.Project.Registry.Attribute.Runtime_Dir,
543+
Index =>
544+
GPR2.Project.Attribute_Index.Create (GPR2.Ada_Language));
545+
546+
Shared_Lib_Ext : constant String :=
547+
Config_Attribute
548+
(GPR2.Project.Registry.Attribute.Shared_Library_Suffix);
509549
begin
510-
Lib_Support := Library_Support'Value (LS);
550+
Lib_Support := Library_Support'Value (Lib_Support_Str);
551+
552+
if Lib_Support = Full
553+
and then not Has_Shared_Lib (RTS_Dir, Shared_Lib_Ext)
554+
then
555+
Lib_Support := Static_Only;
556+
end if;
557+
511558
exception
512559
when Constraint_Error =>
513560
Fatal_Error ("Cannot get library support for this configuration");
@@ -1114,4 +1161,35 @@ package body Setup_RTS is
11141161
return Had_Warnings;
11151162
end Check_RTS_Profile;
11161163

1164+
--------------------
1165+
-- Has_Shared_Lib --
1166+
--------------------
1167+
1168+
function Has_Shared_Lib
1169+
(RTS_Dir : String; Shared_Lib_Ext : String) return Boolean
1170+
is
1171+
Lib_Dir_Search : Search_Type;
1172+
begin
1173+
if not Exists (RTS_Dir) then
1174+
return False;
1175+
end if;
1176+
1177+
Start_Search
1178+
(Lib_Dir_Search,
1179+
Directory =>
1180+
RTS_Dir & GNAT.OS_Lib.Directory_Separator & "adalib",
1181+
Pattern => "*" & Shared_Lib_Ext,
1182+
Filter =>
1183+
(Ordinary_File => True, others => False));
1184+
1185+
return Res : constant Boolean := More_Entries (Lib_Dir_Search) do
1186+
End_Search (Lib_Dir_Search);
1187+
end return;
1188+
1189+
exception
1190+
when Ada.Directories.Name_Error =>
1191+
End_Search (Lib_Dir_Search);
1192+
return False;
1193+
end Has_Shared_Lib;
1194+
11171195
end Setup_RTS;

tools/gnatcov/subprocesses.adb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ package body Subprocesses is
106106
if Success then
107107
Put_Line (Command & " finished");
108108
else
109-
Error (Origin_Command_Name & " failed");
109+
-- Do not use Error as this sets the exit status to Failure, but
110+
-- here we are precisely ignoring the fact that the subprocess
111+
-- failed.
112+
113+
Warning_Or_Error (Origin_Command_Name & " failed");
110114
end if;
111115
end if;
112116
end Check_Status;

0 commit comments

Comments
 (0)