C / C ++ generic Makefile

 

C / C ++ generic Makefile
the Generic Makefile for C / C ++ Program

====================================== ============
Keywords: Makefile, the make, the Generic, C / C ++
Author: whyglinux (whyglinux AT Hotmail DOT COM)
a Date: 2006-03-04
========== ========================================

provided herein for a C / C ++ program is compiled and linked to generate generic Makefile executable.

Before using the Makefile, only you can make some simple settings; and once set up, even after the source file for the increase or decrease in general no longer need to change Makefile. Therefore, even if a Makefile writing rules have not studied people who can quickly establish a working Makefile for their C / C ++ program.

The Makefile can work under GNU Make and GCC compiler. But we can not guarantee can also work for other versions of Make and compiler.

If you find errors in this article, this article or have any thoughts or suggestions by whyglinux AT hotmail DOT com mailbox and contact the author.

This Makefile used as follows:

  • Organizer directory
    try to focus their source in a directory, and the Makefile and source together, so that was easier to use. Of course, you can also classify the source stored in different directories.

    Create a text file named Makefile in the program directory, copy the contents of the back Makefile listed in this file. (Note: In the replication process, preceding each command Makfile Tab characters can be converted into a number of spaces required in this case to replace the space in front of a command Makefile Tab)

    the current working directory to directory Makefile is located. Currently, only the Makefile support calls in the current directory, the directory path does not support the current situation and where the Makefile is not the same directory.
  • Specifies the executable
    program to compile and generate an executable file after a successful connection is set in the Makefile PROGRAM variable. This one can not be empty. A meaningful it is an executable file's name your own program.
  • Specify the source code
    to compile two source extensions by their path and file to determine. Since the header file is included for use by, so to say here that the source should include the header file.

    The path where the program is set SRCDIRS in. If the source code distributed in a different directory, then you need a SRCDIRS specified in, and path names separated by spaces.

    File type used in the procedure specified in SRCEXTS. Extension C / C ++ programs generally have relatively fixed several forms: .c, .C, .cc, .cpp , .CPP, .c ++ ,. cp, or .cxx (see man gcc). Extension determine whether the program C or C ++ program: .c are C programs, other extension indicates a C ++ program. Usually the extension can be fixed using one of them. But there may need to use a variety of extensions, which can all be specified in SOURCE_EXT, separated by a space between each extension.

    Although not common, but the C program also can be compiled as a C ++ program. This can be achieved by setting two CC = $ (CXX) and CFLAGS = $ (CXXFLAGS) in the Makefile.

    The Makefile support for C, C ++ and C / C ++ compiler mixture of three ways:
    • If only .c extension, then this is a C program, compile command represented by the $ (CC) to compile and link.
    • If the specified other extensions other than .c (e.g. .cc, .cpp, .cxx, etc.), then this is a C ++ program, to compile and link with $ (CXX).
    • If both the .c, specify another extension C ++, then this is the C / C ++ hybrid program, will use $ (CC) compiled one of the C program, using $ (CXX) compiled one of the C ++ program, the last and then $ (CXX) linker.

    According to make this work is provided in a file type for the Makefile (extension) is determined automatically, without user intervention.
  • 指定编译选项
    编译选项由三部分组成:预处理选项、编译选项以及连接选项,分别由 CPPFLAGS、CFLAGS与CXXFLAGS、LDFLAGS 指定。

    CPPFLAGS 选项可参考 C 预处理命令 cpp 的说明,但是注意不能包含 -M 以及和 -M 有关的选项。如果是 C/C++ 混合编程,也可以在这里设置 C/C++ 的一些共同的编译选项。

    CFLAGS 和 CXXFLAGS 两个变量通常用来指定编译选项。前者仅仅用于指定 C 程序的编译选项,后者仅仅用于指定 C++ 程序的编译选项。其实也可以在两个变量中指定一些预处理选项(即一些本来应该放在 CPPFLAGS 中的选项),和 CPPFLAGS 并没有明确的界限。

    连接选项在 LDFLAGS 中指定。如果只使用 C/C++ 标准库,一般没有必要设置。如果使用了非标准库,应该在这里指定连接需要的选项,如库所在的路径、库名以及其它联接选项。

    现在的库一般都提供了一个相应的 .pc 文件来记录使用库所需要的预编译选项、编译选项和连接选项等信息,通过 pkg-config 可以动态提取这些选项。与由用户显式指定各个选项相比,使用 pkg-config 来访问库提供的选项更方便、更具通用性。在后面可以看到一个 GTK+ 程序的例子,其编译和连接选项的指定就是用 pkg-config 实现的。
  • Compiling and linking
    the various settings that you saved after the Makefile good. Execute make command, the program began to build.

    Command make will be based on a good path and set the file type search Makefile source file, and then calls the appropriate compiler command depending on the type of file, use the appropriate compiler options for the program to be compiled.

    The program will connect automatically after successful compilation. If no errors will eventually generate an executable file for the program.

    Note: After the program is compiled, will produce .d files and source files one to one. This is a file dependencies, by their decision to make changes in the source file after which you want to be updated. Establish the appropriate .d file for each source file which is the recommended way GNU Make.
  • Makefile targets (Targets)
    The following is a Makefile target on this offer and the completion of its features:
    • make
      the compiler and linker. Equivalent to make all.
    • make objs
      only .o compiler generates object files, no connections (rarely used alone).
    • make clean
      delete object files generated by the compiler and dependencies.
    • make cleanall
      delete the target file, dependent files and executable files.
    • make rebuild
      re-compile and link the program. Equivalent to make clean && make all.

