http://www.blogjava.net/canvas/articles/quick_makefile.html

几个简单适合小程序的Makefile,可直接拷贝使用,自己mark一下,这样长时间不用Makefile也不用去看手册了

0.只有一个文件

# 变量的定义,方便使用
CC      = gcc
CCFLAGS = -O2 -s
BIN     = test
OBJ     = root_password_tool_win32.o

$(BIN) : $(OBJ)
    $(CC) $(CCFLAGS) -o test $(OBJ)

$(OBJ) : root_password_tool_win32.c
    $(CC) $(CCFLAGS) -c root_password_tool_win32.c

.PHONY : clean
clean :
    -rm $(BIN) $(OBJ)

1.简单编译命令行程序,$(CC)前面是tab,不是space

一共五个文件:
test.c
md5.c md5.h
password.c password.h

main函数在test.c中,test.c文件include了md5.h和password.h

CC      = gcc
CCFLAGS = -O2 -s
BIN     = password
OBJ     = md5.o password.o test.o

$(BIN) : $(OBJ)
    $(CC) $(CCFLAGS) -o password $(OBJ)

md5.o : md5.c md5.h
    $(CC) $(CCFLAGS) -c md5.c

password.o : password.c password.h
    $(CC) $(CCFLAGS) -c password.c

test.o : test.c
    $(CC) $(CCFLAGS) -c test.c

.PHONY : clean
clean :
    -rm $(BIN) $(OBJ)

make            # 编译得到password.exe,这里在windows下cigwin+mingw环境中编译
make clean    # 清理编译生成的*.o等文件

2.使用g++编译win32程序的Makefile,其中简写了一些,可以对比1看看不同之处
说明:
    (0)指定静态库目录,连接静态库libcomctl32.a编译程序
    (1)编译windows资源文件(使用mingw的windres)
    (2)使用-mwindows编译选项去除弹出的cmd窗口

CC      = g++

# -O2       : optimization option
# -s        : build small binary
# -mwindows : use this option to remove the popping cmd window
CCFLAGS = -O2 -s -mwindows
BIN     = test
WINDRES = windres
RES     = resource.o
OBJ     = main.o md5.o password.o $(RES)

# where is your mingw library?
LIBPATH = 'C:\Program Files\CodeBlocks\MinGW\lib\'

LIBS=-L$(LIBPATH) -lcomctl32

RM      = -rm

$(BIN): $(OBJ)
    $(CC) $(CCFLAGS) -o $(BIN) $(OBJ) $(LIBS)

main.o: main.cpp

md5.o: md5.cpp md5.h

password.o: password.cpp password.h

# 编译资源文件
$(RES): resource.rc rpt.ico manifest
    $(WINDRES) -o $(RES) resource.rc

.PHONY:clean
clean:
    $(RM) $(BIN) $(OBJ)

3.编译静态库
其中一些$<,$^, $@是Makefile的自动化变量,详细了解可以看《跟我一起写Makefile》的第五章

CC            = g++

OBJS         = utp.o utp_utils.o

# -g : for debug
CFLAGS        = -g -O2 -Wall -DPOSIX
TARGET        = libutp.a

.cpp.o:
    $(CC) -c $(CFLAGS) $<
    
all: $(TARGET)

libutp.a: $(OBJS)
    ar cru $@ $^
    ranlib $@
    
.PHONY : clean
clean :
    -rm *.o $(TARGET)

4.编译动态库
(0)windows下使用mingw编译dll动态库

CC      = g++
OBJS    = utp.o utp_utils.o
CCFLAGS = -fno-exceptions -fno-rtti -Wall -g -lwsock
TARGET  = libutp.dll

all: $(TARGET)

$(TARGET): $(OBJS)
    -rm -f $(TARGET)
    $(CC) -shared -o $(TARGET) $(OBJS) -lws2_32

.cpp.o:
    $(CC) -c -DPOSIX -fpic -I . -I utp_config_lib $(CCFLAGS) $<

.PHONY: clean
clean:
    -rm -f $(OBJS) $(TARGET)

