How to include header files with E-ACSL wrapper script? - c

I am new to Frama-C and wanted to ask how I could add header files when using the E-ACSL wrapper script. Normally, I've been adding header files the following way with WP and RTE:
frama-c -rte main.c -cpp-extra-args="-I src/include -I ..."
However, I am unsure of how I can include these files when using the wrapper script.
e-acsl-gcc.sh --rte=all -c main.c
Without the header files I run into the following error:
[kernel] Parsing main.c (with preprocessing)/main.c:10:10: fatal error: header.h: No such file or directory #include "header.h"
I am using Frama-C 24.0 (Chromium). Any help would be appreciated. Thanks.

If you run e-acsl-gcc.sh -h, you'll get a help message with the script's options:
Options:
-h show this help page
-c compile instrumented code
(...)
-E pass additional arguments to the Frama-C preprocessor
-F pass additional options to the Frama-C command line
(...)
The two above are relevant for you: -E adds arguments to an implicit -cpp-extra-args used by the script, while -F allows you to add the option itself.
So, you can either run:
e-acsl-gcc.sh -E "-Isrc/include -I..." <other options and source files>
Or:
e-acsl-gcc.sh -F -cpp-extra-args="-Isrc/include,-I..." <other options and source files>
Note that with -F, due to quoting issues (between e-acsl-gcc.sh, Frama-C's command-line, C preprocessor, etc), you may need to replace spaces with commas, as in "-Isrc/include,-I...".
Important: do not add spaces between -I and the directory name. Due to parsing issues, e-acsl-gcc.sh will not parse it correctly if you do. GCC accepts both syntaxes anyway, so I'd recommend getting used to not adding spaces after -I (and -D as well) in general.
Overall, using -E is better here, but -F can be used to pass other options besides -cpp-extra-args.

Related

clang-tidy reporting many error: unknown argument

I am running an embedded C project based on a tricore-gcc compiler.
I made a compile_commands.json file that works well.
However, there are some arguments that clang-tidy cannot recognize.
For example I get the following
error: unknown argument: '-fstrict-volatile-bitfields' [clang-diagnostic-error]
when I run clang-tidy.
This is not a surprise of course, since -fstrict-volatile-bitfields is an option for gcc but not for clang-tidy.
However, I would like to suppress output messages due to unknown compiler options.
I tried to append --extra-arg=-Wno-unknown-warning-option as suggested here but the problem persists.
I had the same problem when using clang-tidy for a project compiled with GCC. The two compilers have different set of recognized flags. My compile_commands.json, which was generated by intercept-build, contained a number of options used by GCC that clang-tidy did not understand.
I solved this by a somewhat hackish solution of redacting the compile database before initiating the static analysis pass.
My script contains a number of Sed lines similar to this:
sed -i -E 's#-fconserve-stack##g' compile_commands.json
sed -i -E 's#-maccumulate-outgoing-args##g' compile_commands.json
sed -i -E 's#-mindirect-branch-register##g' compile_commands.json
sed -i -E 's#-mindirect-branch=thunk-extern##g' compile_commands.json
sed -i -E 's#-mpreferred-stack-boundary=3##g' compile_commands.json
sed -i -E 's#-mfunction-return=thunk-extern##g' compile_commands.json
This way, the unsupported flags are made invisible to clang-tidy, which allows to work without errors.

Name an executable file c

I know this seems like a stupid question but how do I name an executable file when using flags like -Wall and -pedantic in c?
I have a file named test.c and another one named function.c where I wrote the functions I need for my program test.c .
I use this command to compile: gcc -Wall -pedantic test.c
Where should I put the name of the executable file? I tried every place but it doesn't seem to work. Is my compiler lacking something or what?
You need to use the -o option, like this
gcc -Wall -pedantic -o MY_EXECUTABLE_NAME test.c
# ^ here (output file name option)
You know, you can always do gcc --help
Usage: gcc [options] file...
Options:
-pass-exit-codes Exit with highest error code from a phase
--help Display this information
--target-help Display target specific command line options
--help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]
Display specific types of command line options
(Use '-v --help' to display command line options of sub-processes)
--version Display compiler version information
-dumpspecs Display all of the built in spec strings
-dumpversion Display the version of the compiler
-dumpmachine Display the compiler's target processor
-print-search-dirs Display the directories in the compiler's search path
-print-libgcc-file-name Display the name of the compiler's companion library
-print-file-name=<lib> Display the full path to library <lib>
-print-prog-name=<prog> Display the full path to compiler component <prog>
-print-multiarch Display the target's normalized GNU triplet, used as
a component in the library path
-print-multi-directory Display the root directory for versions of libgcc
-print-multi-lib Display the mapping between command line options and
multiple library search directories
-print-multi-os-directory Display the relative path to OS libraries
-print-sysroot Display the target libraries directory
-print-sysroot-headers-suffix Display the sysroot suffix used to find headers
-Wa,<options> Pass comma-separated <options> on to the assembler
-Wp,<options> Pass comma-separated <options> on to the preprocessor
-Wl,<options> Pass comma-separated <options> on to the linker
-Xassembler <arg> Pass <arg> on to the assembler
-Xpreprocessor <arg> Pass <arg> on to the preprocessor
-Xlinker <arg> Pass <arg> on to the linker
-save-temps Do not delete intermediate files
-save-temps=<arg> Do not delete intermediate files
-no-canonical-prefixes Do not canonicalize paths when building relative
prefixes to other gcc components
-pipe Use pipes rather than intermediate files
-time Time the execution of each subprocess
-specs=<file> Override built-in specs with the contents of <file>
-std=<standard> Assume that the input sources are for <standard>
--sysroot=<directory> Use <directory> as the root directory for headers
and libraries
-B <directory> Add <directory> to the compiler's search paths
-v Display the programs invoked by the compiler
-### Like -v but options quoted and commands not executed
-E Preprocess only; do not compile, assemble or link
-S Compile only; do not assemble or link
-c Compile and assemble, but do not link
-o <file> Place the output into <file>
-pie Create a position independent executable
-shared Create a shared library
-x <language> Specify the language of the following input files
Permissible languages include: c c++ assembler none
'none' means revert to the default behavior of
guessing the language based on the file's extension
Options starting with -g, -f, -m, -O, -W, or --param are automatically
passed on to the various sub-processes invoked by gcc. In order to pass
other options on to these processes the -W<letter> options must be used.
For bug reporting instructions, please see:
<http://bugzilla.redhat.com/bugzilla>.
gcc -o output_name -Wall -pedant file.c
U should use -o before file name ,because it creates a object file of your code file.

