gcc options. gcc options: Neil Matthew. LSB Standard Libraries

Now that you know something about the C standard, let's look at the options that the gcc compiler offers to ensure compliance with the C standard in the language you write. There are three ways to ensure that your C code is standards-compliant and free of flaws: options that control the version of the standard you intend to conform to, definitions that control header files, and warning options that trigger stricter checking. program code.

gcc has a huge range of options, and here we will consider only those that we consider the most important. A complete list of options can be found in the gcc online man pages. We'll also briefly discuss some of the #define directive options that can be used; Typically they should be specified in your source code before any #include lines or defined on the gcc command line. You might be surprised at how many options there are to select which standard to use, rather than just a flag that forces you to use modern standard. The reason is that many older programs rely on historical compiler behavior and would require significant work to update them to the latest standards. Rarely, if ever, will you want to update your compiler to cause it to break running code. As standards change, it is important to be able to work against a particular standard, even if it is not the most latest version standard

Even if you're writing a small program for personal use, where standards compliance may not be that important, it often makes sense to include additional gcc warnings to force the compiler to look for errors in your code before executing the program. This is always more effective than executing the code step by step in the debugger and wondering where the problem might be. The compiler has many options that go beyond simple standards checking, such as the ability to detect code that meets the standard but may have questionable semantics. For example, a program may have an execution order that allows a variable to be accessed before it is initialized.

If you need to write a program for shared use, given the degree of compliance and types of compiler warnings that you consider sufficient, it is very important to spend a little more effort and get your code to compile without any warnings at all. If you allow some warnings to appear and get into the habit of ignoring them, one day a more serious warning may appear that you risk missing. If your code always compiles without warning messages, a new warning will inevitably attract your attention. Compiling code without warnings is a good habit to adopt.

Compiler options for standards tracking