(1)linux下编译so动态库

CC      = g++
OBJS    = utp.o utp_utils.o
CCFLAGS = -fno-exceptions -fno-rtti -Wall -g
TARGET  = libutp.so

all: $(TARGET)

$(TARGET): $(OBJS)
    -rm -f $(TARGET)
    g++ -shared -o $(TARGET) $(OBJS)

.cpp.o:
    g++ -c -DPOSIX -fpic -I . -I utp_config_lib $(CCFLAGS) $<

.PHONY: clean
clean:
    -rm -f $(OBJS) CCFLAGS

5.编译多个目标,0-2均是编译单个目标
(0) 添加头文件目录
(1) 使用自己编译的静态库libutp.a

CC          = g++ 
CFLAGS      = -g
LIBUTP_PATH = /home/actiontec/workspace/code_reading/third_party/libutp/lib
INCLUDES    = -I${LIBUTP_PATH}
LIBS        = -L$(LIBUTP_PATH) -lutp -lpthread -lrt
TARGET      = all

all: server client

server: server.cpp
    $(CC) $(CFLAGS) -o $@ $^ $(INCLUDES) $(LIBS)

client: client.cpp
    $(CC) $(CFLAGS) -o $@ $^ $(INCLUDES) $(LIBS)

.PHONY : clean
clean:
    -rm *.o server client

nmake命令(windows下的makefile)
http://blog.csdn.net/xiexievv/article/details/45775005

1. 如果已经有vc6的dsp工程,可直接导出nmake脚本文件(.mak)

“Project - Export Makefile...”

nmake -f nMakeTest.mak CFG="nMakeTest - Win32 Debug"

nmake -f nMakeTest.mak CFG="nMakeTest - Win32 Debug" all

nmake -f nMakeTest.mak CFG="nMakeTest - Win32 Release" clean

注:如果未指定/F选项,则使用当前目录下的名为makefile的文件

【nmake /?】  获取更多帮助!  vc6:【D:\program files\Microsoft Visual Studio\VC98\Bin】

vs2008:【D:\program files\Microsoft Visual Studio 9.0\VC\bin】

为了能正确地使用命令行工具及vc6或vs2008下的函数库,需要对一些环境变量进行设置,最快捷地方式是通过如下方式打开命令行窗口(以vs2008为例):

2. vs的c++工程没有提供导出nmake脚本文件的功能,我们只有借助工具或手动编写nmake脚本文件了

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

3. rc.exe 【将.rc资源文本转变成.res二进制文件】

/l 0x804  // 默认语言ID(十六进制数表示)  0x804:简体中文  0x409:美国  更多...

/fo"nMakeTest.res"  // 指定rc文件输出的res名称

例:rc.exe /l 0x804 /fo"nMakeTest.res" /d "_DEBUG" /d "_AFXDLL" “nMakeTest.rc”

4. cl.exe 常见选项 【将.c,.cpp,.cxx编译成obj文件】  更多...

/nologo   // 不打印版权申明信息

/I "../include"    // 添加头文件查找路径(如果路径中带有空格,一定要用引号括起来)

/DWIN32  // 预编译宏定义(win32程序)

/D_CONSOLE  // 预编译宏定义(控制台程序)

/D "_DEBUG"  // 预编译宏定义(Debug版本)

/D_CRT_SECURE_NO_DEPRECATE  // 预编译宏定义(关闭C4996警告。使用strcpy、strcat等不安全函数时会报C4996警告)

/D_CRT_NONSTDC_NO_DEPRECATE  // 预编译宏定义(关闭C4996警告。使用strcpy、strcat等不安全函数时会报C4996警告)

/Od  // 优化选项:带入Debug信息

/O2  // 优化选项:最快速度

/O1  // 优化选项:最小尺寸

/W3  // 设置3级警告级别

/WX     // 将Warining视为error

/Fp"nMakeTest.pch"  // 指定预编译文件名

/Yu"stdafx.h"   // 在生成期间使用预编译头文件

