Linux cc command

Updated: 11/06/2021 by Computer Hope
cc command

On Unix-like operating systems, the cc command runs the system's C compiler.

This page covers the GNU/Linux version of cc, a symbolic link to gcc, the GNU compiler collection.


The compiler's essential duty is to translate a computer program from one language to another, and it usually does this more than once in a single compilation.

When compiling a program written in C, the compiler goes through several steps to translate it into machine code that can be executed on your target architecture or platform.

In general, the compiler performs the following functions on your code:

  1. Pre-processing. The C preprocessor ("cpp") prepares your code to be sent to the actual compiler by removing comments, expanding macros, and performing a few other important steps.
  2. Syntax checking. Does your program contain any syntactical errors? If so, the compiler lets you know, and you need to fix them before you proceed. If it suspects some parts of your program are not correct, but it's unsure that they are actually errors, it may issue warnings, but still compiles the program.
  3. Conversion to assembly language. This is an intermediary step where your code is translated into the language of your target system's assembly language. This is pretty much the last step where your code is still readable by a human.
  4. Assembly. Your program is assembled into the bits and bytes of object code suitable for your target platform.
  5. Linking. The object code is linked together with the object code of any library functions specified by your program and command line options, and an executable file is created.


cc [ options ]


There are literally hundreds of options you can pass to the compiler to fine-tune how your program executes. Here we have selected some useful and commonly-used options which you may need to create an executable file.

-c Compile the code; do not attempt to link source files. Object files are created, which can optionally be linked later in a separate step to create an executable file.
-O[level] Create an optimized executable. The compiler analyzes your code, and if it knows any clever tricks to speed up performance, it implements them in the byte code. The level is an optional number, letter, or word which can specify how much optimization should be done. For instance, the GNU compiler collection allows for the options -O0 to specify minimum optimization (the default), -O1 and -O2 for intermediate levels of optimization, and -O3 for maximum optimization. -Ofast can be used as an alias for -O3, and -Og performs optimizations that are compatible with later analysis by a debugger. Optimization requires more computation and memory, and takes longer to complete. Common optimization tricks for x86 systems include reducing instruction size to make execution less computationally expensive, implementing a dedicated register for the value zero (because zero is used so commonly in most programs), and optimizing certain multiplication and array index-scaling operations by taking advantage of the LEA ("load effective address") instruction.
-Wall Enable "all" (all but the most esoteric) warnings when compiling. This is a good option to use regularly, as it can cue you in to any conditions which may not be errors, but which you may nonetheless want to resolve before compiling.
-ansi Disable most (but not all) of the non-ANSI C compliant features provided by cc. To adhere to strict ANSI standards, enable this option. Doing so ensures that the code is fully portable to be compiled on any other system.
-g Create a debugging version of the compiled executable file. The compiler includes information in the compiled executable about what line of the source file corresponds to what function call. A debugger can later use this information to show the source code as you step through the program. Note that this creates a much larger executable file.
-D name[=value] Defines a macro at compile time by assigning the specified value to the symbol name. When the C preprocessor is run, it expands any instances of name to the text of value.
-Idir Search dir for included files whose names do not begin with a slash (/) before searching the usual directories. The directories for multiple -I options are searched in the order specified. The preprocessor first searches for #include files in the directory containing sourcefile, and then in directories named with -I options (if any), then /usr/ucbinclude, and finally, in /usr/include.
-Ldir Add dir to the list of directories where the compiler looks for linked libraries. This option is passed to ld and /usr/lib.
-llibrary If linking, this options adds the indicated library to the list of libraries to be linked. For instance, if you are using functions from the C math library (libm), you would link it at compile time using the option -lm.

Be aware of your libraries' inter-dependencies and make sure to link them in the correct order on the command line; specify first any libraries which other libraries will depend on. For instance, "-lGL -lGLU" searches libGL first and then libGLU. libGLU depends on libGL, so if you reversed the order of these -l options, the program would not compile.
-M If linking, creates a map file with the same base name as the output executable, but with the suffix .map. This map file contains a list of symbols with their addresses.
-mmodel Specifies the memory model that the compiler and linker use. Values of model include s for "small" memory model, m for "medium", l for "large", and f for "flat" (32-bit), c for "compact", or h for "huge". Unless you're sure you require this option, you may omit it.
-o file name The output name of the compiled executable file. If file name is not specified, the compiled executable will be named a.out.
-S Produces assembler source code, but stops before actually assembling.
-Uname "Undefine" any previously-defined macro named name, either in the source code or specified on the command line with -D.

Environment variables

The following environment variables affect the compilation process:

These environment variables control the way the compiler uses localization information to work with different national conventions. A common value is "en_GB.UTF-8" for English language encoded in UTF-8. If set, the LC_ALL variable overrides all other locale settings. To view your current locale settings, use the locale command.
TMPDIR If TMPDIR is set, it specifies the directory to use for temporary files. The compiler uses temp files to hold the output of one stage of compilation that is to be used as input to the next stage. For example, the output of the preprocessor, which is the input to the actual compiler, is stored in a temporary file during the compilation process.
COMPILER_PATH A colon-separated list of directories, much like the PATH variable. The compiler searches this list of directories for subprograms if it can't find them using the value of GCC_EXEC_PREFIX.
LIBRARY_PATH A colon-separated list of directories, much like PATH. When linking, the compiler searches this list of directories for linked libraries, and for special linker files it can't find using the value of GCC_EXEC_PREFIX.
Each of these variables may hold a list of directories separated by a special character, much like PATH, which the compiler looks for header files. The special character, PATH_SEPARATOR, is target-dependent and determined at build time. For most Linux targets, PATH_SEPARATOR is a colon. CPATH specifies a list of directories to be searched as if specified with the -I option, but after any paths given with the -I option. C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, and OBJC_INCLUDE_PATH apply only when preprocessing the particular language indicated. Each specifies a list of directories to be searched as if specified with -isystem, but after any paths given with -isystem options on the command line. In all these variables, an empty element instructs the compiler to search its current working directory. Empty elements can appear at the beginning or end of a path. For instance, if the value of CPATH is :/special/include, has the same effect as "-I. -I/special/include".
DEPENDENCIES_OUTPUT If this variable is set, its value specifies how to output dependencies for make based on the non-system header files processed by the compiler. System header files are ignored in the dependency output. The value of DEPENDENCIES_OUTPUT can be only a file name, where Make rules are written to that file, guessing the target name from the source file name. Or the value can have the form "file target", where rules are written to file file using target as the target name.


cc myfile.c

Compile the file myfile.c. Output will be written to the executable file a.out.

cc myfile.c -o myexe

Compile the file myfile.c and name the compiled executable output file myexe.

cc myfile.c -Wall -o myexe

Compile the file myfile.c and output the compiled executable as myexe, displaying warnings during compilation if they occur.

cc myfile.c -Wall -lX11 -o myexe

Compile myfile.c to the executable myexe, linking the libX11 library and issuing any applicable warnings during compilation.

cc myfile.c -Wall -ansi -lX11 -o myexe

Compile myfile.c to the executable myexe, linking the libX11 library, adhering strictly to ANSI C standards, and issuing warnings if applicable.

ld — Link editor for object files.
ctags — Create tag files for source code.