Makefile和.Mak文件 + CodeBlocks和VStudio

4

我对整个makefile的概念还不是很了解,所以有一些问题需要解答:

我正在Linux中使用CodeBlocks创建一个项目,我使用了一个叫做cbp2mak的工具将CodeBlocks项目生成了一个 .make 文件(如果谁知道更好的工具,请告诉我)。

现在我不确定 .mak 和 .makefile 之间的区别是什么,有人可以告诉我吗?我可以使用 "make -C .mak" 编译 .mak 文件,但这两者有何区别呢?

我想要使用该文件的原因是:我希望为我的项目提供源代码,并希望它可以在Linux和Windows上都能构建,所以我不想给他们我的Codeblocks项目文件。所以我想使用一个可以用于在Linux和Windows上构建的makefile。

我也希望在Windows上检查MinGW和VC++编译器是否都存在,并使用这两种编译器构建源代码,在Linux上则仅使用GNU GCC。

.mak 文件还有一些宏来确定要构建什么,这取决于它是否在Windows或Linux上运行,因为有一些特定于平台的文件。

所以问题如下:

- .mak 和 .makefile 之间有什么区别?

- 我可以在Windows上运行 .mak 文件吗?可以使用Visual Studio吗?

- 是否有更好的解决方案?(我使用cpb2mak,因为它可以自动生成一个 .mak 文件,这样可以节省很多时间,因为我不知道如何创建makefile)

同时,如果您有任何建议或提示,请随时提供。

编辑:

我现在已经放出了完整的 .mak 文件。

另外,我的项目是一个库,我同时构建了静态和共享版本。.mak 文件是自动生成的,但我用 ifdef 和 "shell, uname" 函数添加了平台处理。

# project performer-1.0


export PATH := /opt/wx/2.8/bin:$(PATH)
export LD_LIBRARY_PATH := /opt/wx/2.8/lib:$(LD_LIBRARY_PATH)

_WX = /home/gr/projects/gui/codeblocks/wx
_WX.LIB = $(_WX)/lib
_WX.INCLUDE = $(_WX)/include

_CB = /home/gr/projects/gui/codeblocks/cb/src
_CB.INCLUDE = $(_CB)/include
_CB.LIB = $(_CB)/devel



CFLAGS_C = $(filter-out -include "sdk.h",$(CFLAGS))

# -----------------------------------------

# MAKE_DEP = -MMD -MT $@ -MF $(@:.o=.d)

CFLAGS = -Wall 
INCLUDES = -I../performer-1.0 
LDFLAGS =  -s
RCFLAGS = 
LDLIBS = $(T_LDLIBS) -lrt -lboost_regex-gcc43-mt -lxerces-c  -lstdc++

LINK_exe = gcc -o $@ $^ $(LDFLAGS) $(LDLIBS)
LINK_con = gcc -o $@ $^ $(LDFLAGS) $(LDLIBS)
LINK_dll = gcc -o $@ $^ $(LDFLAGS) $(LDLIBS) -shared
LINK_lib = rm -f $@ && ar rcs $@ $^
COMPILE_c = gcc $(CFLAGS_C) -o $@ -c $< $(MAKEDEP) $(INCLUDES)
COMPILE_cpp = g++ $(CFLAGS) -o $@ -c $< $(MAKEDEP) $(INCLUDES)
COMPILE_rc = windres $(RCFLAGS) -J rc -O coff -i $< -o $@ -I$(dir $<)

%.o : %.c ; $(COMPILE_c)
%.o : %.cpp ; $(COMPILE_cpp)
%.o : %.cxx ; $(COMPILE_cpp)
%.o : %.rc ; $(COMPILE_rc)
.SUFFIXES: .o .d .c .cpp .cxx .rc

all: all.before all.targets all.after

all.before :
    -
all.after : $(FIRST_TARGET)

# -----------------------------------------------------------
ifeq "$(shell uname)" "Linux"
# -----------------------------------------------------------
    
all.targets : Linux_Dynamic_target Linux_Static_target 

# -----------------------------------------------------------
else
# -----------------------------------------------------------

all.targets : Windows_Dynamic_target

# -----------------------------------------------------------
endif
# -----------------------------------------------------------

clean :
    rm -fv $(clean.OBJ)
    rm -fv $(DEP_FILES)

.PHONY: all clean distclean