/FI "myheader.h" // 在每个源文件的第一行上的#include该文件

/Fd"vcpdb/testpdb" // 会将vc辅助编译的idb及pdb文件(见下面的/Gm选项)输入到vcpdb目录中,

并重命名为testpdb.idb与testpdb.pdb(这里的pdb为project database文件,用于存工程的数据库信息)

/Fo"objFiles" // 将obj文件输出到objFiles目录中

/c   // 编译但不链接

/feMyTest  // 编译后,输出MyTest.exe可执行文件

/EHsc   // 打开"C++例外(Exceptions)",以免出现编译器警告

/LD   // 创建动态链接库 
/LDd   // 创建调试动态链接库

/ML   // 使用 libc.lib 创建单线程可执行文件 
/MLd    // 使用 libcd.lib 创建调试单线程可执行文件 
/MT    // 使用 libcmt.lib 创建多线程可执行文件 
/MTd    // 使用 libcmtd.lib 创建调试多线程可执行文件 
/MD    // 使用 msvcrt.lib/msvcrt.dll 创建多线程可执行文件
/MDd    // 使用 msvcrtd.lib/msvcrtd.dll创建调试多线程可执行文件

/Z7   //生成与 C7.0兼容的调试信息 
/Zd   //生成行号 
/Zi    //生成完整的调试信息

/Gm     // 启用最小重新生成

编译器在.idb文件中存储源文件和类定义之间的依赖关系。
          使用.idb 文件的信息来确定是否需要编译某个源文件。
          而不是该源文件只要包含了被修改的.h文件,就必须重新编译。

/link  // 将/link后指定的选项传递给link.exe

// 默认情况下,cl.exe编译完后,会自动调用link.exe进行连接,
// 所以直接用cl.exe编译带main函数的.c或.cpp后,会生成obj与exe文件。

例:cl /c test1.cpp test2.cpp  // 编译test1.cpp,test2.cpp

例:cl *.cpp /MD /c /I"G:\Visual C++\VC98\PlatformSDK\Include"

5. link.exe常见选项  【将obj、lib、res链接成dll或exe等可执行文件】

/dll  // 输出dll文件

-lib  // 生成lib静态库文件  例:link -lib *.obj /out:test.lib

/libpath:"..\PublicSDK\lib" // 指定外部lib查找路径(路径中不能带有空格,否则链接时会报LNK1181的错误)

/subsystem:windows[console]   // 指定子系统

/machine 指定目标平台{AM33|ARM|EBC|IA64|M32R|MIPS|SH3|SH3DSP|SH4|SH5|THUMB|X86|X64},等

/NODEFAULTLIB:libcd.lib  // 链接时,忽略libcd.lib库

/debug  // 生成调试信息

/export:myAdd=_Add,@1   // 导出extern "C" Add函数,并将符号名修改为myAdd,同时将导出序号设为1(一种dll动态库导出符号的方法)

/export:_g_isTest,@2   // 导出extern "C" g_isTest变量,并将导出序号设为2(一种dll动态库导出符号的方法)

/def:"nMakeTest.def" // 模块导出文件【如果def文件名称与dll名称一致,则不需要显示地指出】(另外一种dll动态库导出符号的方法)

;nMakeTest.lib 导出DLL函数
;作者:kekec
LIBRARY nMakeTest.def
EXPORTS
Add @ 1
g_isTest @ 2

注:还可以在代码中使用__declspec(dllexport)进行符号的导出

#ifdef WIN32DLL_EXPORTS
#define WIN32DLL_API __declspec(dllexport)
#else
#define WIN32DLL_API __declspec(dllimport)
#endif

/************** export.c ***************/ 
#ifdef __cplusplus
extern "C"
{
#endif
    WIN32DLL_API int __stdcall Add(int a, int b)
    {
        return (a + b);
    }

WIN32DLL_API int g_isTest = 0;
#ifdef __cplusplus
}
#endif

/pdb:"nMakeTest.pdb"  // 重命名生成的pdb文件(Program Debug Database),保存调试符号等信息

