Makefile基本指令

语法规则

基本规则

目标 ... : 依赖 ...
	命令1
	命令2
	. . .

1、目标即要生成的文件。如果目标文件的更新时间晚于依赖文件更新时间,则说明依赖文件没有改动,目标文件不需要重新编译。否则会进行重新编译并更新目标文件。

2、默认情况下Makefile的第一个目标为终极目标。

3、依赖:即目标文件由哪些文件生成。

4、命令:即通过执行命令由依赖文件生成目标文件。注意每条命令之前必须有一个tab保持缩进,这是语法要求(会有一些编辑工具默认tab为4个空格,会造成Makefile语法错误)。

5、all:Makefile文件默认只生成第一个目标文件即完成编译,但是我们可以通过all 指定所需要生成的目标文件。

清空编译

每个Makefile中都应该写一个清空目标文件(.o和执行文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。这是一个“修养”(呵呵,还记得我的《编程修养》吗)。一般的风格都是:

   clean:
       rm edit $(objects)

更为稳健的做法是:

   .PHONY : clean
   clean :
   		-rm edit $(objects)

前面说过,.PHONY意思表示clean是一个“伪目标”,。而在rm命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。当然,clean的规则不要放在文件的开头,不然,这就会变成make的默认目标,相信谁也不愿意这样。不成文的规矩是——“clean从来都是放在文件的最后”

自动推导

常规写法如下:
objects = main.o kbd.o command.o display.o
insert.osearch.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
make很强大,它可以自动推导文件以及文件依赖关系后面的命令,只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 也会被推导出来。于是上述可以更新如下:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.o

edit : $(objects)
cc -o edit $(objects)

main.o : defs.h
这也是makefile的隐晦规则。

常用指令

  1. 获取系统名字:
    • UNAME := $(shell uname) 对于Linux,它可能返回"Linux",对于Mac OS,它可能返回"Darwin"
    • OSNAME := $(shell ver) 命令的输出是 “Microsoft Windows [Version 10.0.19041.867]”
  2. 打印输出变量 @echo “Flags: $(CFLAGS)”
  3. find . -maxdepth 10 -type d 从当前目录搜索所有子级目录(搜素深度为10级),-type d表示只查找目录。

生成动态链接库

需要对外暴露的函数使用 __declspec(dllexport) 加在函数前。

  1. 生成命令:gcc -shared -o my.dll build/my.o build/fun1.o

  2. c++ 加载动态库
    注意visual studio中使用x64进行编译(因为gcc是64位版本),否则会加载动态库失败。

    #ifdef _MSC_VER
    #include <winsock2.h> /* For struct timeval */
    #endif
    void DynamicUse()
    {
        // 运行时加载DLL库
        HMODULE module = LoadLibraryA("xxx.dll");     // 根据DLL文件名,加载DLL,返回一个模块句柄
        if (module == NULL)
        {
            printf("加载DLLTest1.dll动态库失败\n");
            return;
        }
        typedef int(*AddFunc)(const char*, int,int,int,int);                  // 定义函数指针类型
        AddFunc generate_mbd;
        // 导出函数地址
        generate_mbd = (AddFunc)GetProcAddress(module, "generate_mbd");     // GetProcAddress返回指向的函数名的函数地址
    
        string file_name = "./photo.png";
        const char* name = file_name.c_str();
    
        int sum = generate_mbd(name, 110, 105, 30, 1);
        printf("动态调用,sum = %d\n", sum);
    }
    
  3. python 加载dll

    from ctypes import *
    #dll = CDLL("export.dll")
    dll = windll.LoadLibrary("export.dll")
    dll.say_hello()
    

报错以及解决

注意 win系统下要在vscode 中的git bash下进行编译。

  1. “XXX is up to date”问题的解决办法 删除曾经makefile生成的文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AICVer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值