make文件是怎么回事? 你要定义一个告诉make如何工作的makefile,类似于一个批命令文件,可语法是make的语法,可以很复杂。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 //抱歉,忘了作者了Wisual C++ Documentation->Using Visual C++->Visual C++User's Guide ->Working with Projects ->Overview NMAKE reference。几乎所有的C/C++命令行工具里都有Make工具。Microsoft的叫做NMAKE,Borland的叫做Make。基本的语法都差不多。举一个例子:你开发一个最简单的Win32 Application.源文件如下://Generic.h#ifndef __GENERIC_H#define __GENERIC_H#include <windows.h>#define GENERICCLASS "GenericClass"#define GENERICWINDOW "Generic Window"LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM);BOOL CALLBACK AboutProc(HWND,UINT,WPARAM,LPARAM);#endif /*__GENERIC_H*///Generic.C#include <windows.h>#include "Generic.h"#include "resource.h"int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow){ WNDCLASSEX wcex; HWND hwnd; MSG msg; wcex.cbSize=sizeof(wcex); wcex.style=0; wcex.lpfnWndProc=MainWndProc; wcex.cbClsExtra=0; wcex.cbWndExtra=0; wcex.hInstance=hInstance; wcex.hIcon=LoadIcon(NULL,IDI_APPLICATION); wcex.hCursor=LoadCursor(NULL,IDC_ARROW); wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName=NULL; wcex.lpszClassName=GENERICCLASS; wcex.hIconSm=LoadIcon(NULL,IDI_APPLICATION); if (!RegisterClassEx(&wcex)) { return FALSE; } hwnd=CreateWindowEx(0, GENERICCLASS, GENERICWINDOW, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (!hwnd) { return FALSE; } ShowWindow(hwnd,nCmdShow); while (GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam;}LRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp){ static HINSTANCE hInstance; static HMENU hMenu; switch (message) { case WM_CREATE: { hInstance=((LPCREATESTRUCT)lp)->hInstance; hMenu=LoadMenu(hInstance,(LPSTR)IDR_MAINMENU); SetMenu(hwnd,hMenu); } return 0; case WM_COMMAND: { switch (LOWORD(wp)) { case IDM_EXIT: { char lpszQueryQuit[32]; char lpszQueryQuitCaption[32]; LoadString(hInstance,IDS_QUERYQUIT,lpszQueryQuit,32); LoadString(hInstance,IDS_QUERYQUITCAPTION,lpszQueryQuitCaption,32); if (MessageBox(hwnd,lpszQueryQuit,lpszQueryQuitCaption,MB_YESNO)==IDYES) { PostQuitMessage(0); } } return 0; case IDM_ABOUT: { return DialogBoxParam(hInstance, (LPSTR)IDD_ABOUT, hwnd, AboutProc, (LPARAM)hInstance); } return 0; default: break; } } return 0; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc; RECT rc; char lpszHello[32]; hdc=BeginPaint(hwnd,&ps); GetClientRect(hwnd,&rc); LoadString(hInstance,IDS_HELLO,lpszHello,32); DrawText(hdc,lpszHello,lstrlen(lpszHello),&rc,DT_CENTER); EndPaint(hwnd,&ps); } return 0; case WM_DESTROY: { PostQuitMessage(0); } return 0; default: break; } return DefWindowProc(hwnd,message,wp,lp);}BOOL CALLBACK AboutProc(HWND hwnd,UINT message,WPARAM wp,LPARAM lp){ static HINSTANCE hInstance; switch (message) { case WM_INITDIALOG: { hInstance=(HINSTANCE)hInstance; } return TRUE; case WM_COMMAND: { if ((LOWORD(wp)==IDOK)||(LOWORD(wp)==IDCANCEL)) { EndDialog(hwnd,0); } } return TRUE; default: break; } return FALSE;}//Generic.rc#include "resource.h"#include <windows.h>///////////////////////////////////////////////////////////////////////////////// Dialog//IDD_ABOUT DIALOG DISCARDABLE 0, 0, 187, 69STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENUCAPTION "Generic Dialog"FONT 10, "System"BEGIN DEFPUSHBUTTON "OK",IDOK,66,43,50,14 CTEXT "Generic Window 32 bits Application\nWriter Tian Wei", IDC_STATIC,24,15,136,18END///////////////////////////////////////////////////////////////////////////////// Menu//IDR_MAINMENU MENU DISCARDABLE BEGIN POPUP "&File" BEGIN MENUITEM "E&xit", IDM_EXIT END POPUP "&Help" BEGIN MENUITEM "&About", IDM_ABOUT ENDEND///////////////////////////////////////////////////////////////////////////////// String Table//STRINGTABLE DISCARDABLE BEGIN IDS_QUERYQUIT "Do you really want to quit?" IDS_QUERYQUITCAPTION "Confirm quitting" IDS_HELLO "Hello world!"END//resource.h#define IDS_QUERYQUIT 1#define IDS_QUERYQUITCAPTION 2#define IDS_HELLO 3#define IDD_ABOUT 101#define IDR_MAINMENU 102#define IDM_EXIT 40001#define IDM_ABOUT 40002#define IDC_STATIC -1现在你写一个如下的generic.mak,用于Microsoft的命令行工具。//generic.makmspath = d:\progra~1\micros~1\vc98 #这一行应该是你的VC的路径,不一定是我写的。linkpath = $(mspath)\bincpath = $(mspath)\binrpath = $(mspath)\bincincpath = $(mspath)\includecc = $(cpath)\cl.exe cflags = -c -I$(cincpath) rincpath = $(cincpath)rc = $(rpath)\rc.exerflags = -i$(rincpath) libpath = $(mspath)\liblink = $(linkpath)\link.exelinkflags = -subsystem:windows -libpath:$(libpath)crtlibs = libc.libwin32libs = kernel32.lib user32.lib gdi32.lib uuid.lib oldnames.lib advapi32.lib comctl32.lib comdlg32.lib shell32.lib shlwapi.lib comlibs = ole32.lib oleaut32.lib oledlg.lib deflibs = $(crtlibs) $(win32libs) $(comlibs)all: generic.exegeneric.obj: generic.c generic.h resource.h $(cc) $(cflags) generic.cgeneric.res: generic.rc resource.h $(rc) $(rflags) generic.rcgeneric.exe: generic.obj generic.res $(link) $(linkflags) -out:generic.exe generic.obj generic.res $(deflibs)最后,可以在控制台方式下这样运行NMAKE:namke -f"Generic.mak"当然,如果nmake的路径不再环境变量里,还要用全名。最后就会产生generic.obj,generic.res,generic.exe三个文件。如果用VC,那么在选择工程类型的时候要选择makefile,这样的话就可以正确的编译。当然,你会觉得每次写这么复杂的makefile太累了。VC的Include目录里边有一个Win32.mak,里边定义好了编译和连接用到的标志,比如generic.mak可以这么写:!include <win32.mak>all: generic.exegeneric.obj: generic.c generic.h resource.h $(cc) $(cdebug) $(cflags) $(cvars) generic.cgeneric.res: generic.rc resource.h $(rc) $(cdebug) $(rcvars) -r -fo generic.res generic.rcgeneric.exe $(link) $(linkdebug) $(guiflags) -out:generic.exe generic.obj generic.res $(guilibs)简单地说以#开头的是注释,以!开头的是一些控制语句, 比如!if !else !endif !include等等。以$开头并且用括号包起来的是常量。常量必须先定义。比如cc = cl.exe就把cc定义成了cl.exe以后遇到$(cc)就会被扩展成cl.exe。最重要的是依赖性。以下generic.obj: generic.c generic.h resource.h $(cc) $(cdebug) $(cflags) $(cvars) generic.c表示generic.obj依赖generic.c generic.h resource.h三个文件。如果其中一个被改动过,那么generic.obj叫要被重新建立。建立的方法是$(cc) $(cdebug) $(cflags) $(cvars) generic.c。all: generic.exe表示最终的目标是generic.exe makefile已经有了。vc下此文件是否名为nmake? vc下面也叫makefile。nmake.exe是读取makefile并且执行的程序。unix下面make是读取makefile并且执行的程序。 麻烦谁给我一份COM技术内幕的随书光盘 高手指教:如何打开某一.exe文件,通过编码实现,要求如下: 进程间的通讯问题 编译出错,请各位指点 VC高手进,紧急求助,在线等待? 我最要好的朋友的父亲得了乙型肝炎,快转成肝癌了,请问哪里有好的医院和治疗方法?(请版主不要删!帮忙置顶一下) 请教大虾在vc中如何操作word文件啊?! 文件 另存为 隐藏了文件的扩展名 打不开 关于模态对话框的问题 好像有一种比TOP_MOST还要更高级的窗口 win32 sdk 编程如何创建线程? 程序员大调查!!!
几乎所有的C/C++命令行工具里都有Make工具。Microsoft的叫做NMAKE,Borland的叫做Make。基本的语法都差不多。
举一个例子:
你开发一个最简单的Win32 Application.源文件如下:
//Generic.h
#ifndef __GENERIC_H
#define __GENERIC_H#include <windows.h>#define GENERICCLASS "GenericClass"
#define GENERICWINDOW "Generic Window"LRESULT CALLBACK MainWndProc(HWND,UINT,WPARAM,LPARAM);
BOOL CALLBACK AboutProc(HWND,UINT,WPARAM,LPARAM);#endif /*__GENERIC_H*///Generic.C#include <windows.h>
#include "Generic.h"
#include "resource.h"int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
WNDCLASSEX wcex;
HWND hwnd;
MSG msg;
wcex.cbSize=sizeof(wcex);
wcex.style=0;
wcex.lpfnWndProc=MainWndProc;
wcex.cbClsExtra=0;
wcex.cbWndExtra=0;
wcex.hInstance=hInstance;
wcex.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName=NULL;
wcex.lpszClassName=GENERICCLASS;
wcex.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
return FALSE;
}
hwnd=CreateWindowEx(0,
GENERICCLASS,
GENERICWINDOW,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if (!hwnd)
{
return FALSE;
}
ShowWindow(hwnd,nCmdShow);
while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}LRESULT CALLBACK MainWndProc(HWND hwnd,
UINT message,
WPARAM wp,
LPARAM lp)
{
static HINSTANCE hInstance;
static HMENU hMenu;
switch (message)
{
case WM_CREATE:
{
hInstance=((LPCREATESTRUCT)lp)->hInstance;
hMenu=LoadMenu(hInstance,(LPSTR)IDR_MAINMENU);
SetMenu(hwnd,hMenu);
}
return 0;
case WM_COMMAND:
{
switch (LOWORD(wp))
{
case IDM_EXIT:
{
char lpszQueryQuit[32];
char lpszQueryQuitCaption[32];
LoadString(hInstance,IDS_QUERYQUIT,lpszQueryQuit,32);
LoadString(hInstance,IDS_QUERYQUITCAPTION,lpszQueryQuitCaption,32);
if (MessageBox(hwnd,lpszQueryQuit,lpszQueryQuitCaption,MB_YESNO)==IDYES)
{
PostQuitMessage(0);
}
}
return 0;
case IDM_ABOUT:
{
return DialogBoxParam(hInstance,
(LPSTR)IDD_ABOUT,
hwnd,
AboutProc,
(LPARAM)hInstance);
}
return 0;
default:
break;
}
}
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc;
RECT rc;
char lpszHello[32];
hdc=BeginPaint(hwnd,&ps);
GetClientRect(hwnd,&rc);
LoadString(hInstance,IDS_HELLO,lpszHello,32);
DrawText(hdc,lpszHello,lstrlen(lpszHello),&rc,DT_CENTER);
EndPaint(hwnd,&ps);
}
return 0;
case WM_DESTROY:
{
PostQuitMessage(0);
}
return 0;
default:
break;
}
return DefWindowProc(hwnd,message,wp,lp);
}BOOL CALLBACK AboutProc(HWND hwnd,UINT message,WPARAM wp,LPARAM lp)
{
static HINSTANCE hInstance;
switch (message)
{
case WM_INITDIALOG:
{
hInstance=(HINSTANCE)hInstance;
}
return TRUE;
case WM_COMMAND:
{
if ((LOWORD(wp)==IDOK)||(LOWORD(wp)==IDCANCEL))
{
EndDialog(hwnd,0);
}
}
return TRUE;
default:
break;
}
return FALSE;
}//Generic.rc
#include "resource.h"
#include <windows.h>
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//IDD_ABOUT DIALOG DISCARDABLE 0, 0, 187, 69
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Generic Dialog"
FONT 10, "System"
BEGIN
DEFPUSHBUTTON "OK",IDOK,66,43,50,14
CTEXT "Generic Window 32 bits Application\nWriter Tian Wei",
IDC_STATIC,24,15,136,18
END
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//IDR_MAINMENU MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", IDM_EXIT
END
POPUP "&Help"
BEGIN
MENUITEM "&About", IDM_ABOUT
END
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//STRINGTABLE DISCARDABLE
BEGIN
IDS_QUERYQUIT "Do you really want to quit?"
IDS_QUERYQUITCAPTION "Confirm quitting"
IDS_HELLO "Hello world!"
END//resource.h
#define IDS_QUERYQUIT 1
#define IDS_QUERYQUITCAPTION 2
#define IDS_HELLO 3
#define IDD_ABOUT 101
#define IDR_MAINMENU 102
#define IDM_EXIT 40001
#define IDM_ABOUT 40002
#define IDC_STATIC -1现在你写一个如下的generic.mak,用于Microsoft的命令行工具。
//generic.mak
mspath = d:\progra~1\micros~1\vc98 #这一行应该是你的VC的路径,不一定是我写的。
linkpath = $(mspath)\bin
cpath = $(mspath)\bin
rpath = $(mspath)\bin
cincpath = $(mspath)\includecc = $(cpath)\cl.exe
cflags = -c -I$(cincpath) rincpath = $(cincpath)
rc = $(rpath)\rc.exe
rflags = -i$(rincpath) libpath = $(mspath)\lib
link = $(linkpath)\link.exe
linkflags = -subsystem:windows -libpath:$(libpath)crtlibs = libc.libwin32libs = kernel32.lib user32.lib gdi32.lib uuid.lib oldnames.lib advapi32.lib comctl32.lib comdlg32.lib shell32.lib shlwapi.lib comlibs = ole32.lib oleaut32.lib oledlg.lib deflibs = $(crtlibs) $(win32libs) $(comlibs)all: generic.exegeneric.obj: generic.c generic.h resource.h
$(cc) $(cflags) generic.cgeneric.res: generic.rc resource.h
$(rc) $(rflags) generic.rcgeneric.exe: generic.obj generic.res
$(link) $(linkflags) -out:generic.exe generic.obj generic.res $(deflibs)最后,可以在控制台方式下这样运行NMAKE:
namke -f"Generic.mak"
当然,如果nmake的路径不再环境变量里,还要用全名。
最后就会产生generic.obj,generic.res,generic.exe三个文件。
如果用VC,那么在选择工程类型的时候要选择makefile,这样的话就可以正确的编译。当然,你会觉得每次写这么复杂的makefile太累了。VC的Include目录里边有一个Win32.mak,里边定义好了编译和连接用到的标志,比如generic.mak可以这么写:!include <win32.mak>all: generic.exegeneric.obj: generic.c generic.h resource.h
$(cc) $(cdebug) $(cflags) $(cvars) generic.cgeneric.res: generic.rc resource.h
$(rc) $(cdebug) $(rcvars) -r -fo generic.res generic.rcgeneric.exe
$(link) $(linkdebug) $(guiflags) -out:generic.exe generic.obj generic.res $(guilibs)简单地说以#开头的是注释,以!开头的是一些控制语句, 比如!if !else !endif !include等等。以$开头并且用括号包起来的是常量。常量必须先定义。比如cc = cl.exe就把cc定义成了cl.exe以后遇到$(cc)就会被扩展成cl.exe。
最重要的是依赖性。
以下
generic.obj: generic.c generic.h resource.h
$(cc) $(cdebug) $(cflags) $(cvars) generic.c
表示generic.obj依赖generic.c generic.h resource.h三个文件。如果其中一个被改动过,那么generic.obj叫要被重新建立。建立的方法是$(cc) $(cdebug) $(cflags) $(cvars) generic.c。
all: generic.exe表示最终的目标是generic.exe
nmake.exe是读取makefile并且执行的程序。unix下面
make是读取makefile并且执行的程序。