/map:"nMakeTest.map" // 重命名生成的map文件

/out:"nMakeTest.exe" // 重命名生成的exe文件

/implib:"test.lib"  // 生成名为test.lib的导出库

/entry:_DllMainCRTStartup@12   // 指定_DllMainCRTStartup函数dll的起始地址

/incremental:yes   // 开启增量链接

incremental开关默认是开启的。
          开启增量链接产生的exe或dll文件的size要大一些。
          因为有代码和数据的填充,增量链接的exe或dll文件会包含跳转trunk来处理函数重定位到新地址。 
          MSDN上明确指出:为确保最终发布版本不包含填充或者trunk,请关闭增量链接。

例:link gdiplus.lib /subsystem:windows /out:test.exe file1.obj file2.lib file3.res // 生成名为test.exe的windows可执行程序
例:link gdiplus.lib /subsystem:console /out:test.exe *.obj file2.lib file3.res // 生成名为test.exe的控制台可执行程序
例:link gdiplus.lib /subsytem:windows /dll /out:test.dll /implib:test.lib /def:test.def *.obj file2.lib file3.res // 生成名为test.dll动态库

例:link *.obj rc.res /LIBPATH:"G:\Visual C++\lib" /SUBSYSTEM:WINDOWS /MACHINE:X86 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib OpenGL32.Lib

6. nmake指令说明

(1) 符号说明

#   // 注释符(命令所在行不能使用注释符,命令应该与注释都独立使用一行进行书写;如:erase nMakeTest.obj  # 删除nMakeTest.obj文件【非法】)

^#abc  // 表示#abc这个字符串

\  // 连接符,用于将两行合并为一行;在宏中,分多行写时,一定要用"\"进行连接

%  // 文件说明符,表示其后的字符串为一文件名

---------------------

若文件名为 c:\prog.exe
%s 将为 c:\prog.exe 
%:F 将为 c:\prog.exe
%:dF 将为 c
%:pF 将为 c:\
%:fF 将为 prog
%:eF 将为 exe

---------------------

@  // 命令修饰符;防止修饰的命令的结果,被打印出来

!       // 命令修饰符

  $  // 宏引用符

:  // 依赖符号

  ?【*】  // 通配符支持

++++++++++++++++++++++++++++++++++++

$@   // 表示所有目标全名(路径+文件名称+扩展名)的挨个值

$$@  // 与$@用法含义一致,但仅在作为依赖项中的依赖项时有效

$<   // 表示所有依赖目标的挨个值,仅在推理规则的命令中有效

$^   // 表示所有依赖目标的集合,以空格分隔,若有重复,会被去重;

$+   // 与$^含义一致,只是不进行去重处理。
     $?    // 表示所有比目标心的依赖目标的集合,以空格分隔

$*    // 当前目标的路径和文件名称,没有文件扩展名
     $**  // 当前目标的所有依赖项

----------------------------

修饰符   说明  
D         驱动器和目录  
B         文件名称  
F         文件名称和扩展名  
R         驱动器、目录和文件名称

----------------------------

(2) 长文件名用双引号引起来

  例:ALL : nMakeTest.dll  // 文件名较短时,可不需要引号
  例:ALL : "$(OUTDIR)\nMakeTest.exe" // 文件名较长时,特别是路径中有空格的情况,一定要用引号

(3) 预定义规则

.c.obj    // 默认操作:cl /c $*.c

也可对默认操作显示地重写:

.c.obj:
    cl /c /Ox /DWIN32 $<

(4) 包含文件

!INCLUDE nmake.opt

include makefile.mak

(5) 条件判断 - 01

!IF "$(CFG)" == ""
CFG=nMakeTest - Win32 Debug
!MESSAGE No configuration specified. Defaulting to nMakeTest - Win32 Debug.
!ELSE
!MESSAGE Be specified.
!ENDIF

(6) 条件判断 - 02  【!IFNDEF   !IFDEF】