How to specify default include directory in GCC

I am new in GCC and I am wondering how to tell the compiler that several include directories need to be specified as default for searching .h files. I read that -I dir is the key to accomplish that but doing my makefiles I encounter some problems. For example:
include_dir = C:/Users/rmrd001/Documents/Make/GCC/first/mydir/
FLAGS = -I "$(include_dir)"
func2.o: func2.c func2.h
gcc $(FLAGS) -c func2.c
And I got the error:
make:*** No rule to make target 'func2.c', needed by 'func2.o'. Stop.
The include_dir is not the working directory. It is working_directory/my_dir.
Please help.
-I is used for finding include files, but not for finding the main file. You have to pass an explicit path to the main file.
You can add path with -I option right in command line;
You can specify path with env variable C_INCLUDE_PATH
Also you can find more info on gcc official site and here

Can I use Preprocessor Directives in .ld file

Can I use Preprocessor Directives in .ld file?
I need to to use one of two sets of .ld file and wants to let Build engine deside that using macro, Can I do that?
Yes, you can. You need to run preprocessor manually for your linker script, like this:
in="your_linker_script.ld"
out="generated_script.ld"
cflags=-Iinclude/
gcc -E -P -x c $cflags $in >$out
Flags:
-E specifies GCC to only run preprocessor
-P prevents preprocessor from generating linemarkers (#line directives)
-x c tells GCC to treat your linker script as C source file (it's needed to run GCC with your LD script)
Or you can simply use cpp tool, which is actually C preprocessor.
After this you will be able to use generated linker script to build your program (e.g. in Makefile).
Example
Here is how I solved this problem in my project:
Here is my linker script uses preprocessor (#include directive and CONFIG_TEXT_BASE constant). Excerpt:
#include <config.h>
. = CONFIG_TEXT_BASE;
Here is script to generate preprocessed linker script. Excerpt:
gcc -E -P -x c -Iinclude $cflags $in >>$out
Here is my Makefile, it's generating preprocessed linker script at $(LDS_GEN) target (line 53) and the this generated script is being used to build result binary (line 42). Excerpt:
$(LDS_GEN): $(LDS)
build/gen-lds.sh $(LDS) $(LDS_GEN) $(CFLAGS)
$(APP).bin: $(OBJS) $(LDS_GEN)
$(LD) $(OBJS) -T $(LDS_GEN) -o $(APP).elf
Small update after long time. This way of pre-processing works until the memory file does not contain lines that are fooling the pre-processor. E.g.:
"KEEP(*path/*.o(.rodata .rodata*))"
The "/*" after path is considered comment start (the line contains what is considered a C multi-line comment start and not a match pattern).
This line is valid for the linker but it is considered comment and the output from C pre-processor will remove everything till a supposed closing comment is found:
"KEEP(*path"
The resulting file is clearly invalid for the linker. I have no solution at the moment.
As a simplification of Sam's answer, I added the below to my makefile and away we go :)
PRE_LD_FILE = $(PROG_NAME).ld
LD_FILE = $(PROG_NAME)_generated.ld
$(LD_FILE) : $(PRE_LD_FILE)
cpp $(PRE_LD_FILE) | grep -v '^#' >>$(LD_FILE)

C/C++ file before preprocessing

Is it possible to look at a c/c++ file before preprocessing? Or rather after just a half-hearted pre-processing? Basically there is a
#define <commonly_used_word> 0
in a third party library header and I want to figure out where it is. So basically, I just want the compiler to include all the headers but not the the preprocessor as such.
Your original source file is file before preprocessing.
It sounds like you want your #include directives processed, yet you want to keep macros non-substituted. Both actions are carried out by the preprocessor.
In general case it is impossible, since in C and C++ it is legal to use macros as include file names, as in
#define INCLUDE_FILE "stdio.h"
#include INCLUDE_FILE
Achieving what you want would require a preprocessor specifically designed to satisfy your request. I, for one, don't know of any such preprocessor implementation.
If you want to find where a specific macro is defined, you might try the following trick: define your own macro with the same name before including any headers, and start compilation. The compiler (the preprocessor) should complain about macro redefinition when it encounters the library definition of the same macro and point out its location to you.
There are GCC-specific -M and -MM options:
To list absolute paths of include files, use -M
Instead of outputting the result of preprocessing, output a rule
suitable for make describing the dependencies of the main source file.
The preprocessor outputs one make rule containing the object file name
for that source file, a colon, and the names of all the included
files, including those coming from -include or -imacros command line
options. gcc -M test.c
If you dont want the system includes like
#include <stdio.h>,
then use -MM Like -M but do not mention header files that are found in
system header directories, nor header files that are included,
directly or indirectly, from such a header. gcc -MM test.c
That could significantly narrow down the search area.
http://www.math-linux.com/spip.php?article263
You can tell cpp to generate the list of included files using -M option:
$ cpp -M a.c
a.o: a.c /usr/include/stdio.h /usr/include/features.h \
/usr/include/sys/cdefs.h /usr/include/bits/wordsize.h \
/usr/include/gnu/stubs.h /usr/include/gnu/stubs-64.h \
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/include/stddef.h \
/usr/include/bits/types.h /usr/include/bits/typesizes.h \
/usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
/usr/lib/gcc/x86_64-pc-linux-gnu/4.7.1/include/stdarg.h \
/usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
It gives you a Makefile rule format but you could ignore that and use with any other command.
For example, you can grep for the symbol (here I'm ignoring stderr because of \ and a.o: not being a real file names -- laziness):
$ grep '#\s*define\s*BUFSIZ' $(cpp -M a.c) 2>/dev/null
/usr/include/stdio.h:# define BUFSIZ _IO_BUFSIZ
You can also use a program like ctags to find the symbol for you:
$ ctags $(cpp -M a.c)
...
$ grep BUFSIZ tags
BUFSIZ /usr/include/stdio.h 128;" d
If you know which header files contain the definition you're looking for, e.g by using find and grep as suggested, you may be able to pinpoint which one is affecting the current source file by getting gcc to print the header inclusion tree. As described in gcc's documentation, you can achieve this by using the -H option, possibly combined with -MG to eliminate normal processing.

Resources