Ansi is the most important standards option and forces the compiler to act according to the ISO C90 language standard. It disables some non-standard-compliant gcc extensions, disables C++-style comments (//) in C programs, and enables handling of ANSI trigraphs (three-character sequences). In addition, it contains the __ STRICT_ANSI__ macro, which disables some extensions in header files that are not compatible with the standard. The adopted standard may change in subsequent versions of the compiler.

Std= - This option provides finer control over the standard used, providing a parameter that specifies exactly the required standard. Below are the main possible options:

C89 - support the C89 standard;

ISO9899:1999 - support latest version ISO standard, C90;

Gnu89 - support the C89 standard, but allow some GNU extensions and some functionality C99. In version 4.2 of gcc, this option is the default.

Options for standard tracking in define directives

There are constants (#defines) that can be specified as options on the command line or as definitions in the source code of the program. We generally think of these as using the compiler command line.

STRICT_ANSI__ - forces the ISO C standard to be used. Determined when the -ansi option is given on the compiler command line.

POSIX_C_SOURCE=2 - Enables functionality defined in IEEE Std 1003.1 and 1003.2. We will return to these standards later in this chapter.

BSD_SOURCE - Enables functionality of BSD systems. If they conflict with POSIX definitions, the BSD definitions take precedence.

GNU_SOURCE - allows wide range properties and functions, including GNU extensions. If these definitions conflict with POSIX definitions, the latter take precedence.

Compiler options for warning output

These options are passed to the compiler from command line. And again we will list only the main ones, full list can be found in the interactive reference guide gcc.

Pedantic is the most powerful option for checking the purity of C code. In addition to enabling the C standard check option, it disables some traditional C constructs prohibited by the standard and invalidates all GNU extensions to the standard. This option should be used to maximize the portability of your C code. The downside is that the compiler is very concerned about the cleanliness of your code, and sometimes you have to rack your brains to get rid of the few remaining warnings.

Wformat - checks the correctness of the argument types of printf family functions.

Wparentheses - checks for the presence of parentheses, even where they are not needed. This option is very useful for checking that complex structures initialized as intended.

Wswitch-default - checks for the presence of a default option in switch statements, which is generally considered good style programming.

Wunused - tests a variety of cases, e.g. static functions declared but not described, unused parameters, discarded results.

Wall - Enables most gcc warning types, including all previous -W options (only -pedantic is not covered). With its help it is easy to achieve clean code.

Note

There are many more advanced warning options available, see the gcc web pages for details. In general we recommend using -Wall ; this is a good compromise between verification ensuring the program code High Quality, and the need for the compiler to output a mass of trivial warnings, which become difficult to reduce to zero.

GCC is a freely available optimizing compiler for C, C++ languages.

Program gcc, launched from the command line, is an add-on to a group of compilers. Depending on the file name extensions passed as parameters and additional options, gcc launches the necessary preprocessors, compilers, linkers.

Files with the extension .cc or .C are considered as files in the C++ language, files with the extension .c as programs in C language, and files with the extension .o are considered objective.

To compile the C++ source code found in the file F.cc, and create an object file F.o, you need to run the command:

Gcc -c F.cc

The -c option means "compile only".

To link one or more object files derived from source code - F1.o, F2.o, ... - into a single executable file F, you need to enter the command:

Gcc -o F F1.o F2.o

The -o option specifies the name of the executable file.

You can combine the two processing steps - compilation and linking - into one overall step using the command:

Gcc -o F F1.cc ... -lg++

- possible additional compilation and linking options. The –lg++ option indicates the need to include the standard library of the C++ language, - possible additional libraries.
After linking, an executable file F will be created, which can be run using the command

./F

- a list of command line arguments for your program.
Libraries are often used during the linking process. A library is a collection of object files grouped into a single file and indexed. When the link command encounters a library in the list of object files to link, it checks to see if the linked object files already contain calls to functions defined in one of the library files. If such functions are found, the corresponding calls are associated with the object file code from the library. Libraries can be included using the -lname option. In this case, in standard directories such as /lib , /usr/lib, /usr/local/lib the library will be searched for in a file named libname.a. Libraries should be listed after the source or object files containing calls to the corresponding functions.

Compilation options

Among the many compilation and linking options, the most commonly used are:

Option Purpose
-c This option means that only compilation is necessary. From the source files of the program, object files are created in the form name.o. No layout is performed.
-Dname=value Define name in the compiled program as the value of v alue. The effect is the same as having a line #define name value at the beginning of the program. Part =value can be omitted, in which case the default value is 1.
-o file-name Use file-name as the name for the created file.
-lname Use libname.so library when linking
-Llib-path
-Iinclude-path
Add lib-path and include-path to the standard search directories for libraries and header files, respectively.
-g Place debugging information for the debugger in an object or executable file gdb. The option must be specified for both compilation and linking. In combination –g It is recommended to use the option to disable optimization –O0(see below)
-MM Output dependencies on header files used in a C or C++ program in a format suitable for the utility make. No object or executable files are created.
-pg Place profiling instructions in an object or executable file to generate information used by the utility gprof. The option must be specified for both compilation and linking. Assembled with option -pg The program generates a statistics file when launched. Program gprof based on this file, creates a transcript indicating the time spent performing each function.
-Wall Displays messages about any warnings or errors that occur during program compilation.
-O1
-O2
-O3
Various levels of optimization.
-O0 Don't optimize. If you use multiple -O options with or without level numbers, the last such option is valid.
-I Used to add your own directories to search for header files during the build process
-L Passed to the linker. Used to add your own library search directories during the build process.
-l Passed to the linker. Used to add your own libraries to be searched during the build process.

Linux OS first appeared only as the system kernel. Unfortunately, the kernel itself is not very useful; programs need registration, file management, compilation of new programs, etc. To make the system useful, the GNU Project has added various features. They were clones of similar programs available in UNIX and UNIX-like systems of that time. The transformation of Linux into a UNIX-like system set the first standards for Linux, providing C programmers with a familiar work environment.

Different UNIX (and later Linux) developers added their own extensions to the commands and utilities they included with the system, and the structure of the file systems they used also differed slightly. All this made it difficult to create applications that could run on different systems. Moreover, the programmer could not even rely on the system functionality being implemented in the same way or the configuration files being stored in the same location.

It became clear that standardization was needed to maintain the similarity of UNIX systems, and such work is now underway.

Over time, not only have standards moved forward, but the Linux OS has been improved at an impressive rate by the community, supported by commercial organizations such as Red Hat and Canonical, and even by non-Linux developers such as IBM. As Linux evolved, along with the development of a collection of compilers, gcc not only maintained the relevant standards, but also defined new standards if existing ones were found to be ineffective. In fact, as the Linux operating system and its associated software and utilities became increasingly popular, UNIX system developers began making changes to their products to make them more compatible with the Linux operating system.

In this final chapter, we're going to look at Linux standards, focusing on the areas you need to know about in order to not only write applications that run on your Linux systems after you upgrade them, but also create code that can be portable to others. Linux distributions, and perhaps into UNIX-like systems, thus ensuring the sharing of your programs.

In particular we will cover the following topics:

□ C programming language standard;

□ UNIX standards, especially POSIX, developed by the IEEE, and the Single UNIX Specification, developed by the Open Group;

□ development by the Free Standards Group, especially the Linux Standard Base, which defines the layout of the standard Linux file system.

A good starting point for understanding the standards specific to the Linux operating system is the Linux Standard Base (LSB), which can be found on the Linux Foundation Web site at http://www.linux-foundation.org/.

We are not going to go into detail about the content of the standards, many of which are comparable in scope to this book. We want to highlight the key standards you should be aware of, give you a brief history of how these standards developed, and help you decide which ones might be useful when writing your own programs.

C programming language

The C programming language is the de facto programming language of the Linux OS, therefore, in order to write C programs for Linux, you need to understand a little about its origins, find out how the language has changed, and, most importantly, understand how programs are checked for compliance with standards.

A Brief History Lesson

For those who aren't much of a history buff, don't worry: this book is about programming, not history, so the review will be very brief.

The C programming language emerged in the early 1970s and was based in part on the earlier BCPL programming language and extensions to the B language. Dennis M. Ritchie wrote a user manual for the language in 1974, and around the same time C was used as a programming language to rework the UNIX kernel on PDP-11 computers. In 1978, Brian W. Kernighan and Ritchie wrote the classic manual on the language, The C Programming Language.

Very quickly the language gained great popularity, due, undoubtedly, partly to the rapid growth in popularity of UNlX systems, but also to its capabilities and understandable syntax. The syntax of the C language continued to evolve in a consistent manner, but as it changed more and more from the original description given in the book, it became clear that a standard was needed that was consistent with modern usage and that was more rigorous.

In 1983, ANSI (American National Standards Institute) founded the X3J11 standards committee to develop a clear and rigorous definition of the language. Along the way, both organizations made minor changes to the language, most notably giving it the long-awaited ability to declare parameter types, but mostly the committee simply brought clarity and rationale to the existing definition of what constituted a common language variant of the language. The final standard was published in 1989 as ANSI Standard Programming Language C, X3.159-1989, or more briefly C89, sometimes referred to as C90. (This latter turned into the ISO/IEC 9899:1990 standard, Programming Languages ​​- C. Both standards are formally identical.)

As with most standards, publication did not end the work of the committee, which continued to iron out some of the inaccuracies found in the specification and began work on a new version of the standard in 1993, called C9X. The committee also published minor adjustments and updates existing standard in 1994-1996

A new version standard was made in the 1990s. and officially became the C99 standard; it has been adopted by ISO as ISO/IEC 9899:1999. There is still an active J11 committee that oversees the standardization of the C language and its libraries, but it now operates under the International Committee for Information Technology Standards group. information technologies). For more information on C standardization work, visit the website http://j11.incits.org/.

GNU Compiler Collection

After the development of the Emacs editor (yes, we love Emacs), the next major achievement of the GNU project, as mentioned in chapter 1, became a completely free C compiler, gcc, the first official version which was released in 1987.

The name gcc originally stood for GNU C Compiler (the GNU Project's C compiler), but since the underlying compiler runtime now supports many other programming languages, such as C++, Objective-C, FORTRAN, Java and Ada, as well as libraries for these languages, the definition has been replaced by the more appropriate GNU Compiler Collection (collection of GNU compilers).

gcc has always been and seems to remain the standard compiler for Linux and C or C++, the main language for writing programs in the Linux OS. Home page gcc can be found at http://gcc.gnu.org/.

The GNU C compiler has always kept a good track of the development of the C language standard, although it allows for some extensions of the language, and there are of course minor delays, as with almost all compilers, between the release of the standard and the release of compiler versions that follow the specification exactly. Sometimes the opposite happens, and gcc anticipates weak changes to the standard, which can also be completely confusing. gcc has a number of command-line and other options that allow you to specify the version of the C language standard that the compiler must conform to, as well as a number of other options to control how picky or strict the compiler is.

gcc options

Now that you know something about the C standard, let's look at the options that the gcc compiler offers to ensure compliance with the C standard in the language you write. There are three ways to ensure that your C code is standards-compliant and free of flaws: options that control the version of the standard you intend to conform to, definitions that control header files, and warning options that trigger stricter code checking. .

gcc has a huge range of options, and here we will consider only those that we consider the most important. A complete list of options can be found in the gcc online man pages. We will also briefly discuss some of the directive's options

, which can be applied; Typically they should be specified in your source code before any directive lines or defined on the gcc command line. You might be surprised at how many options there are to select which standard to use, rather than simply checking a flag to force the current standard to be used. The reason is that many older programs rely on historical compiler behavior and would require significant work to update them to the latest standards. Rarely, if ever, will you want to update your compiler to cause it to break running code. As standards change, it is important to be able to work against a particular standard, even if it is not the most recent version of the standard.

Even if you're writing a small program for personal use, where standards compliance may not be that important, it often makes sense to include additional gcc warnings to force the compiler to look for errors in your code before executing the program. This is always more effective than executing the code step by step in the debugger and wondering where the problem might be. The compiler has many options that go beyond simple standards checking, such as the ability to detect code that meets the standard but may have questionable semantics. For example, a program may have an execution order that allows a variable to be accessed before it is initialized.

If you need to write a program for shared use, given the degree of compliance and types of compiler warnings that you consider sufficient, it is very important to spend a little more effort and get your code to compile without any warnings at all. If you allow some warnings to appear and get into the habit of ignoring them, one day a more serious warning may appear that you risk missing. If your code always compiles without warning messages, a new warning will inevitably attract your attention. Compiling code without warnings is a good habit to adopt.

Compiler options for standards tracking- This is the most important standards option and forces the compiler to act in accordance with the ISO C90 language standard. It disables some gcc extensions that are not compatible with the standard, disables C++-style comments () in C programs, and enables handling of ANSI trigraphs (three-character sequences). In addition, it contains the __ macro, which disables some extensions in header files that are not compatible with the standard. The adopted standard may change in subsequent versions of the compiler. - This option provides finer control over the standard used, providing a parameter that specifies exactly the required standard. The following are the main possible options: - support the C89 standard; - support the latest version of the ISO standard, C90; - support the C89 standard, but allow some GNU extensions and some C99 functionality. In version 4.2 of gcc, this option is the default. Options for tracking standard in directives define

There are constants (

), which can be specified by options on the command line or as definitions in the source code of the program. We generally think of these as using the compiler command line. - forces the use of ISO standard C. Determined when the option is specified on the compiler command line. - Enables functionality defined by IEEE Std 1003.1 and 1003.2. We will return to these standards later in this chapter. - includes functionality of BSD systems. If they conflict with POSIX definitions, the BSD definitions take precedence. - Allows a wide range of properties and functions, including GNU extensions. If these definitions conflict with POSIX definitions, the latter take precedence. Compiler options for warning output

These options are passed to the compiler from the command line. Again, we'll only list the main ones; a complete list can be found in the gcc online reference manual.

- This is the most powerful option for checking the purity of C code. In addition to enabling the C standard compliance check option, it disables some traditional C constructs that are prohibited by the standard, and makes all GNU extensions invalid in relation to the standard. This option should be used to maximize the portability of your C code. The downside is that the compiler is very concerned about the cleanliness of your code, and sometimes you have to rack your brains to get rid of the few remaining warnings. - checks the correctness of the argument types of family functions. - checks for the presence of parentheses, even where they are not needed. This option is very useful for verifying that complex structures are initialized as intended. - checks for the presence of variant in statements, which is generally considered good programming style. - checks various cases, for example, static functions declared but not described, unused parameters, discarded results. - includes most gcc warning types, including all previous options - (only not covered). With its help it is easy to achieve clean code.
Note

There are many more advanced warning options available, see the gcc web pages for details. In general we recommend using

; This is a good compromise between checking, which ensures high quality code, and the need for the compiler to issue a mass of trivial warnings that become difficult to reduce to zero.

Interfaces and Linux Standards Base

Now we're going to move up a level and move from C programming to looking at the interfaces (system functions) provided by the operating system. This level of standardization has different components: functions provided by libraries and system calls implemented by the operating system at a low level. Both have two levels of detail: what interfaces are represented and a definition of what each interface does.

The defining document in this area for the Linux OS is the Linux Standards Base (LSB, operating system standards for Linux based), which can be found on the websites http://mvw.linuxbase.org or http://www.linux-foundation.org/en/LSB. Several versions of the standards have already been released, and work continues.

A list of certified distributions can be found at http://www.linux-foundation.org/en/Products. Various versions of Red Hat, SUSE and Ubuntu are certified, but remember that after the release of the distribution, some time may pass until certification occurs. The Web site has a list of distributions that are undergoing testing or just need some updates in order to pass certification tests.

The Linux Standards Base (as of version 3.1) defines three areas for compliance testing:

□ kernel - main libraries, utilities and location of key file system components;

□ C++ - C++ libraries;

□ desktop - additional files for desktop settings, mainly different graphic libraries.

In the specification, we are most interested in the kernel.

The LSB standard covers a number of areas in its own documentation, but also references external standards for specific interface definitions. The standard covers the following areas:

□ object file formats for binary compatibility;

□ dynamic linking standards;

□ standard libraries, both core and X Window System libraries;

□ command shell and other command line programs;

□ runtime environment, including users and groups;

□ system initialization and run levels.

In this chapter, we will only discuss standard libraries, users, and system initialization.

LSB Standard Libraries

The Linux Standard Base documentation defines in two ways the interfaces that must be present. For some functions, mostly implemented by the GNU Project C library or tending to be Linux-only standards, both the interface and its behavior are defined. For other interfaces, especially those with a UNIX-like framework, the standard simply states that the interface must be present and must behave as defined by another standard, typically the Common Application Environment (CAE) or, more commonly, the Single UNIX Specification UNIX specification), which is available on the Open Group website http://www.opengroup.org. Some parts can be found (registration currently required) at http://www.unix.org/online.html.

Unfortunately, the underlying Linux and UNIX standards have a rather complicated past, and there is too much choice, although in general the different versions are almost compatible.

A Brief History Lesson

UNIX OS was born in the late 1960s. AT&T's Bell Laboratories division when Ken Thompson and Dennis Ritchie wrote an operating system initially intended for personal use only, which they called Unics. Somehow the name changed to UNIX. AT&T allowed universities to take the source code for their own development, and UNIX quickly became incredibly popular due to its very clear logical structure and powerful ideas. The availability of source code should have been a significant incentive, as it allowed programmers to make changes and experiment.

The BSD operating system was an option that came out of work done at the University of California at Berkeley, which put a lot of emphasis on organizing and maintaining the network.

When AT&T began making UNIX a commercial system, which happened mostly in the mid-1980s, it called releases UNIX systems System, and the most popular was UNIX System V.

Many other variants emerged, too many to list here, all with slight variations from the basic standards and some additions as companies tried to add value to the product by creating their own extensions.

Things really got complicated when AT&T sold the UNIX business to Novell, which decided to end it in 1994, and ownership of the rights and trademarks became an uncertain matter, subject to various lawsuits.

In 1988, IEEE (Institute of Electrical and Electronic Engineers, Institute of Electrical and Electronics Engineers, http://www.ieee.org) released the first set of standards: POSIX or IEEE 1003 - standards that were intended to be the defining specification of a portable interface for computer operating systems. Although it is a good and well-defined standard, POSIX is also very much a kernel specification with a very limited scope.

In 1994, the X/Open Company, a non-supplying organization, released a more comprehensive set of specifications, the X/Open CAE or Common Applications Environment, which is an extension of the IEEE POSIX standards and is formally identical to them in many areas. X/Open later merged with OSF (Free Software Foundation). software) for the establishment of the Open Group; its home web page is located at http://www.opengroup.org/. The CAE standard was revised and released in 2002 as Single UNIX Specification, Version 3, developed by the Open Group.

It is this specification that is most often referenced in the Linux standards base.

Note

It should be noted that "Linux" is trademark, owned by Linus Torvalds. Cm. http://www.linuxmark.org/.

Applying the LSB Standard to Libraries

Enough about the history of creating standards. What does it mean for people writing programs in C (or C++), the requirement for their portability?

First, you must make sure that the library function you are using is in the LSB standard. If it's not there, you may be doing something that won't easily transfer to another system, and you should look standard way implementation of the problem you are trying to solve. Maybe it's worth a try Linux command apropos, which searches online help pages for relevant links.

Second, and more difficult, you should make sure that the behavior of the function you are using is included in the standard and that you are not relying on behavior that is not described in the standard. You may have to refer to the Single UNIX Specification for this if the function's use is not defined in the LSB standard. Very good way check for undefined or potentially erroneous behavior - refer to the Linux online manual. Many of its pages have a "BUGS" section, which is an invaluable source of information about where in Linux a particular call does not fully implement the standards or where there are defects and oddities in behavior.

LSB Users and Groups

This section of the standard is precise, concise, and clear. The following are some of the requirements of the standard.

□ The specification requires that to obtain detailed user information, never read files such as /etc/passwd directly, but always use standard library calls, e.g.

, or standard utilities, for example.

□ The standard requires a user named root in the root group, who is a system administrator with full privileges or access rights. We also find in the standard a number of optional user and group names that should never be used in standard applications; they are intended to be used by distributions.

□ The standard also states that IDs less than 100 are system IDs Accounts, the range 100-499 is occupied by system administrators and post-installation scripts, and finally, ID numbers 500 and above are intended for regular user accounts.

In general, most Linux programmers should be aware of the user-related standards requirements.

LSB system initialization

The area of ​​system initialization or startup has always, at least for us, been a source of concern due to subtle distribution differences.

Linux inherited from UNIX-like operating systems the idea of ​​runlevels, or runlevels, that define the services that are constantly running on the system. In table 18.1 provides standard definitions for the Linux OS.


Table 18.1

Run level Description
0 Halt. Used as a logical state to go to when the system stops
1 Single-user mode. Directories other than / (root) may not be mounted and will not have network support. Typically used for system maintenance
2 Multiplayer mode, but no online support
3 Regular multiplayer with online support using a text mode login screen
4 Reserved
5 Regular online multiplayer using the graphical login screen
6 Pseudo-level used for reboot

The LSB standard provides these levels, but does not require their use, although they are very common.

Accompanying runlevels is a set of init scripts that are used to start, stop, and restart services. In the past they were stored in different places in the /etc directory, often in /etc/init.d or /etc/rc.d/init.d. This variety often caused confusion, as users who changed distributions could not find the init scripts in the usual places, and the installation of programs would fail if they tried to execute the init script from the wrong directory.

The LSB 3.1 standard defines the /etc/init.d directory as the location for storing init scripts, but it also allows this directory to be a link to another location on the system.

Each script in the /etc/init.d directory has a name associated with the service it provides. Since all Linux OS services must share the same namespace, it is important that these names are unique. For example, life will be difficult if MySQL and PostgreSQL services decide to name their scripts "database". To resolve this conflict, there is another set of standards. This is the Assigned Names And Numbers Authority (LANANA) standard, which can be found on the website http://www.lanana.org/. Fortunately, you will need to know very little about this standard, except that it stores a list of registered script and package names, making life easier for users Linux systems.


The init script must accept a parameter that controls what it does. The standard defines the parameters listed in table. 18.2.


Table 18.2

Parameter Meaning
Starts (or restarts) a service
Stops the service
Restarts the service; usually implemented as a simple stop of a service followed by starting that service
Reinstalls the service by reloading the parameters without actually stopping the service. Not all services support this option, so this option may not be available in some scenarios, or if available, may have no effect
Tries to force a reinstallation if the service supports it; if not, it restarts the service
Prints a text message about the status of the service and returns a status code that can be used to determine the status of the service

All commands return 0 if successful or an error code indicating the reason for the failure. In case of parameter

returns 0 if the service is running; all other codes mean that the service is not running for some reason.

File system device standard

The last standard we're going to look at in this chapter is the Filesystem Hierarchy Standard (FHS). It can be found at http://www.pathname.com/fhs/.

The purpose of this standard is to define typical storage locations in the Linux file system so that both developers and users can make educated guesses about the location of certain files. Long-time users of UNIX-like operating systems have long complained about subtle differences in file system layouts, and the FHS standard offers Linux distributions a way to avoid going down this choppy path.

The file layout in the Linux system at first glance may seem like a semi-arbitrary structure of files and directories based on historical ideas. This is partly true, but over the years the layout has justifiably evolved into the hierarchy we see today. Its main idea is to divide files and directories into the following three groups:

□ files and directories unique to a particular running Linux system, such as startup scripts and configuration files;

□ files and directories that are read-only and possibly shared by multiple running Linux systems, e.g. executable files applications;

□ directories that are read/write, but possibly shared between running Linux or other systems operating systems, such as user home directories.

In this book we are not too interested sharing files different versions Linux, although, in the case of a network of Linux machines, this great way make sure there is only one copy of directories key programs, and share it across different machines on the network. This is especially useful for diskless workstations.

The FHS standard defines a top-level structure that has a number of required subdirectories and several optional directories; the main ones are given in table. 18.3.


Table 18.3

Catalog Required? Purpose
/bin Yes Important system binaries
/boot Yes Files required to boot the system
/dev Yes Devices
/etc Yes System files configurations
/home No Directories for user files
/lib Yes Standard Libraries
/media Yes Space for removable mountable media, with separate subdirectories for each media type supported by the system
/mnt Yes Convenient point for temporarily mounting devices such as CD-ROMs and flash memory drives
/opt Yes Additional application software
/root No root user files
/sbin Yes Important system binaries that are required during the system startup process
/srv Yes Read-only data for services provided by this system
/tmp Yes Temporary files
/usr Yes Auxiliary hierarchy. Traditionally, user files are also stored here, but these days this is considered bad style and the average user should not be given write access to this directory
/var Yes Variable data such as log files

Additionally, there may be other directories starting with lib, although this is not common. Typically, you'll also see a /lost+found directory (for file system recovery using fsck) and a /proc directory, which is a pseudo-file system that provides a representation of the running system. The current version of the FHS standard strongly supports the /proc file system, but its presence is not required. The details regarding the /proc system are largely beyond the scope of the topics discussed in this book, although we have included it short review V chapter 3.

□ /bin - Contains binary files that can be used by both root and non-root users and are important for functioning in single-user mode where some other directory structures may not be mounted. For example, you can usually find kernel commands here

and, like the team.

□ /boot - used for files required during boot of a Linux system. Often this directory is very small, less than 10 MB, and is often a separate partition. This is very useful on PC based systems that have BIOS restrictions for active partition, which must be in the first 2 or 4 GB of the disk. By having this directory as a separate partition, you will have more flexibility when placing the rest of the disk partitions.

□ /dev - contains special device files that are mapped to hardware devices. For example, /dev/had will map to the first IDE drive.

□ /etc - contains configuration files. Traditionally, some binaries can be found here, but this is no longer true for most modern Linux systems. The most famous file in the /etc directory is probably the passwd file, which contains user information. Other useful files are fstab with a list of mount options; hosts with a list of mappings from IP addresses to computer names, and the httpd directory containing the configuration for the Apache server.

□ /home - directory for user files. Typically, each user in this directory will have one directory named the same as the user's login name, and this will be the default login directory. For example, after registering, the user rick will almost certainly find himself in the /home/rick directory.

□ /lib - Contains important shared libraries and kernel modules, especially those that will be needed when the system boots in single-user mode.

□ /media - designed as a top-level directory for storing mount point directories for removable media. The goal is to be able to remove unnecessary top-level directories such as /cdrom and /floppy.

□ /mnt is just a convenient place to temporarily mount additional file systems. Traditionally, some distributions have added subdirectories to the /mnt directory for different devices, such as /cdrom and /floppy, but the current preference is to place them in the /media directory, reverting /mnt to its original purpose as a single top-level temporary mount location.

□ /opt - directory for software vendors used for inserting software applications added to the base distribution. Distributions should not use it to store software that comes as part of the standard distribution, but should be left for use by third party vendors. Typically, vendors will create subdirectories with their own names and subdirectories within them, such as /bin and /lib, for files relevant to their application.

Note

By convention, many Open Source Linux packages use the /usr/local directory for installation.

□ /root is the directory for files used by the root user. It is not part of the /home directory in the directory tree because it may not mount in single-user mode.

□ /sbin - used for commands usually used only system administrator and required during system boot in single-user mode. This is where the teams live

, And .

□ /srv - designed to host read-only local data, but is not widely used at present.

□ /tmp - used for temporary files. Usually, but not always, cleared when the system boots.

□ /usr - a rather complex auxiliary file system, usually containing all the commands system type and libraries not required at system boot or in single-user mode. The directory has many subdirectories such as /bin, /lib, /X11R6 and /local.

Note

When UNIX and Linux systems first appeared, the /usr directory also had subdirectories for logging, buffering Email and so on. Now all these subdirectories are removed from the usr directory and placed in the var directory. The advantage of this approach is that /usr is now mountable file system, it can be shared by other systems on the network, and it is less susceptible to damage to the system that stops it in an uncontrolled manner, such as a power failure.

□ /var - Contains frequently changing data, such as print spool files, application log files, and email spool directories.

Sections on this page:

Now that you know something about the C standard, let's look at the options that the gcc compiler offers to ensure compliance with the C standard in the language you write. There are three ways to ensure that your C code is standards-compliant and free of flaws: options that control the version of the standard you intend to conform to, definitions that control header files, and warning options that trigger stricter code checking. .

gcc has a huge range of options, and here we will consider only those that we consider the most important. A complete list of options can be found in the gcc online man pages. We'll also briefly discuss some of the #define directive options that can be used; Typically they should be specified in your source code before any #include lines or defined on the gcc command line. You might be surprised at how many options there are to select which standard to use, rather than simply checking a flag to force the current standard to be used. The reason is that many older programs rely on historical compiler behavior and would require significant work to update them to the latest standards. Rarely, if ever, will you want to update your compiler to cause it to break running code. As standards change, it is important to be able to work against a particular standard, even if it is not the most recent version of the standard.

Even if you're writing a small program for personal use, where standards compliance may not be that important, it often makes sense to include additional gcc warnings to force the compiler to look for errors in your code before executing the program. This is always more effective than executing the code step by step in the debugger and wondering where the problem might be. The compiler has many options that go beyond simple standards checking, such as the ability to detect code that meets the standard but may have questionable semantics. For example, a program may have an execution order that allows a variable to be accessed before it is initialized.

If you need to write a program for shared use, given the degree of compliance and types of compiler warnings that you consider sufficient, it is very important to spend a little more effort and get your code to compile without any warnings at all. If you allow some warnings to appear and get into the habit of ignoring them, one day a more serious warning may appear that you risk missing. If your code always compiles without warning messages, a new warning will inevitably attract your attention. Compiling code without warnings is a good habit to adopt.

Compiler options for standards tracking

Ansi is the most important standards option and forces the compiler to act according to the ISO C90 language standard. It disables some non-standard-compliant gcc extensions, disables C++-style comments (//) in C programs, and enables handling of ANSI trigraphs (three-character sequences). In addition, it contains the __ STRICT_ANSI__ macro, which disables some extensions in header files that are not compatible with the standard. The adopted standard may change in subsequent versions of the compiler.

Std= - This option provides finer control over the standard used, providing a parameter that specifies exactly the required standard. The following are the main possible options:

C89 - support the C89 standard;

Iso9899:1999 - support the latest version of the ISO standard, C90;

Gnu89 - Maintain the C89 standard, but allow some GNU extensions and some C99 functionality. In version 4.2 of gcc, this option is the default.

Options for tracking standard in directives define

There are constants (#defines) that can be specified as options on the command line or as definitions in the source code of the program. We generally think of these as using the compiler command line.

STRICT_ANSI__ - forces the ISO C standard to be used. Determined when the -ansi option is given on the compiler command line.

POSIX_C_SOURCE=2 - Enables functionality defined in IEEE Std 1003.1 and 1003.2. We will return to these standards later in this chapter.

BSD_SOURCE - Enables functionality of BSD systems. If they conflict with POSIX definitions, the BSD definitions take precedence.

GNU_SOURCE - Allows a wide range of properties and functions, including GNU extensions. If these definitions conflict with POSIX definitions, the latter take precedence.

Compiler options for warning output

These options are passed to the compiler from the command line. Again, we'll only list the main ones; a complete list can be found in the gcc online reference manual.

Pedantic is the most powerful option for checking the purity of C code. In addition to enabling the C standard check option, it disables some traditional C constructs prohibited by the standard and invalidates all GNU extensions to the standard. This option should be used to maximize the portability of your C code. The downside is that the compiler is very concerned about the cleanliness of your code, and sometimes you have to rack your brains to get rid of the few remaining warnings.

It is a common belief that GCC lags behind other compilers in performance. In this article we will try to figure out what basic optimizations of the GCC compiler should be applied to achieve acceptable performance.

What are the default options in GCC?

(1) The default optimization level in GCC is “-O0”. It is clearly not optimal from a performance standpoint and is not recommended for compiling the final product.
GCC does not recognize the architecture on which compilation is run until the ”-march=native” option is passed. By default, GCC uses the option specified during its configuration. To find out the GCC configuration, just run:

This means that GCC will add “-march=corei7” to your options (unless another architecture is specified).
Most GCC compilers for x86 (baseline for 64-bit Linux) add: “-mtune=generic -march=x86-64” to the given options, since the configuration did not specify options that define the architecture. You can always find out all the options passed when GCC starts, as well as its internal options, using the command:

As a result, often used:

Specifying the architecture to use is important for performance. The only exception is those programs where calling library functions takes up almost the entire startup time. GLIBC can select the optimal function for a given architecture at runtime. It is important to note that with static linking, some GLIBC functions do not have versions for different architectures. That is, dynamic assembly is better if the speed of GLIBC functions is important..
(2) By default, most GCC compilers for x86 in 32-bit mode use the x87 floating-point model, since they were configured without “-mfpmath=sse”. Only if the GCC configuration contains “--with-mfpmath=sse”:

the compiler will use the SSE model by default. In all other cases, it is better to add the “-mfpmath=sse” option to the build in 32-bit mode.
So, often used:

Adding the option ”-mfpmath=sse” is important in 32-bit mode! The exception is the compiler, which has “--with-mfpmath=sse” in its configuration.

32 bit mode or 64 bit?

32-bit mode is usually used to reduce the amount of memory used and, as a result, speed up work with it (more data fits into the cache).
In 64-bit mode (compared to 32-bit) the number of registers available common use increases from 6 to 14, XMM registers from 8 to 16. Also, all 64-bit architectures support the SSE2 extension, so in 64-bit mode there is no need to add the “-mfpmath=sse” option.
It is recommended to use 64-bit mode for counting tasks, and 32-bit mode for mobile applications.

How to get maximum performance?

There is no specific set of options to get the best performance, but GCC has many options that are worth trying. Below is a table with recommended options and growth projections for Intel processors Atom and 2nd Generation Intel Core i7 regarding the “-O2” option. The predictions are based on the geometric mean of the results of a specific set of problems compiled by GCC version 4.7. It is also assumed that the compiler configuration was carried out for x86-64 generic.
Forecast for increased performance on mobile applications relative to “-O2” (only in 32-bit mode, since it is the main one for the mobile segment):

Forecast for increased performance on computing tasks relative to “-O2” (in 64-bit mode):
-m64 -Ofast -flto ~17%
-m64 -Ofast -flto -march=native ~21%
-m64 -Ofast -flto -march=native -funroll-loops ~22%

The advantage of the 64-bit mode over 32-bit for computing tasks with the “-O2 -mfpmath=sse” options is about ~5%
All data in the article is a forecast based on the results of a specific set of benchmarks.
Below is a description of the options used in the article. Full description (in English): http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Optimize-Options.html "
  • "-Ofast" is similar to "-O3 -ffast-math" includes more high level optimizations and more aggressive optimizations for arithmetic calculations (for example, real reassociation)
  • "-flto" inter-module optimizations
  • "-m32" 32 bit mode
  • "-mfpmath=sse" enables the use of XMM registers in real arithmetic (instead of the real stack in x87 mode)
  • "-funroll-loops" enables loop unrolling