!IFNDEF PRIVATE_RUNTIMEMODE_DEBUG
RUNTIMEMODE_DEBUG = /MDd 
!ELSE
RUNTIMEMODE_DEBUG = $(PRIVATE_RUNTIMEMODE_DEBUG)
!ENDIF

(7) 输出消息日志

!MESSAGE Invalid configuration "$(CFG)" specified.

(8) 描述块 - makefile的核心 【注:在依赖项(或规则)和命令块之间不能出现空行,commands之前为一个tab字符,多条command之间用;分割】

只要dependences中任意一个文件比targets新,就执行commands命令

targets... : dependences...
  commands...

(9) ALL / CLEAN

OUTDIR=.\Release
INTDIR=.\Release
ALL : "$(OUTDIR)\nMakeTest.exe"
CLEAN :
  -@erase "$(INTDIR)\nMakeTest.obj"
  -@erase "$(INTDIR)\nMakeTest.pch"
  -@erase "$(INTDIR)\nMakeTest.res"
  -@erase "$(INTDIR)\nMakeTestDlg.obj"
  -@erase "$(INTDIR)\StdAfx.obj"
  -@erase "$(INTDIR)\vc60.idb"
  -@erase "$(OUTDIR)\nMakeTest.exe"
  -@erase "$(OUTDIR)\nMakeTest.map"
"$(OUTDIR)" :
  if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"

(10) 编译

CPP=cl.exe
CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)\nMakeTest.pch" /Yu"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 
.c{$(INTDIR)}.obj::
  $(CPP) @<<
  $(CPP_PROJ) $< 
<<
.cpp{$(INTDIR)}.obj::
  $(CPP) @<<
  $(CPP_PROJ) $< 
<<
.cxx{$(INTDIR)}.obj::
  $(CPP) @<<
  $(CPP_PROJ) $< 
<<

(11) 链接

LINK32=link.exe
LINK32_FLAGS=/nologo /subsystem:windows /incremental:no /pdb:"$(OUTDIR)\nMakeTest.pdb" /map:"$(INTDIR)\nMakeTest.map" /machine:I386 /out:"$(OUTDIR)\nMakeTest.exe" 
LINK32_OBJS= \
  "$(INTDIR)\nMakeTest.obj" \
  "$(INTDIR)\nMakeTestDlg.obj" \
  "$(INTDIR)\StdAfx.obj" \
  "$(INTDIR)\nMakeTest.res"
"$(OUTDIR)\nMakeTest.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
   $(LINK32) @<<
  $(LINK32_FLAGS) $(LINK32_OBJS)
<<

(12) 文件依赖

SOURCE=.\nMakeTest.cpp
"$(INTDIR)\nMakeTest.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\nMakeTest.pch"
SOURCE=.\nMakeTest.rc
"$(INTDIR)\nMakeTest.res" : $(SOURCE) "$(INTDIR)"
$(RSC) $(RSC_PROJ) $(SOURCE)

(13) 预编译文件

SOURCE=.\StdAfx.cpp
!IF "$(CFG)" == "nMakeTest - Win32 Release"
CPP_SWITCHES=/nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)\nMakeTest.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c 
"$(INTDIR)\StdAfx.obj" "$(INTDIR)\nMakeTest.pch" : $(SOURCE) "$(INTDIR)"
  $(CPP) @<<
 $(CPP_SWITCHES) $(SOURCE)
<<
!ELSEIF "$(CFG)" == "nMakeTest - Win32 Debug"
CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"$(INTDIR)\nMakeTest.pch" /Yc"stdafx.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c 
"$(INTDIR)\StdAfx.obj" "$(INTDIR)\nMakeTest.pch" : $(SOURCE) "$(INTDIR)"
  $(CPP) @<<
 $(CPP_SWITCHES) $(SOURCE)
<<
!ENDIF

转载于:https://www.cnblogs.com/jukan/p/5923060.html