Makefile for this implementation principle not prepared a detailed explanation. If you are interested, you can refer to the end of the text listed in the "References."

Makefile reads as follows:
###############################################################################
#
# Generic Makefile for C/C++ Program
#
# Author: whyglinux (whyglinux AT hotmail DOT com)
# Date:   2006/03/04
# Description:
# The makefile searches in <SRCDIRS> directories for the source files
# with extensions specified in <SOURCE_EXT>, then compiles the sources
# and finally produces the <PROGRAM>, the executable file, by linking
# the objectives.
# Usage:
#   $ make           compile and link the program.
#   $ make objs      compile only (no linking. Rarely used).
#   $ make clean     clean the objectives and dependencies.
#   $ make cleanall  clean the objectives, dependencies and executable.
#   $ make rebuild   rebuild the program. The same as make clean && make all.
#==============================================================================
## Customizing Section: adjust the following if necessary.
##=============================================================================
# The executable file name.
# It must be specified.
# PROGRAM   := a.out    # the executable name
PROGRAM   :=
# The directories in which source files reside.
# At least one path should be specified.
# SRCDIRS   := .        # current directory
SRCDIRS   :=
# The source file types (headers excluded).
# At least one type should be specified.
# The valid suffixes are among of .c, .C, .cc, .cpp, .CPP, .c++, .cp, or .cxx.
# SRCEXTS   := .c      # C program
# SRCEXTS   := .cpp    # C++ program
# SRCEXTS   := .c .cpp # C/C++ program
SRCEXTS   :=
# The flags used by the cpp (man cpp for more).
# CPPFLAGS  := -Wall -Werror # show all warnings and take them as errors
CPPFLAGS  :=
# The compiling flags used only for C.
# If it is a C++ program, no need to set these flags.
# If it is a C and C++ merging program, set these flags for the C parts.
CFLAGS    :=
CFLAGS    +=
# The compiling flags used only for C++.
# If it is a C program, no need to set these flags.
# If it is a C and C++ merging program, set these flags for the C++ parts.
CXXFLAGS  :=
CXXFLAGS  +=
# The library and the link options ( C and C++ common).
LDFLAGS   :=
LDFLAGS   +=
## Implict Section: change the following only when necessary.
##=============================================================================
# The C program compiler. Uncomment it to specify yours explicitly.
#CC      = gcc
# The C++ program compiler. Uncomment it to specify yours explicitly.
#CXX     = g++
# Uncomment the 2 lines to compile C programs as C++ ones.
#CC      = $(CXX)
#CFLAGS  = $(CXXFLAGS)
# The command used to delete file.
#RM        = rm -f
## Stable Section: usually no need to be changed. But you can add more.
##=============================================================================
SHELL   = /bin/sh
SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))
OBJS    = $(foreach x,$(SRCEXTS), /
      $(patsubst %$(x),%.o,$(filter %$(x),$(SOURCES))))
DEPS    = $(patsubst %.o,%.d,$(OBJS))
.PHONY : all objs clean cleanall rebuild
all : $(PROGRAM)
# Rules for creating the dependency files (.d).
#---------------------------------------------------
%.d : %.c
        @$(CC) -MM -MD $(CFLAGS) $<
