What command do I have to give to gnattest to make it only consider the code in my src directory (and ignore all subprojects such as the Ada Drivers Library)?
I've read this question, which says to tag every subprogram I want to test with the 'Test_Case' aspect. I'll go that route if I have to but I'd like the protection of gnattest automatically adding new test cases for new code so that I don't miss anything.
Here's my gpr file:
with "c:\Domains\ada\Ada_Drivers_Library\boards\MicroBit\microbit_zfp.gpr";
project Demo_Project is
for Runtime ("ada") use Microbit_Zfp'Runtime ("Ada");
for Target use "arm-eabi";
for Main use ("main.adb");
for Languages use ("Ada");
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Create_Missing_Dirs use "True";
package Compiler renames Microbit_Zfp.Compiler;
package Linker is
for Default_Switches ("ada") use Microbit_Zfp.Linker_Switches & ("-Wl,--print-memory-usage", "-Wl,--gc-sections", "-U__gnat_irq_trap");
end Linker;
package Ide is
for Program_Host use ":1234";
for Communication_Protocol use "remote";
for Connection_Tool use "pyocd";
end Ide;
package Prove is
for Proof_Switches ("Ada") use ("-j0");
end Prove;
package Builder is
for Switches ("ada") use ("-j0", "-s");
end Builder;
end Demo_Project;
Here's the gnattest command that GPS created (which incorrectly created tests for the ada drivers library):
arm-eabi-gnat test -Pdemo_project.gpr --tests-dir=C:\Domains\ada\demo_project\microbit\tests
Update: 2019-12-17:
Here's what I got when I ran the suggested answer:
>c:\GNAT\2019\bin\gnattest -Pdemo_project.gpr --tests-dir=tests
Could not locate exec arm-eabi-gnatls
gprconfig: can't find a toolchain for the following configuration:
gprconfig: language 'ada', target 'arm-eabi', runtime 'zfp-cortex-m0'
microbit_zfp.gpr:61:25: warning: libraries are not supported on this platform
object path not found for runtime zfp-cortex-m0
gnattest: initialization failed
Update: 2019-12-17 (2):
I made some progress by adding the "--test-case-only" flag like so and adding a test_case aspect to a single procedure in the Battery package. Here's the command I ran:
arm-eabi-gnat test -dd -PC:\Domains\ada\Demo_Project\microbit\demo_project.gpr --tests-dir=C:\Domains\ada\Demo_Project\tests --test-case-only
Gnattest was successful. I can see my Battery package in the project view for the tests. However, when I try to build and run it from GPS, I get this mess:
gprbuild --target=arm-eabi -d -PC:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\test_driver.gpr -XADL_BUILD_CHECKS=Enabled -XADL_BUILD=Debug -XTEST_DRIVER_BUILD_MODE=no-config-file C:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\test_runner.adb -largs -Wl,-Map=map.txt
Compile
[Ada] test_runner.adb
[Ada] gnattest_main_suite.adb
[Ada] battery-test_data.adb
[Ada] battery-test_data-tests.adb
battery-test_data-tests.adb:40:13: warning: pragma Restrictions (No_Exception_Propagation) in effect
battery-test_data-tests.adb:40:13: warning: this handler can never be entered, and has been removed
battery-test_data-tests.adb:53:13: warning: pragma Restrictions (No_Exception_Propagation) in effect
battery-test_data-tests.adb:53:13: warning: this handler can never be entered, and has been removed
[Ada] battery-test_data-tests-suite.adb
[Ada] gnattest_generated.ads
Bind
[gprbind] test_runner.bexch
[Ada] test_runner.ali
Link
[link] test_runner.adb
c:/gnat/2019-arm-elf/bin/../lib/gcc/arm-eabi/7.4.1/../../../../arm-eabi/bin/ld.exe: C:\Domains\ada\Ada_Drivers_Library\boards\MicroBit\obj\zfp_lib_Debug\libada_drivers_library.a(crt0.o): in function `hang':
(.text+0x40): undefined reference to `__stack_end'
c:/gnat/2019-arm-elf/bin/../lib/gcc/arm-eabi/7.4.1/../../../../arm-eabi/bin/ld.exe: (.text+0x48): undefined reference to `__data_words'
c:/gnat/2019-arm-elf/bin/../lib/gcc/arm-eabi/7.4.1/../../../../arm-eabi/bin/ld.exe: (.text+0x4c): undefined reference to `__data_load'
c:/gnat/2019-arm-elf/bin/../lib/gcc/arm-eabi/7.4.1/../../../../arm-eabi/bin/ld.exe: (.text+0x54): undefined reference to `__bss_words'
c:/gnat/2019-arm-elf/bin/../lib/gcc/arm-eabi/7.4.1/../../../../arm-eabi/bin/ld.exe: C:\Domains\ada\Ada_Drivers_Library\boards\MicroBit\obj\zfp_lib_Debug\libada_drivers_library.a(crt0.o): in function `__vectors':
(.vectors+0x0): undefined reference to `__stack_end'
c:/gnat/2019-arm-elf/bin/../lib/gcc/arm-eabi/7.4.1/../../../../arm-eabi/bin/ld.exe: C:\gnat\2019-arm-elf\arm-eabi\lib\gnat\zfp-cortex-m0\adalib\libgnat.a(s-memory.o): in function `__gnat_malloc':
s-memory.adb:(.text.__gnat_malloc+0x40): undefined reference to `__heap_end'
c:/gnat/2019-arm-elf/bin/../lib/gcc/arm-eabi/7.4.1/../../../../arm-eabi/bin/ld.exe: C:\gnat\2019-arm-elf\arm-eabi\lib\gnat\zfp-cortex-m0\adalib\libgnat.a(s-memory.o):(.data.system__memory__top+0x0): undefined reference to `__heap_start'
collect2.exe: error: ld returned 1 exit status
gprbuild: link of test_runner.adb failed
gprbuild: failed command was: c:\gnat\2019-arm-elf\bin\arm-eabi-gcc.exe test_runner.o b__test_runner.o C:\Domains\ada\Demo_Project\microbit\obj\battery.o C:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\battery-test_data.o C:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\gnattest_generated.o C:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\battery-test_data-tests.o C:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\battery-test_data-tests-suite.o C:\Domains\
ada\Demo_Project\microbit\obj\gnattest\harness\gnattest_main_suite.o C:\Domains\ada\Ada_Drivers_Library\boards\MicroBit\obj\zfp_lib_Debug\libada_drivers_library.a C:\gnat\2019-arm-elf\arm-eabi\zfp-cortex-m0\lib\aunit\libaunit.a -g -Wl,-Map=map.txt -LC:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\ -LC:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\ -LC:\gnat\2019-arm-elf\arm-eabi\zfp-cortex-m0\lib\aunit\ -LC:\Domains\ada\Demo_Project\microbit\obj\ -LC:\Domains\ada\Ada_Drive
rs_Library\boards\MicroBit\obj\zfp_lib_Debug\ -LC:\gnat\2019-arm-elf\arm-eabi\lib\gnat\zfp-cortex-m0\adalib\ -static-libgcc C:\gnat\2019-arm-elf\arm-eabi\lib\gnat\zfp-cortex-m0\adalib\libgnat.a -Wl,-LC:\gnat\2019-arm-elf\arm-eabi\lib\gnat\zfp-cortex-m0\/adalib -nostartfiles -nolibc -mlittle-endian -mthumb -msoft-float -mcpu=cortex-m0 -o test_runner
[2019-12-17 10:47:38] process exited with status 4, 100% (174/174), elapsed time: 03.00s
Traceback (most recent call last):
File "C:\GNAT\2019\share\gps\support\ui\workflows\__init__.py", line 351, in internal_run_as_wf
r = workflow(*args, **kwargs)
File "C:\GNAT\2019\share\gps\plug-ins\memory_usage_providers\ld.py", line 242, in async_fetch_memory_usage_data
visitor.on_memory_usage_data_fetched(regions, sections, modules)
GPS.Unexpected_Exception: unexpected internal exception raised CONSTRAINT_ERROR : Memory_Usage_Views.Memory_Region_Description_Maps.Reference: key not in map
[C:\GNAT\2019\bin\gps.exe]
0x21a541b
0x197c5b5
[C:\GNAT\2019\bin\gps.libgnatcoll_python\libgnatcoll_python.dll]
0xc7d79bc at ???
[C:\GNAT\2019\bin\gps.libgnatcoll_python\libgnatcoll_python.dll]
0xc7d8b16 at ???
[C:\GNAT\2019\bin\gps.python27\python27.dll]
0x1e0c3d54
0x1e113eb9
0x1e114778
0x1e117ee2
0x1e119780
0x1e0b5831
0x1e08dae3
0x1e1141cb
0x1e117fbd
0x1e119780
0x1e0b5831
0x1e08dae3
0x1e09bfcf
0x1e08dae3
[C:\GNAT\2019\bin\gps.libgnatcoll_python\libgnatcoll_python.dll]
0xc7e459f at ???
[C:\GNAT\2019\bin\gps.libgnatcoll_python\libgnatcoll_python.dll]
0xc7e55e0 at ???
[C:\GNAT\2019\bin\gps.libgnatcoll_python\libgnatcoll_python.dll]
0xc7e5833 at ???
[C:\GNAT\2019\bin\gps.libgnatcoll\libgnatcoll.dll]
0xc08dbb4 at ???
[C:\GNAT\2019\bin\gps.exe]
0x197ecf7
0x1975d5f
0x10687c2
0x14ba66a
0x145cc61
0x15e0780
0xfcfa72
0x10b4114
0x10b4672
0x10b7893
0x10b7cf7
0xe30b4c
0xe31022
0xe2deaa
[C:\GNAT\2019\bin\gps.libglib-2.0-0\libglib-2.0-0.dll]
g_timeout_dispatch at gmain.c:4545
g_main_context_dispatch at gmain.c:3122
g_main_context_iterate.isra.10 at gmain.c:3808
g_main_context_iteration at gmain.c:3869
[C:\GNAT\2019\bin\gps.libgio-2.0-0\libgio-2.0-0.dll]
g_application_run at gapplication.c:2308
[C:\GNAT\2019\bin\gps.exe]
0x425199
0x2150c58
0x4013f6
0x4014e9
[C:\windows\system32\kernel32.dll]
0x7768556b
[C:\windows\SYSTEM32\ntdll.dll]
0x777e372b
Build error. [workflow stopped]
There are three problems:
the autogenerated test code wants to throw exceptions but my project doesn't allow them.
I don't understand any of the output after that.
And I don't really understand how the gpr files work. I'm sure there's a magic incantation I can type there and get this sorted out but I've been googling and trying things for a whole day and I'm stuck.
FYI: I'm running the 2019 community versions of gnat, the ARM cross-compiler, and GPS on windows 7.
Update: 2019-12-18:
I've made some progress but it's still not working correctly. I edited the test_driver.gpr as Fabien suggested. I had to comment out the original linker package because it wouldn't work with two of them in the file.
test_driver.gpr now looks like this:
with "test_demo_project.gpr";
with "gnattest_common.gpr";
with "c:\Domains\ada\Ada_Drivers_Library\boards\MicroBit\microbit_zfp.gpr";
project Test_Driver is
for Origin_Project use "..\..\..\demo_project.gpr";
for Target use Gnattest_Common'Target;
for Runtime ("Ada") use Gnattest_Common'Runtime ("Ada");
for Languages use ("Ada", "ASM_CPP");
for Main use ("test_runner.adb");
for Exec_Dir use ".";
package Builder renames Gnattest_Common.Builder;
-- package Linker renames Gnattest_Common.Linker;
package Linker is
for Default_Switches ("Ada") use MicroBit_ZFP.Linker_Switches &
("-Wl,--print-memory-usage",
"-Wl,--gc-sections");
end Linker;
package Binder renames Gnattest_Common.Binder;
package Compiler renames Gnattest_Common.Compiler;
package Ide renames test_demo_project.Ide;
package GNATtest is
for GNATTest_Mapping_File use "gnattest.xml";
end GNATtest;
end Test_Driver;
It doesn't fix the problem with test cases being generated for the ada drivers library but I can live with running gnattest with the "--test-case-only" flag, which largely accomplishes my goal.
But when I build the project it complains about the "ASM_CPP" language and the use of assertions. See below:
gprbuild --target=arm-eabi -d -PC:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\test_driver.gpr -XADL_BUILD_CHECKS=Enabled -XADL_BUILD=Debug -XTEST_DRIVER_BUILD_MODE=no-config-file -largs -Wl,-Map=map.txt
test_driver.gpr:5:09: warning: there are no sources of language "ASM_CPP" in this project
Compile
[Ada] battery-test_data-tests.adb
battery-test_data-tests.adb:40:13: warning: pragma Restrictions (No_Exception_Propagation) in effect
battery-test_data-tests.adb:40:13: warning: this handler can never be entered, and has been removed
battery-test_data-tests.adb:53:13: warning: pragma Restrictions (No_Exception_Propagation) in effect
battery-test_data-tests.adb:53:13: warning: this handler can never be entered, and has been removed
Bind
[gprbind] test_runner.bexch
[Ada] test_runner.ali
Link
[link] test_runner.adb
Memory region Used Size Region Size %age Used
flash: 21668 B 256 KB 8.27%
ram: 3056 B 16 KB 18.65%
[2019-12-19 08:39:18] process terminated successfully, elapsed time: 02.08s
[2019-12-19 08:39:21] The selected rows in the Locations view cannot be exported, please select files and/or categories.
I tried removing the "ASM_CPP" text and the warning goes away. I don't know now to remove the warnings about the use of exceptions.
When I run my tests I get this:
arm-eabi-gnatemu -PC:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\test_driver.gpr C:\Domains\ada\Demo_Project\microbit\obj\gnattest\harness\test_runner
[2019-12-19 08:40:01] process terminated successfully, elapsed time: 00.66s
I get the same output when I make my tests fail or pass. Is the warning about the use of exceptions causing the compiler to remove them, which breaks the tests? What do I have to do allow exceptions in my tests?
The question you linked is about testing only a few subprograms, not all the sources in one project, which should be as easy as:
gnattest -Pproject.gpr
You can specify one or more specific files:
gnattest -Pproject.gpr file1.ads file2.ads
Just avoid -r, and you should be fine:
-r Consider recursively all sources from all projects
The compilation errors in your last update seems to show that you did not specify the linker script and startup code.
Those are provided in Ada Drivers Library in the project file boards/MicroBit/microbit_zfp.gpr.
So you first have to "with" this project from the test_driver.gpr project, and then add those lines to the test_driver.gpr project:
package Linker is
for Default_Switches ("Ada") use MicroBit_ZFP.Linker_Switches &
("-Wl,--print-memory-usage",
"-Wl,--gc-sections");
end Linker;
You also have to add assembly in the list of languages in test_driver.gpr:
for Languages use ("Ada", "ASM_CPP");
Related
I have installed GNAT 2018 (64 bits) on a PC Windows 8.1.
GNATColl seems well present and compiled through repertories :
C:/GNAT/2018/include/gnatcoll
C:/GNAT/2018/lib/gnatcoll.static
I try to compile this small test program :
with Ada.Text_IO; use Ada.Text_IO;
with GNATCOLL.Terminal; use GNATCOLL.Terminal;
procedure Test_Colors is
Info : Terminal_Info;
begin
Info.Init_For_Stdout (Auto);
Info.Set_Color (Standard_Output, Blue, Yellow);
Put_Line ("A blue on yellow line");
Info.Set_Color (Standard_Output, Style => Reset_All);
Put_Line ("Back to standard colors -- much better");
end Test_Colors;
with the command :
gnatmake -gnat12 -gnatf -O3 "Test_Colors.adb" -aIC:/GNAT/2018/include/gnatcoll -aLC:/GNAT/2018/lib/gnatcoll.static
The file Test_Colors.ali is well created but then the binding goes wrong :
gnatbind -aIC:/GNAT/2018/include/gnatcoll -aOC:/GNAT/2018/lib/gnatcoll.static -x test_colors.ali
gnatlink test_colors.ali -O3
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0x46d): undefined reference to `gnatcoll_get_console_screen_buffer_info'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0x4f6): undefined reference to `gnatcoll_terminal_has_colors'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0x6c6): undefined reference to `gnatcoll_get_console_screen_buffer_info'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0x729): undefined reference to `gnatcoll_terminal_has_colors'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0x73d): undefined reference to `gnatcoll_terminal_has_colors'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0x9f3): undefined reference to `gnatcoll_set_console_text_attribute'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0xc93): undefined reference to `gnatcoll_set_console_text_attribute'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0xfb4): undefined reference to `gnatcoll_set_console_text_attribute'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0x1372): undefined reference to `gnatcoll_set_console_text_attribute'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0x23e): undefined reference to `gnatcoll_beginning_of_line'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0x28e): undefined reference to `gnatcoll_clear_to_end_of_line'
.\gnatcoll-terminal.o:gnatcoll-terminal.adb:(.text+0x2d8): undefined reference to `gnatcoll_terminal_width'
collect2.exe: error: ld returned 1 exit status
gnatlink: error when calling C:\GNAT\2018\bin\gcc.exe
gnatmake: *** link failed.
Compilation échouée.
Do you know what to do to use successfully GNATColl ?
Jacob’s project file will indeed build (assuming you have your source in a subdirectory \src and are happy with having your executable in \bin), but this one is a lot simpler:
with "gnatcoll";
project Test_Colors is
for Main use ("test_colors.adb");
end Test_Colors;
The other options he shows will be extremely useful as you develop more advanced projects.
Use a project file and gprbuild. Something along these lines:
with "gnatcoll";
project Colors is
for Languages use ("Ada");
for Main use ("test_colors.adb");
for Source_Dirs use ("src/");
for Object_Dir use "obj/";
for Exec_Dir use "bin/";
package Builder is
for Default_Switches ("Ada")
use ("-m",
"-s");
end Builder;
package Compiler is
for Default_Switches ("Ada")
use ("-fstack-check", -- Generate stack checking code (part of Ada)
"-gnata", -- Enable assertions (part of Ada)
"-gnato13", -- Overflow checking (part of Ada)
"-gnatf", -- Full, verbose error messages
"-gnatwa", -- All optional warnings
"-gnatVa", -- All validity checks
"-gnaty3aAbcdefhiklnOprstux", -- Style checks
"-gnatyM125", -- Style checks
"-gnatwe", -- Treat warnings as errors
"-gnat2012", -- Use Ada 2012
"-Wall", -- All GCC warnings
"-O2"); -- Optimise (level 2/3)
end Compiler;
end Colors;
Now you can build your program with the command:
gprbuild -j0 -p -P colors.gpr
If you don't have any other project files in the directory you run the command from, it is even simpler:
gprbuild -j0 -p
I am very new to Frama-c and I got an issue when I am trying to open a C source file.
The error shows as
"fatal error: event.h: No such file or directory. Compilation terminated".
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i (no preprocessing)
[kernel] Parsing WorkSpace/bipbuffer.c (with preprocessing)
[kernel] user error: failed to run: gcc -E -C -I. -dD -D__FRAMAC__ -nostdinc -D__FC_MACHDEP_X86_32 -I/usr/share/frama-c/libc -o '/tmp/bipbuffer.ce6d077.i' '/home/xxx/WorkSpace/bipbuffer.c' you may set the CPP environment variable to select the proper preprocessor command or use the option "-cpp-command".
[kernel] user error: stopping on file "/home/xxx/WorkSpace/bipbuffer.c" that has errors. Add'-kernel-msg-key pp' for preprocessing command.
So bascially I am trying to open a C source file but it returns an error like this. I aslo tried other very simple C files like hello world and other slicing functions, it works well.
I thought it was because I didn't have the dependencies of 'event.h' but it still return these errors after I installed the libevent dependencies. I am not sure if I need to manually set some path of the dependencies for frama-c
Here is part of the C file (Source link: https://memcached.org/) that I would like to open:
#include "stdio.h"
#include <stdlib.h>
/* for memcpy */
#include <string.h>
#include "bipbuffer.h"
static size_t bipbuf_sizeof(const unsigned int size)
{
return sizeof(bipbuf_t) + size;
}
int bipbuf_unused(const bipbuf_t* me)
{
if (1 == me->b_inuse)
/* distance between region B and region A */
return me->a_start - me->b_end;
else
return me->size - me->a_end;
}
......
Thanks,
Compilers and other tools working with C source code need to know where to find header files. There are some standard places where they look automatically, but Frama-C has fewer of those than (and different ones from) a normal compiler.
You need to find out where event.h is installed, then pass something like -cpp-extra-args "-I /path/to/directory/" to Frama-C. Pass the directory name only, not including the name event.h itself.
In addition to Isabelle Newbie's answer, I'd like to point out that the Chlorine version of Frama-C, whose beta has been recently announced, features a new option -json-compilation-database that attempts to read the arguments to be passed to the pre-processor from a compilation database.
Such database can be generated directly by cmake, but there are solutions for make-based project such as the one you refer to, in particular bear, which intercepts the commands launched by make to build the database.
Here's a detailed summary of how you could proceed, using the new -json-compilation-database option from Frama-C 17 Chlorine, plus an extra script list_files.py (which is not in the beta, but will be available in the final 17 release, and can be downloaded here):
Get the source files you want to analyze with Frama-C, run ./configure, and if possible try to disable optional dependencies from external libraries; for instance, some code bases include optional dependencies based on availability of libraries/system features, but have fallback options (resorting to standard C library or POSIX functions). The more you give Frama-C, the better the chances of analyzing it well, so if such external libraries are not essential, excluding them might help get a more "POSIXy" code, which should help. This is typically visible in config.h files, in macros commonly named HAVE_*.
Compile and install Build EAR or some equivalent tool to obtain a compile_commands.json file.
Run bear make (or cmake with flag CMAKE_EXPORT_COMPILE_COMMANDS) to get the compile_commands.json file.
Run the aforementioned list_files.py in the directory containing compile_commands.json to obtain the list of C sources used during compilation.
Run Frama-C (17 Chlorine or newer), giving it the list of sources found in the previous step, plus option -json-compilation-database . to parse the compile_commands.json and, hopefully, get the appropriate preprocessing flags.
Ideally, this should suffice, but in practice, this is rarely enough. In particular due to the presence of external libraries and non-C99, non-POSIX functions, the following steps are always needed.
6. Inclusion of external libraries
At this step, Frama-C will complain about the lack of event.h. You'll have to include the headers of this library yourself. Note: copying headers directly from your /usr/include is not likely to work, due to several architecture-specific definitions, especially files such as bits/*.h..
Instead, consider downloading the external libraries and preparing them (e.g. running ./configure at least). Then manually add the extra include directory via -cpp-extra-args="-I <path/to/your/sources/for/libevent.h>/include".
7. Inclusion of missing non-POSIX headers
Some other headers may be missing, in particular GNU- or BSD-specific sources (e.g. sysexits.h). Get these headers and add them when necessary. The error message in this case comes from the preprocessor (gcc) and is similar to this:
memcached.c:51:10: fatal error: sysexits.h: No such file or directory
#include <sysexits.h>
^~~~~~~~~~~~
compilation terminated.
8. Definition of missing non-POSIX types and constants
At this point, all necessary headers should be available, but parsing with Frama-C may still fail. This is due to usage of non-POSIX type definitions (e.g. caddr_t, struct ling), non-POSIX constants (e.g. MAXPATHLEN, SOCK_NONBLOCK, NI_MAXSERV). Error messages typically resemble the following:
[kernel] memcached.c:3261: Failure: Cannot resolve variable MAXPATHLEN
Constants are often easy to provide manually, by grepping what's available in your /usr/include.
Type definitions, on the other hand, may require some copy-pasting at the right places, especially if they depend on other types which are also missing. This step is hardly automatizable, but relatively straightforward once you get used to some specific error messages.
For instance, the following error message is related to a missing type definition (caddr_t):
[kernel] Parsing memcached.c (with preprocessing)
[kernel] memcached.c:1074:
syntax error:
Location: line 1074, between columns 38 and 47, before or at token: c
1072 *hdr++ = 0;
1073 *hdr++ = 0;
1074 assert((void *) hdr == (caddr_t)c->msglist[i].msg_iov[0].iov_base + UDP_HEADER_SIZE);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1075 }
1076
Note that the token just before c is (caddr_t), which has never been defined (it is often defined as either void * or char *).
The following error message is related to an incomplete type, i.e., a struct used somewhere but never defined:
[kernel] memcached.c:5811: User Error:
variable `ling' has initializer but incomplete type
It means that variable ling's type, which is struct linger (non-POSIX), has never been defined. In this case, we can copy it from our /usr/include/bits/socket.h:
struct linger
{
int l_onoff; /* Nonzero to linger on close. */
int l_linger; /* Time to linger. */
};
Note: if there are POSIX constants/definitions missing from Frama-C's libc, consider notifying its developers, or proposing pull requests in Frama-C's Github.
9. Fixing incompatible and missing function prototypes
Parsing is likely to succeed after the previous step, but it may still fail due to incompatible function prototypes. For instance, you may get:
[kernel] User Error: Incompatible declaration for usleep:
different integer types int and unsigned int
First declaration was at assoc.c:238
Current declaration is at items.c:1573
This is the consequence of a warning emitted earlier:
[kernel:typing:implicit-function-declaration] slabs.c:1150: Warning:
Calling undeclared function usleep. Old style K&R code?
It means that function usleep is called, but it does not have a prototype, therefore Frama-C uses the pre-C99 convention of "implicit int": it generates such a prototype, but later in the code, an actual declaration of usleep is found, and its type is not int. Hence the error.
To prevent this, you need to ensure usleep's prototype is properly included. Since it is not POSIX.1-2008, you need to either define/undefine the appropriate macros (see unistd.h), or add your own prototype.
At the end, this should allow Frama-C to parse the files and build an AST.
However, there are several missing prototypes yet; we were just lucky that none conflicted with actual declarations. Ideally, you'll consider the parsing stage done when there are no more messages such as implicit-function-declaration and similar warnings.
Some of the missing prototypes in memcached, such as getsubopt, are POSIX and should be integrated into Frama-C's standard library. Others might make part of a small library of non-standard stubs, to be reused for other software.
Contributing with results for future reuse
Successful conclusion of the parsing stage for such open source libraries is enough to consider them for integration into this repository of open source case studies, so that future users can start their analyses without having to redo all of these steps. (The repository is oriented towards Eva, but not exclusively: parsing is useful for all of Frama-C plug-ins.)
I somehow cannot compile (neither run) my Ada code in GPS. I get an error:
cannot generate code for file random.ads (package spec)
gprbuild: *** compilation phase failed
The random.ads file looks like this:
with Ada.Numerics.Float_Random;
use Ada.Numerics.Float_Random;
package random is
protected randomOut is
procedure Inicializal;
entry Parcel(
randomout: out Positive;
from: in Positive;
to: in Positive := 1
);
private
G: Generator;
Inicializalt: Boolean := False;
end randomOut;
task print is
entry write(what: in String);
end print;
end random;
The .gpr file looks as follows:
project Default is
package Compiler is
for Default_Switches ("ada") use ("-g", "-O2");
end Compiler;
for Main use ("hunting.adb");
end Default;
What does this mean? How can I fix it? Thank you!
You can't generate code for a package specification.
This is normal and expected.
You can compile the package body, random.adb, and generate code for it - but there's usually no need.
Just compile your main program, (or your test harness if you're unit testing) and let the compiler find all its dependencies.
(If it can't, either you haven't written them yet, or it's looking in the wrong place. If you need help with that, add relevant info to the question).
The problem is caused by
task print is
entry write(what: in String);
end print;
As any task is specified as a body, the compiler had trouble deciding: it had a body, that has to be compiled, in a spec file, which does not. Moving the task to the .adb file solved the issue.
I want to build Interbase plugin for Qt using MinGW toolchain.
According to Qt documentation, I can do it only by MSVC, but I need MinGW... So, I wrote this .cmd file
set QTDIR=C:\Qt\4.8.0-minGW
set PATH=C:\Qt\4.8.0-minGW\bin
set PATH=%PATH%;C:\MinGW\bin
set QMAKESPEC=win32-g++
set INCLUDE=%INCLUDE%;c:\Program Files\Borland\InterBase\SDK\include
set LIB=%LIB%;c:\Program Files\Borland\InterBase\SDK\lib_ms
qmake -o Makefile ibase.pro
mingw32-make.exe
pause
and ran it from c:\Qt\4.8.0-minGW\src\plugins\sqldrivers\ibase\. Whole output is very long, but there's many similar lines, that's why I'll show only one of them and the final lines
tmp/obj/debug_shared/qsql_ibase.o: In function `ZN12QIBaseDriver24qHandleEventNo
tificationEPv':
C:\Qt\4.8.0-minGW\src\plugins\sqldrivers\ibase/../../../sql/drivers/ibase/qsql_i
base.cpp:1845: undefined reference to `isc_event_counts'
C:\Qt\4.8.0-minGW\src\plugins\sqldrivers\ibase/../../../sql/drivers/ibase/qsql_i
base.cpp:1864: undefined reference to `isc_que_events'
collect2: ld returned 1 exit status
mingw32-make.exe: *** [debug-all] Error 2
Could you tell me, how should I achive my target. Thank you.
P.S. I googled a lot and saw this quiestion - Compiling InterBase support in Qt - but there wasn't exact answer what to do...
I've done it !!!
The problem was in header file ibase.h from Interbase's SDK. There was following lines:
#if (defined(_MSC_VER) && defined(_WIN32)) || \
(defined(__BORLANDC__) && (defined(__WIN32__) || defined(__OS2__)))
...
#define ISC_EXPORT __stdcall
...
Macro ISC_EXPORT was not defined and all function's declarations was wrong. When I changed these lines in the following way:
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
...
#define ISC_EXPORT __stdcall
...
plugin was successfuly build
I've a problem with the classic math function linking of my bare metal program with blackfin tool chain linker. I tried many things but I cannot see why the libm.a does't provide the definitions for the function it use. Do I need to add an extra library? if yes which one?
I've put my linker verbose lign with linked libraries and the example linking error I got.
Thanks,
William
bfin-elf-ld -v -o test_ad1836_driver -T coreb_test_ad1836_driver.lds --just-symbol ../../icc_core/icc queue.o ezkit_561.o heap_2.o port.o tasks.o test_ad1836_driver.o list.o croutine.o user_isr.o bfin_isr.o app_c.o context_sl_asm.o cycle_count.o CFFT_Rad4_NS_NBRev.o fir_decima.o fir_decima_spl.o math_tools.o -Ttext 0x3c00000 -L /opt/uClinux/bfin-elf/bfin-elf/lib -lbffastfp -lbfdsp -lg -lc -lm -Map=test_ad1836_driver.map
argv[0] = 'bfin-elf-ld'
bindir = '/opt/uClinux/bfin-elf/bin/'
tooldir = '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/'
linker = '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/ld.real'
elf2flt = '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/elf2flt'
nm = '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/nm'
objdump = '/opt/uClinux/bfin-elf/bin/bfin-elf-objdump'
objcopy = '/opt/uClinux/bfin-elf/bin/bfin-elf-objcopy'
ldscriptpath = '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/../lib'
Invoking: '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/ld.real' '-v' '-o' 'test_ad1836_driver' '-T' 'coreb_test_ad1836_driver.lds' '--just-symbol' '../../icc_core/icc' 'queue.o' 'ezkit_561.o' 'heap_2.o' 'port.o' 'tasks.o' 'test_ad1836_driver.o' 'list.o' 'croutine.o' 'user_isr.o' 'bfin_isr.o' 'app_c.o' 'context_sl_asm.o' 'cycle_count.o' 'CFFT_Rad4_NS_NBRev.o' 'fir_decima.o' 'fir_decima_spl.o' 'math_tools.o' '-Ttext' '0x3c00000' '-L' '/opt/uClinux/bfin-elf/bfin-elf/lib' '-lbffastfp' '-lbfdsp' '-lg' '-lc' '-lm' '-Map=test_ad1836_driver.map'
GNU ld version 2.17
/opt/uClinux/bfin-elf/bfin-elf/lib/libm.a(w_atan2.o): In function `atan2':
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/w_atan2.c:96: undefined reference to `__eqdf2'
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/w_atan2.c:96: relocation truncated to fit: R_BFIN_PCREL24 against undefined symbol `__eqdf2'
.....
/opt/uClinux/bfin-elf/bfin-elf/lib/libm.a(e_sqrt.o): In function `_ieee754_sqrt':
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/e_sqrt.c:110: undefined reference to `__muldf3'
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/e_sqrt.c:110: undefined reference to `__adddf3'
.....
/opt/uClinux/bfin-elf/bfin-elf/lib/libm.a(s_atan.o): In function `atan':
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/s_atan.c:169: undefined reference to `__muldf3'
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/s_atan.c:170: undefined reference to `__muldf3'
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/s_atan.c:172: undefined reference to `__muldf3'
Add -lgcc. You need the functions to compare, add and multiply C double type values, respectively, __eqdf2, __adddf3 and __muldf3.
Usually, I'd recommend using the compiler driver (gcc) instead of linking directly with ld, even for firmware/kernel type outputs, because the former will take care of the necessary startup files and compiler runtime libraries.
Hi I think I know the problem, blackfin is not really compatible with the maths std lib. It is why in the VDSP version the maths functions are re implemented. To solve my problem, I did convert the VDSP maths lib to gcc and it compile fine now.
Thanks
Actually I found a better answer,
blackfin does in fact support std math. I just had some library flag in the wrong order.
For the linker, use the following lib flag order and it should work:
/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/ld.real' '-v' '-o' .... '-L' '/opt/uClinux/bfin-elf/lib/gcc/bfin-elf/4.3.5/' '-lgcc' '-L' '/opt/uClinux/bfin-elf/bfin-elf/lib' '-lbfdsp' '-lg' '-lm' '-lbffastfp' '-lc'