几个简单的Makefile相关推荐

  1. 一个最简单的Makefile例子(转)

    原文地址:http://hi.baidu.com/hellosim/blog/item/42e78341b40c3e8db2b7dce3.html 转载请注明出处 1.hello.c #include ...

  2. 生成简单的Makefile文件(Python实现)

    在linux下写几个测试程序,还要一行行的输入g++命令进行编译,当经常改测试代码的时候,那一次次的敲(或者一次次的上线箭头选)也感觉不爽,不如make来的快.用Makefile的好处就不用多说了,这 ...

  3. Makefile:简单的makefile列子

    现在我要编译一个Hello world,需要如下三个文件: 1. print.h #include<stdio.h> void printhello(); 2. print.c #incl ...

  4. 一个简单的makefile编写VCS仿真

    一个简单的makefile编写VCS仿真 1 VCS简介 VCS是编译型Verilog模拟器,它完全支持OVI标准的Verilog HDL语言.PLI和SDF. VCS具有行业中较高的模拟性能,其出色 ...

  5. 简单的makefile文件编写

    习惯了windows下ide创建工程已经代码的编写,然后一键运行,很简单,因为很多事ide都帮我们做了,但是linux下不一样,需要手动编译,执行一条条的命令,一般工程都是由于很多文件组成的,比如c+ ...

  6. Makefile编写及一个简单的Makefile架构实现

    Makefile编写及一个简单的Makefile架构实现 Makefile常用命令 GCC/G++常用编译参数 简单Makefile框架实现 使用CMake构建项目 Makefile常用命令 make ...

  7. 关于linux模块驱动简单的Makefile

    ( 转)嵌入式Linux驱动开发笔记 Linux驱动一般以模块module的形式来加载,首先需要把驱动编译成模块的形式.简单的例子, Begin of hello.c file #include &l ...

  8. 简单的makefile模板

    makefile不是总用到,每次用到的时候总要重新找资料,有点麻烦(怪自己基础知识不扎实,汗).留一个通用模板放这,方便以后使用 CC = gcc CXX = g++ LINK = g++ CFLAG ...

  9. 一个简单的Makefile

    下面是Makefile的代码:由源文件sum.c和compare.c编译成.o文件,再链接成sum可执行文件.(在当前目录下面输入make就可执行) sum: sum.o compare.ogcc - ...

最新文章

  1. 打一针就可修复受损心脏,“癌症克星”CAR-T跨界疗法登上Science封面
  2. Dijkstra算法实现
  3. redis和kafka比较
  4. C# 读取根目录的json文件中的某个值
  5. HTML5学习笔记(一):初步印象
  6. 学习日记16、easyui editor datagrid 动态绑定url
  7. 第四章 Python数据分析-描述性分析
  8. 谈谈谈zookeeper
  9. 【5G核心网】 NGAP 消息
  10. 跟我学RocketMQ之批量消息发送源码解析
  11. 2017.10.19 測試總結并今日總結
  12. Js 获取当前时间上一个月 YYYY-mm
  13. 如何将计算机删除的程序还原,如何去恢复电脑上误删的文件?简单恢复
  14. 诗词欣赏,沁园春政治与经济
  15. zabbix学习4: 监控Java原理-zabbix性能优化-低级自动发现-zabbix api
  16. matlab同轴电缆能量密度,导体电介质和磁介质之同轴电缆的能量密度.ppt
  17. 微信小程序参数二维码的8大使用场景
  18. Strange Printer
  19. 湖泊水库水质安全监测系统解决方案
  20. 基于QT平台webapi科大讯飞语音机器人

热门文章

  1. 咸鸭蛋吃了对身体有什么好处?
  2. Exynos1080处理器性能与功耗究竟怎么样?
  3. 空调开28度,一晚上会消耗多少电?空调耗电量与什么有关?
  4. 加盟商最大的顾虑是什么?
  5. 过去几年的互联网经济,首先是“免费经济”
  6. 想赚钱?找自己的长板!
  7. 为什么大家都会往大城市跑
  8. Tomcat logs 目录下各日志文件的含义
  9. t–sql pl–sql_不正确SQL Server统计信息– SQL查询性能的杀手–基本知识
  10. 用Navicat连接MySQL数据库出现1251错误:密码方式错误