%.d : %.C
        @$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cc
        @$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cpp
        @$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.CPP
        @$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.c++
        @$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cp
        @$(CC) -MM -MD $(CXXFLAGS) $<
%.d : %.cxx
        @$(CC) -MM -MD $(CXXFLAGS) $<
# Rules for producing the objects.
#---------------------------------------------------
objs : $(OBJS)
%.o : %.c
        $(CC) -c $(CPPFLAGS) $(CFLAGS) $<
%.o : %.C
        $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cc
        $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cpp
        $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.CPP
        $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.c++
        $(CXX -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cp
        $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
%.o : %.cxx
        $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $<
# Rules for producing the executable.
#----------------------------------------------
$(PROGRAM) : $(OBJS)
ifeq ($(strip $(SRCEXTS)), .c)  # C file
        $(CC) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
else                            # C++ file
        $(CXX) -o $(PROGRAM) $(OBJS) $(LDFLAGS)
endif
-include $(DEPS)
rebuild: clean all
clean :
        @$(RM) *.o *.d
cleanall: clean
        @$(RM) $(PROGRAM) $(PROGRAM).exe
### End of the Makefile ##  Suggestions are welcome  ## All rights reserved ###
###############################################################################


Two examples provided below specifically illustrate usage Makefile above.

Example One Hello World program

function of this program is to output Hello, world! Such a line of text. By the hello.h, hello.c, main.cxx three files. The first two files are C program, the latter is a C ++ program, so this is a mixed C and C ++ programs.
/* File name: hello.h
 * C header file
 */
#ifndef HELLO_H
#define HELLO_H
#ifdef __cplusplus
extern "C" {
#endif
  void print_hello();
#ifdef __cplusplus
}
#endif
#endif

/* File name: hello.c
 * C source file.
 */
#include "hello.h"
#include <stdio.h>
void print_hello()
{
  puts( "Hello, world!" );
}


/* File name: main.cxx
 * C++ source file.
 */
#include "hello.h"
int main()
{
  print_hello();
  return 0;
}


To create a new directory, and then copy these three files to the directory, and copy the Makefile to the directory. After that, the Makefile related items set as follows:

PROGRAM   := hello      # 设置运行程序名
SRCDIRS   := .          # 源程序位于当前目录下
SRCEXTS   := .c .cxx    # 源程序文件有 .c 和 .cxx 两种类型
CFLAGS    := -g         # 为 C 目标程序包含 GDB 可用的调试信息
CXXFLAGS  := -g         # 为 C++ 目标程序包含 GDB 可用的调试信息


Because of this simple program using only the C standard library functions (puts), so for CFLAGS and CXXFLAGS no excessive demands, LDFLAGS and CPPFLAGS option is also no need to set.

After the above settings, you can execute the make command to compile the program. If no error occurs, then,. / Hello you can run the program.

If you modify the source code, you can only see and modify the relevant source file is compiled. Also you can add a new source file for the program, as long as their extension is already set in the Makefile, then there is no need to modify the Makefile.

Example Two GTK + version of the Hello World program

that GTK + version 2.0 Hello World program can be obtained from the following website: http: //www.gtk.org/tutorial/c58.html#SEC-HELLOWORLD. Of course, to compile GTK +, you also need on your system is already installed GTK +.

As with the first example, create a new directory separately, to save the program provided for the above web page main.c file. Makefile to make the following settings:

PROGRAM   := hello      # 设置运行程序名
SRCDIRS   := .          # 源程序位于当前目录下
SRCEXTS   := .c         # 源程序文件只有 .c 一种类型
CFLAGS    := `pkg-config --cflags gtk+-2.0`  # CFLAGS
LDFLAGS   := `pkg-config --libs gtk+-2.0`    # LDFLAGS


This is a C program, so there is no need CXXFLAGS settings - even if it is set, it will not be used.

Compiling and linking the required libraries GTK + CFLAGS and LDFLAGS pkg-config automatically generated by the program.

Now you can run make to compile,. / Hello GTK + perform this procedure.

References:
  • Multi-file projects and the GNU Make utility
    Author: George Foot
    http://www.elitecoders.de/mags/cscene/CS2/CS2-10.html
  • GNU Make Manual
    http://www.gnu.org/software/make/manual/

 

 

 

 

Reproduced in: https: //my.oschina.net/dake/blog/196853

Guess you like

Origin blog.csdn.net/weixin_33725515/article/details/91586321