zoukankan      html  css  js  c++  java
  • c++跨平台技术学习(二)--使用跨平台的Make系统

    make主要用在代码移植性上。跨平台管理编译工作有好几种方法,每种的核心都是一个叫make的程序,这是一个跨平台的工具。

    Make

    假如你有一个程序叫做bar,它由bar.cpp和main.cpp两个C++源文件以及一个bar.h头文件组成

    main.cpp

    #include "bar.h"
    int main(int argc, char *argv[]) {
        Bar bar;
        bar.SetBar(17);
        bar.PutBar();
    
    }

    bar.h

    #pragma once
    #ifndef  _BAR_00__
    #define  _BAR_00__
    class Bar {
    public:
        void SetBar(int bar);
        void PutBar();
    private:
        int m_bar;
    
    };
    #endif // ! _BAR_00__

    bar.cpp

    #include<stdlib.h>
    #include<stdio.h>
    #include "bar.h"
    void Bar::SetBar(int bar) {
        m_bar = bar;
    }
    void Bar::PutBar() {
        char buf[16];
        snprintf(buf, sizeof(buf) - 1, "% d", m_bar);
        setenv("BAR", buf, 1);
    }

    bar对象维护了一个整数m_bar.m_bar的值由SetBar()决定,而PutBar()函数则把m_bar的值存到环境变量BAR里。

    从创建一个简单脚本build.sh开始,把它编译链接为一个bar应用程序

    #! /bin/sh
    g++ -g -o bar bar.cpp main.cpp

    随后执行

    sh build.sh

    make工具按照一定的依赖规则来执行一组命令,以获得需要的目标或结果。上面例子中,目标就是可执行文件bar,它依赖于源文件bar.cpp和main.cpp,而用来生成可执行文件的命令是

    g++ -o bar bar.cpp main.cpp

    make要求在一个文件里指定目标,依赖关系和命令,通常这个文件的名字是Makefile,下面这个makefile同样可以编译我们的例子

    bar:bar.cpp main.cpp
    g++ -g -o bar bar.cpp main.cpp

    有了Makefile之后,只需要键入下列命令

    make

    然后make就会为我们生成bar程序

    make如何处理shell脚本带来的问题:

    • make没彻底消除可移植性,在windows上,make并不像linux活mac上那样是原生应用程序.
    • makefile并没有解决指定不同编译器编译项目的问题。
    • 命令行参数依然是硬编码
    • make只会在源码的修改时间比可执行文件的修改时间万,才重新编译bar

      如何改进呢,重写makefile如下

    bar:bar.o main.o
       g++ -g -o bar main.o bar.o
    bar.o:bar.cpp bar.h
      g++ -g -c bar.cpp
    main.o:main.cpp bar.h
      g++ -g -c main.cpp

    上面的makefile通过引入两个新目标bar.o和main.o解决了依赖性的问题。现在依赖关系有了明确的目标,例如当bar.cpp和bar.h发生修改时,bar.o应该重新编译。bar自己的依赖关系也发生了变化,它不在依赖于源文件,而是依赖于目标文件。所以touch文件main.cpp后再执行make时,会得到以下结果

    touch main.cpp
    make
    g++ -g -c main.cpp
    g++ -g -o bar bar.o main.o

    注意到make只重新编译了目标main.o和bar,但是编译器和命令行参数仍旧是硬编码。这两个问题都可以用macro来解决

    OBJS=bar.o  main.o
    CXXFLAGS=-g
    barL $(OBJS)
             $(CXX) $(CXXFLAGS) -o $@ $(OBJS)
    bar.o:bar.cpp bar.h
             $(CXX) $(CXXFLAGS) -c bar.cpp
    main.o:main.cpp bar.h
             $(CXX) $(CXXFLAGS) -c main.cpp)

    如果你注意到所有的.o文件其实都只依赖于对应的.cpp文件和bar.h的话,我们可以进一步改进Makefile,通过额外的make机制如模式规则(pattern rules),Makefile可以简化为:

    OBJS=bar.o main.o
    CXXFLAGS= -g
    bar:$(OBJS)
          $(CXX) $(CXXFLAGS) -o $@(OBJS)
    % o:%.cpp
          $(CXX) $(CXXFLAGS) -c $ <
    $(OBJS):bar.h

    问题依然存在,把-g 提取出来放到CXXFLAGS里确实是一大进步,但是依然是Makefile里的硬编码,what’s more terrible,它和编译器脱离开来了,如果CXX不是使用g++,那么-g可能会在别的编译器上有完全不同的意思

    未完待续……

  • 相关阅读:
    Python函数
    mysql实现体温管理系统
    python操作Mysql
    Python列表,元祖
    word中标题去掉前面的点
    关于浏览器被劫持解决方法
    小程序开发问题
    微信小游戏开发
    yii2修改默认控制器和布局视图
    yii2的url美化设置
  • 原文地址:https://www.cnblogs.com/ainima/p/6331778.html
Copyright © 2011-2022 走看看