# -----------------------------------------------------------
ifeq "$(shell uname)" "Linux"
# -----------------------------------------------------------

# -----------------------------------------
# Linux_Dynamic_target

Linux_Dynamic_target.BIN = libs/libperformer-1.so
Linux_Dynamic_target.OBJ = src/analysis/analyzer.o src/analysis/comparer.o src/analysis/paverage.o src/analysis/pfunctor.o src/analysis/pmax.o src/analysis/pmin.o src/config/configfile.o src/data_collection/datacollector.o src/data_collection/linux/linfactory.o src/data_collection/linux/linmemprof.o src/data_collection/linux/lintimer.o src/data_collection/linux/procsmaps.o src/data_collection/linux/procstatus.o src/data_collection/pstructs.o src/data_collection/resultxml.o 
DEP_FILES += src/analysis/analyzer.d src/analysis/comparer.d src/analysis/paverage.d src/analysis/pfunctor.d src/analysis/pmax.d src/analysis/pmin.d src/config/configfile.d src/data_collection/datacollector.d src/data_collection/linux/linfactory.d src/data_collection/linux/linmemprof.d src/data_collection/linux/lintimer.d src/data_collection/linux/procsmaps.d src/data_collection/linux/procstatus.d src/data_collection/pstructs.d src/data_collection/resultxml.d 
clean.OBJ += $(Linux_Dynamic_target.BIN) $(Linux_Dynamic_target.OBJ)

Linux_Dynamic_target : Linux_Dynamic_target.before $(Linux_Dynamic_target.BIN) Linux_Dynamic_target.after_always
Linux_Dynamic_target : CFLAGS += -Wall -g  -Os
Linux_Dynamic_target : INCLUDES += 
Linux_Dynamic_target : RCFLAGS += 
Linux_Dynamic_target : LDFLAGS +=  $(CREATE_LIB) $(CREATE_DEF)
Linux_Dynamic_target : T_LDLIBS = 
ifdef LMAKE
Linux_Dynamic_target : CFLAGS -= -O1 -O2 -g -pipe
endif

Linux_Dynamic_target.before :
    
    
Linux_Dynamic_target.after_always : $(Linux_Dynamic_target.BIN)
    
$(Linux_Dynamic_target.BIN) : $(Linux_Dynamic_target.OBJ)
    $(LINK_dll)

# -----------------------------------------
# Linux_Static_target

Linux_Static_target.BIN = libs/libperformer-1.a
Linux_Static_target.OBJ = src/analysis/analyzer.o src/analysis/comparer.o src/analysis/paverage.o src/analysis/pfunctor.o src/analysis/pmax.o src/analysis/pmin.o src/config/configfile.o src/data_collection/datacollector.o src/data_collection/linux/linfactory.o src/data_collection/linux/linmemprof.o src/data_collection/linux/lintimer.o src/data_collection/linux/procsmaps.o src/data_collection/linux/procstatus.o src/data_collection/pstructs.o src/data_collection/resultxml.o 
DEP_FILES += src/analysis/analyzer.d src/analysis/comparer.d src/analysis/paverage.d src/analysis/pfunctor.d src/analysis/pmax.d src/analysis/pmin.d src/config/configfile.d src/data_collection/datacollector.d src/data_collection/linux/linfactory.d src/data_collection/linux/linmemprof.d src/data_collection/linux/lintimer.d src/data_collection/linux/procsmaps.d src/data_collection/linux/procstatus.d src/data_collection/pstructs.d src/data_collection/resultxml.d 
clean.OBJ += $(Linux_Static_target.BIN) $(Linux_Static_target.OBJ)

Linux_Static_target : Linux_Static_target.before $(Linux_Static_target.BIN) Linux_Static_target.after_always
Linux_Static_target : CFLAGS += -Wall -g  -Os
Linux_Static_target : INCLUDES += 
Linux_Static_target : RCFLAGS += 
Linux_Static_target : LDFLAGS +=   $(CREATE_DEF)
Linux_Static_target : T_LDLIBS = 
ifdef LMAKE
Linux_Static_target : CFLAGS -= -O1 -O2 -g -pipe
endif

Linux_Static_target.before :
    
    
Linux_Static_target.after_always : $(Linux_Static_target.BIN)
    
$(Linux_Static_target.BIN) : $(Linux_Static_target.OBJ)
    $(LINK_lib)
    

# -----------------------------------------

# -----------------------------------------------------------
else
# -----------------------------------------------------------   

