Summary: What do the -f and -m in gcc and clang compiler options stand for?
Details:
When using clang I've noticed that many compiler options start with -f and others start with -m. I assume that there is some historical reason for this and I was curious so I looked at the gcc help and saw the following:
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 options must
be used.
If I had to guess I think that -f might stand for frontend and -m for machine. But I'd be interested to hear a more comprehensive answer, possibly including the other sub-processes that gcc invokes.
I don't have specific sources that state what 'f' and 'm' mean, but we can infer based on usage patterns found in documentation.
'f' stands for 'flag'.
Flags are on if specified via '-fFLAG' and off via '-fno-FLAG'
ex:
-fpic # flag to set position independent code
-fno-builtin # don't recognize build in functions ...
The technical definition is that 'f' defines "Control the interface conventions used in code generation".
Src:
https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
(e.g -fpci, when this flag is set)
'm' stands for mode. One general characteristic is that it sometimes has parameters. e.g
-mabi=name #abi mode = name
-mcpu=cpu
Src:
https://gcc.gnu.org/onlinedocs/gccint/Standard-Names.html (e.g ... when this mode...)
According to gcc onlinedocs, options of the form -ffoo and -fno-foo stand for machine independent code generation conventions.
Examples: fpic, -fno-pic
-m options stand for machine dependent options.
eg: -mcpu, -march, -matomic
https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options or https://home.cs.colorado.edu/~main/cs1300/doc/gnu/gcc_2.html#SEC43
https://gcc.gnu.org/onlinedocs/gcc/Submodel-Options.html#Submodel-Options or https://home.cs.colorado.edu/~main/cs1300/doc/gnu/gcc_2.html#SEC16
Related
I've been exploring compilers and cross compilers. I'm reading the GCC manual.
Specifically, there are these statements in the manual that I have queries regarding:
The linker searches a standard list of directories for the library. The directories searched include several standard system directories plus any that you specify with -L.
The -isystem and -idirafter options also mark the directory as a system directory, so that it gets the same special treatment that is applied to the standard system directories.
Alright, what are these "system directories"? On a Linux machine, what are the system directories for the native compiler?
And if I've built a cross compiler (like the one shown here: https://wiki.osdev.org/GCC_Cross-Compiler), what are the "system directories" with respect to this compiler?
Can I change the system directory when I build GCC? Moreover, Where does sysroot come into the picture?
The "standard" system directories aren't specific directories - it may vary across installations/distributions.
gcc has an option -print-search-dirs. Using which you can get the list of directories, it looks for.
Something like:
gcc -print-search-dirs | grep libraries | sed 's/libraries: =//g' | tr ':' '\n' | xargs readlink -f
It's the same for cross compiler's too (you'd call cross compiler's front-end instead of plain gcc).
--sysroot is straightward:
--sysroot=dir Use dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers
in /usr/include and libraries in /usr/lib, it instead searches
dir/usr/include and dir/usr/lib.
If you use both this option and the -isysroot option, then the
--sysroot option applies to libraries, but the -isysroot option applies to header files.
The GNU linker (beginning with version 2.16) has the necessary support
for this option. If your linker does not support this option, the
header file aspect of --sysroot still works, but the library aspect
does not.
GCC is nothing if not configurable.
When you build an instance GCC, you need to completely specify the target environment. (Fortunately, most of this has already been done for you.) If necessary, you can tweak any of these settings before you do the build. The settings are described in detail in the GCC internals manual, but the particular ones you're interested in are in the chapter describing Target Macros, and particularly the section on Controlling the Compilation Driver. In this last section, you'll find descriptions of the various macros which define include paths. (Search for the word "include" in that page. Read everything you find :-); GCC documentation is not a tutorial.)
I have already known that the GCC's argument -finstrument-functions can hook the functions and the argument -finstrument-functions-exclude-file(functions)-list can exclude some files/functions to be traced.
But now I have a lot of files to be compiled and only some of them need to be traced. I wonder if I can include some specific functions/files to be traced, such as something like -finstrument-functions-include-file(functions)-list?
Thanks a lot!
GCC does not support this out-of-the-box (it's more a task for your build system). One common hack to achieve what you want is to write a shell wrapper which replaces GCC and adds flags where needed:
$ cat path/to/fake/gcc
#!/bin/sh
FLAGS=
if echo "$*" | grep -q 'myfile1.c'; then
FLAGS=-finstrument-functions
fi
exec /usr/bin/gcc "$#" $FLAGS
$ export PATH="path/to/fake:$PATH"
If you use cmake to build your project you may benefit from adding COMPILE_OPTIONS at a specific level. Use
add_compile_options()
for directory-wide settings
target_compile_options()
for target-specific settings and
set_source_files_properties()
for file specific settings.
In your case
set_source_files_properties(
myfile1.cc PROPERTIES COMPILE_FLAGS -finstrument-functions)
Recent GCC compilers can be extended by GCC plugins.
But now I have a lot of files to be compiled and only some of them need to be traced.
You should consider writing your own GCC plugin to do that job. See also this draft report.
You may configure your build automation tool (e.g. GNU make or ninja) to help you.
At last, some of your C code (e.g. #include-ed files) could be generated. Think of meta-programming approaches (e.g. with SWIG or ANTLR or Bison or GPP or your own C code generator), perhaps using X-macros.
I'm writing some code for a project that uses a Kinetis processor. These processors have a Flash Config Field which is stored in flash at a particular address. If the wrong value gets written to that field, you can lock yourself out of your chip for good.
My code for this consists of a packed struct, an instance that specifies the .flashConfig section, some static asserts to ensure the struct is the required size, and the #define that gets written to the FSEC field (the important one) is as expected. Then in the linker script I have that section stored in the correct bit of flash. Additionally I have an ASSERT to see if I have the correct amount of data in that section.
This is all pretty good, but I'm still nervous (I've seen these chips gets themselves locked up, on several occasions now). What I want to do is add an extra assert to the linker script, something like:
ASSERT(BYTE_AT(0x40C) == 0xBE);
Is that possible?
I considered using objdump / objcopy to get dump this from a .bin in a post build step. However I'm building this on windows, so no grep / awk which would be nice and easy. Other people will also have to build this, so I don't want to rely on cygwin being installed or what not. Plus this is a little more removed than the linker, and therefore could easily be missed if someone removes the post_build script.
I don't want to rely on cygwin being installed or what not.
Write a C program that performs the same check objdump and grep would have done.
Plus this is a little more removed than the linker, and therefore could easily be missed if someone removes the post_build script.
Make the verification program invoke the linker, and then verify the result. That is, instead of
${LD} -o foo.bin ${LDFLAGS} ${OBJS} && ./post_build foo.bin
do this:
./build_and_verify -o foo.bin ${LDFLAGS} ${OBJS}
Does the gcc output of the object file (C language) vary between compilations? There is no time-specific information, no change in compilation options or the source code. No change in linked libraries, environmental variables either. This is a VxWorks MIPS64 cross compiler, if that helps. I personally think it shouldn't change. But I observe that sometimes randomly, the instructions generated changes. I don't know what's the reason. Can anyone throw some light on this?
How is this built? For example, if I built the very same Linux kernel, it includes a counter that is incremented each build. GCC has options to use profiler information to guide code generation, if the profiling information changes, so will the code.
What did you analyze? The generated assembly, an objdump of object files or the executable? How did you compare the different versions? Are you sure you looked at executable code, not compiler/assembler/linker timestamps?
Did anything change in the environment? New libraries (and header files/declarations/macro definitions!)? New compiler, linker? New kernel (yes, some header files originate with the kernel source and are shipped with it)?
Any changes in environment variables (another user doing the compiling, different machine, different hookup to the net gives a different IP address that makes it's way into the build)?
I'd try tracing the build process in detail (run a build and capture the output in a file, and do so again; compare those).
Completely mystified...
I had a similar problem with g++. Pre 4.3 versions produced exactly the same object files each time. With 4.3 (and later?) some of the mangled symbol names are different for each run - even without -g or other recordings. Perhaps the use a time stamp or random number (I hope not). Obviously some of those symbols make it into the .o symbol table and you get a difference.
Stripping the object file(s) makes them equal again (wrt. binary comparison).
g++ -c file.C ; strip file.o; cmp file.o origfile.o
Why should it vary? It is the same result always. Try this:
for i in `seq 1000`; do gcc 1.c; md5sum a.out; done | sort | uniq | wc -l
The answer is always 1. Replace 1.c and a.out to suit your needs.
The above counts how many different executables are generated by gcc when compiling the same source for 1000 times.
I've found that in at least some environments, the same source may yield a different executable if the source tree for the subsequent build is located in a different directory. Example:
Checkout a pristine copy of your project to dir1. Do a full rebuild from scratch.
Then, with the same user on the same machine, checkout the same exact copy of your source code to dir2 (dir1 != dir2). Do another full rebuild from scratch.
These builds are minutes apart, with no change in the toolchain or any 3rd party libs or code. Binary comparison of source code is the same. However, the executable in dir1 has different md5sum than the executable in dir2.
If I compare the different executables in BeyondCompare's hex editor, the difference is not just some tiny section that could plausibly be a timestamp.
I do get the same executable if I build in dir1, then rebuild again in dir1. Same if I keep building the same source over and over from dir2.
My only guess is that some sort of absolute paths of the include hierarchy are embedded in the executable.
My gcc sometimes produces different code for exactly the same Input. The output object files differ in exactly one byte.
Sometimes this causes linker Errors, because one possible object file is invalid. Recompiling another version usually fixes the linker error.
The gcc Version is 4.3.4 on Suse Linux Enterprise.
The gcc Parameters are:
cc -std=c++0x -Wall -fno-builtin -march=native -g -I<path1> -I<path2> -I<path3> -o obj/file.o -c file.cpp
If someone experiences the same effect, then please let me know.
List of available LLVM passes are desribed here. I am interested in knowing which passes are included for different optimization levels. For example, for -O2 which passes are included. Is there any site or document which provides that information.
It's visible in PassManagerBuilder.cpp file. Take a look at populateModulePassManager method where OptLevel is integer that follows -O option.
from the command line you can use:
echo "" | opt -O3 -disable-output -debug-pass=Arguments