• 理解make/makefile/cmake/qmake和Makefile编写规则


    5分钟理解make/makefile/cmake/nmake
    make makefile cmake qmake都是什么,有什么区别?

    1.理解qmake、cmake、makefile、make相关概念

    最近,有没有被make、cmake、makefile 这些东西绕晕了,看看下面的文章,也许就可以理解清楚了。

    1. gcc

    它是GNU Compiler Collection(就是GNU编译器套件),也可以简单认为是编译器,它可以编译很多种编程语言(括C、C++、Objective-C、Fortran、Java等等)。
    我们的程序只有一个源文件时,直接就可以用gcc命令编译它。
    可是,如果我们的程序包含很多个源文件时,该咋整?用gcc命令逐个去编译时,就发现很容易混乱而且工作量大,所以出现了下面make工具。

    2. make

    make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用makefile文件中用户指定的命令来进行编译和链接的。

    3. makefile

    这个是啥东西?
    简单的说就像一首歌的乐谱,make工具就像指挥家,指挥家根据乐谱指挥整个乐团怎么样演奏,make工具就根据makefile中的命令进行编译和链接的。makefile命令中就包含了调用gcc(也可以是别的编译器)去编译某个源文件的命令。
    makefile在一些简单的工程完全可以人工拿下,但是当工程非常大的时候,手写makefile也是非常麻烦的,如果换了个平台makefile又要重新修改,这时候就出现了下面的Cmake这个工具。

    4. cmake

    cmake就可以更加简单的生成makefile文件给上面那个make用。当然cmake还有其他更牛X功能,就是可以跨平台生成对应平台能用的makefile,我们就不用再自己去修改了。
    可是cmake根据什么生成makefile呢?它又要根据一个叫CMakeLists.txt文件(学名:组态档)去生成makefile。

    5. CMakeList.txt

    到最后CMakeLists.txt文件谁写啊?亲,是你自己手写的。当然简单的工程自己手写makefile也是基本操作。

    6.qmake是什么,先说一下Qt这个东西。

    Qt是跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器,简单的说就是C++的第三方库。

    你可以用Qt简简单单就实现非常复杂的功能,是因为Qt对C++进行了扩展,你写一行代码,Qt在背后帮你写了几百上千行,而这些多出来的代码就是靠Qt专有的moc编译器(The Meta-Object Compiler)和uic编译器(User Interface Complier)来重新翻译你那一行代码。问题来了,你在进行程序编译前就必须先调用moc和uic对Qt源文件进行预处理,然后再调用编译器进行编译。上面说的那种普通makefile文件是不适用的,它没办法对qt源文件进行预处理。所以qmake就产生了。

    qmake工具就是Qt公司制造出来,用来生成Qt 专用makefile文件,这种makefile文件就能自动智能调用moc和uic对源程序进行预处理和编译。qmake当然必须也是跨平台的,跟cmake一样能对应各种平台生成对应makefile文件。

    qmake是根据Qt 工程文件(.pro)来生成对应的makefile的。工程文件(.pro)相对来说比较简单,一般工程你都可以自己手写,但是一般都是由Qt的开发环境 Qt Creator自动生成的,你还是只需要按下那个邪恶三角形就完事了。
    还没有完,由于qmake很简单很好用又支持跨平台,而且是可以独立于它的IDE,所以你也可以用在非Qt工程上面,照样可以生成普通的makefile,只要在pro文件中加入CONFIG -= qt 就可以了。

    2. Makefile的编写

    关于Makefile的编写推荐下面的教程
    跟我一起写makefile
    认识Make、Makefile、CMake和CMakeLists

    1、生成可执行文件的makefile

    ######################################
    ######################################
    
    # source file
    SOURCE  := $(wildcard *.c) $(wildcard *.cpp)
    OBJS    := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE))) 
    
      
    # target you can change test to what you want
    # 目标文件名,输入任意你想要的执行文件名
    TARGET  := test
    
      
    
    #compile and lib parameter
    #编译参数
    CC      := gcc      #编译器
    LIBS    :=          #链接哪些库
    LDFLAGS :=          #lib库路径
    DEFINES :=
    INCLUDE := -I.
    CFLAGS  := -g -Wall -O3 $(DEFINES) $(INCLUDE)  #-g -Wall -O3 -Iinclude
    
    # CFLAGS 表示用于 C 编译器的选项,CXXFLAGS 表示用于 C++ 编译器的选项
    CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H         
    
    #i think you should do anything here
    #下面的基本上不需要做任何改动了
    .PHONY : everything objs clean veryclean rebuild
    everything : $(TARGET)
    all : $(TARGET)
    objs : $(OBJS)
    
      
    
    rebuild: veryclean everything
    clean :
        rm -fr *.so
        rm -fr *.o
    
    veryclean : clean
        rm -fr $(TARGET)
    
    $(TARGET) : $(OBJS)
        $(CC) $(CXXFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(LIBS)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    2、生成静态链接库的makefile

    ######################################
    ######################################
    #target you can change test to what you want
    #共享库文件名,lib*.a
    
    TARGET  := libtest.a
    
      
    
    #compile and lib parameter
    #编译参数
    CC      := gcc
    AR      = ar
    RANLIB  = ranlib
    LIBS    :=
    LDFLAGS :=
    DEFINES :=
    INCLUDE := -I.
    CFLAGS  := -g -Wall -O3 $(DEFINES) $(INCLUDE)
    
    CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H
    
      
    
    #i think you should do anything here
    #下面的基本上不需要做任何改动了
    #source file
    #源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件
    SOURCE  := $(wildcard *.c) $(wildcard *.cpp)
    OBJS    := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))
    
      
    
    .PHONY : everything objs clean veryclean rebuild
    everything : $(TARGET)
    all : $(TARGET)
    objs : $(OBJS)
    rebuild: veryclean everything
    clean :
        rm -fr *.o
    veryclean : clean
        rm -fr $(TARGET)
    
     
    $(TARGET) : $(OBJS)
        $(AR) cru $(TARGET) $(OBJS)
        $(RANLIB) $(TARGET)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    3、生成动态链接库的makefile

    ######################################
    ######################################
    #target you can change test to what you want
    #共享库文件名,lib*.so
    TARGET  := libtest.so
    
    #compile and lib parameter
    #编译参数
    CC      := gcc
    LIBS    :=
    LDFLAGS :=
    DEFINES :=
    INCLUDE := -I.
    CFLAGS  := -g -Wall -O3 $(DEFINES) $(INCLUDE)
    
    CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H
    
    SHARE   := -fPIC -shared -o
    
    #i think you should do anything here
    #下面的基本上不需要做任何改动了
    #source file
    #源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件
    SOURCE  := $(wildcard *.c) $(wildcard *.cpp)
    OBJS    := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))
    
      
    
    .PHONY : everything objs clean veryclean rebuild
    everything : $(TARGET)
    all : $(TARGET)
    objs : $(OBJS)
    
    rebuild: veryclean everything
    clean :
        rm -fr *.o
    veryclean : clean
        rm -fr $(TARGET)
    
      
    $(TARGET) : $(OBJS)
        $(CC) $(CXXFLAGS) $(SHARE) $@ $(OBJS) $(LDFLAGS) $(LIBS)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    makefile生成可执行文件、静态库、动态库模板

    3. 通用的makefile的编写,和上面的大同小异

    通用MAKEFILE的编写和在项目工程中使用MAKEFILE(包括动态库、静态库的链接、整个工程联合编译)
    几个Makefile通用模板分享!

    https://blog.csdn.net/SunXiWang/article/details/78701130
    https://blog.csdn.net/qq_20553613/article/details/90649734

  • 相关阅读:
    如何从任何苹果、Windows或安卓设备访问iCloud照片
    还在为如何编写Web自动化测试用例而烦恼嘛?资深测试工程师手把手教你Selenium 测试用例编写
    论文精度 —— 2018 CVPR《Generative Image Inpainting with Contextual Attention》
    Maxcompute SQL 的查询结果条数受限1W
    2311rust过程宏的示例
    maven assembly打包生成Java应用启动脚本bat和sh
    【易忽视】方程两边同时平方会改变方程的解吗?【简洁证明】
    【华为OD机试真题 JS】一种字符串压缩表示的解压
    Hadoop面试题+详解
    Python-魔法函数
  • 原文地址:https://blog.csdn.net/tywwwww/article/details/126876646