You are here: >

Linux and Unix cc command

cc commandAbout cc
cc syntax
cc examples
Related commands
Linux and Unix main page

About cc

cc stands for "C compiler". On modern systems, cc is usually an alias to a program which can compile the C programming language, such as gcc or clang.

On a standard GNU/Linux system, running cc will execute gcc, the GNU compiler collection. This documentation therefore refers to syntaxes, options and behaviors which are in some cases gcc-specific. If your system is configured to alias the cc command to another compiler, you should consult your compiler's documentation for details about how its behavior may differ.

How The Compiler Works

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 the a single compilation.

When compiling a program written in C, the compiler goes through several steps to translate it into machine code which 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 will let you know, and you will have to fix them before you proceed. If it suspects some parts of your program are not correct, but it's not sure that they are actually errors, it may issue warnings, but still compile 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 syntax

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 of the most useful and commonly-used options which you may need to create an executable file.


Just compile the code; do not attempt to link source files. Object files will be created, which can optionally be linked later in a separate step to create an executable file.


Create an optimized executable. The compiler will analyze your code, and if it knows any clever tricks to speed up performance, it will implement them in the byte code. level is an optional number, letter, or word which can specify how much optimization should be done. For instance, the GNU compiler colection 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 will perform optimizations that are compatible with later analysis by a debugger.

Optimization requires more computation and memory, and will take 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.


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.


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 will ensure that your code is fully portable to be compiled on any other system.


Create a debugging version of the compiled executable file. The compiler will include information in the compiled executable about which line of which source file corresponds to which 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 will expand any instances of name to the text of value.


Search dir for included files whose names do not begin with a slash (/) prior to 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.


Add dir to the list of directories where the compiler will look for linked libraries. This option is passed to ld and /usr/lib.


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" will search libGL first and then libGLU. libGLU depends on libGL, so if you reversed the order of these -l options, the program would not compile.


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.


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 filename

The output name of the compiled executable file. If filename is not specified, the compiled executable will be named a.out.


Produces assembler source code, but stops before actually assembling.


"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.


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 which 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.


A colon-separated list of directories, much like the PATH variable. The compiler will search this list of directories for subprograms if it can't find them using the value of GCC_EXEC_PREFIX.


A colon-separated list of directories, much like PATH. When linking, the compiler will search 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, in which the compiler will look 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, that has the same effect as "-I. -I/special/include".


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 just a file name, in which case the 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", in which case the rules are written to file file using target as the target name.

cc examples

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.