# -----------------------------------------
# Windows_Dynamic_target

Windows_Dynamic_target.BIN = libs/performer-1.so
Windows_Dynamic_target.OBJ = src/analysis/analyzer.o src/analysis/comparer.o src/analysis/paverage.o src/analysis/pfunctor.o src/analysis/pmax.o src/analysis/pmin.o src/config/configfile.o src/data_collection/datacollector.o src/data_collection/pstructs.o src/data_collection/resultxml.o src/data_collection/windows/winfactory.o src/data_collection/windows/wintimer.o 
DEP_FILES += src/analysis/analyzer.d src/analysis/comparer.d src/analysis/paverage.d src/analysis/pfunctor.d src/analysis/pmax.d src/analysis/pmin.d src/config/configfile.d src/data_collection/datacollector.d src/data_collection/pstructs.d src/data_collection/resultxml.d src/data_collection/windows/winfactory.d src/data_collection/windows/wintimer.d 
clean.OBJ += $(Windows_Dynamic_target.BIN) $(Windows_Dynamic_target.OBJ)

Windows_Dynamic_target : Windows_Dynamic_target.before $(Windows_Dynamic_target.BIN) Windows_Dynamic_target.after_always
Windows_Dynamic_target : CFLAGS += -Wall -g  -Os
Windows_Dynamic_target : INCLUDES += 
Windows_Dynamic_target : RCFLAGS += 
Windows_Dynamic_target : LDFLAGS +=  $(CREATE_LIB) $(CREATE_DEF)
Windows_Dynamic_target : T_LDLIBS = 
ifdef LMAKE
Windows_Dynamic_target : CFLAGS -= -O1 -O2 -g -pipe
endif

Windows_Dynamic_target.before :
    
    
Windows_Dynamic_target.after_always : $(Windows_Dynamic_target.BIN)
    
$(Windows_Dynamic_target.BIN) : $(Windows_Dynamic_target.OBJ)
    $(LINK_dll)
    
ifdef MAKE_DEP
-include $(DEP_FILES)
endif

# -----------------------------------------------------------
endif
#
2个回答

4

我相信Glen的回答是不正确的,因为mak和mk(make)文件根本不一样。它们都用于自动化构建,但相似之处就到此为止。

mak文件是微软的标准,可以通过以下命令在Visual Studio命令提示符中构建:

nmake /f NAMEOFfile.mak

nmake是Visual Studio的一部分,mak文件的语法/结构也与mk(make)文件不同。

make或mk文件主要用于Linux构建,在某些跨平台支持的情况下使用(前提是开发人员支持Windows)。要构建mk文件,您需要Autotools或CMake(这些工具在Windows和Linux中都可用)。mk文件还将附带一个需要在make步骤之前运行的configure脚本,而这对于mak/nmake则不是这种情况。


cbp2make可以为不同平台生成.mak文件,请在此处查看: https://sourceforge.net/p/cbp2make/wiki/Home/ 我认为对于Linux,生成的.mak文件通常是“Makefile”。 - ggurov

1

我认为它们没有区别。只是不同名称的makefile而已。

尝试编辑你的问题并发布.mak文件的内容,这样我们就能更清楚地理解了。


是的,抱歉,我现在在其他地方写作,所以我没有.mak文件,但我会发布一些类似的内容。 - iQ.
从您发布的内容来看,那似乎是一个Makefile,只是名称不同而已。 - Glen
那么微软的nmake实用程序会愉快地运行我生成的.mak文件吗?如果.mak文件还想使用MinGW和VC++编译,nmake实用程序会抱怨吗?或者有更好的工具吗? - iQ.
有些 makefile 是特定于某些 make 程序的。例如,pmake 和标准 make 似乎在运行针对彼此的 makefile 时存在问题。cbp2mak 文档(如果有)说明了什么? - Glen
很遗憾,这里没有太多的文档,只有一个告诉你如何使用它的readme文件。它只生成一个.mak文件,我没有将其发布在上面。老实说,我不太理解其中大部分内容,所以我不确定它是否能在Windows上运行。我不确定是否有任何好的跨平台构建系统,Linux是主要目标,因此最好拥有一个GNU兼容的make系统。那么cmake呢?它是否会生成可以在GNU make系统上编写的make文件?还是用户需要安装cmake,而我正在尝试避免这种情况。 - iQ.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接