我有一个Verifone终端(vx520和vx820)。 我希望为此终端创建一个makefile来编译应用程序。 我有“ VRXSDK”版本1.2.0
如何做到?
或如何编译“ main.c”或“ main.cpp”之类的文件,直到拥有用于Verifone POS终端的执行文件
答案 0 :(得分:1)
无论您从哪里获得“ VRXSDK”,都应该能够获得一些示例项目文件。您将在其中找到一个生成文件(可能带有.smk扩展名)。我建议您从此开始,并在阅读它的过程中,为您提供更具体的问题,以及您可以使用自己喜欢的搜索引擎查找的内容。
从本质上讲,make文件是一个程序,该程序使用您根据各种因素确定的输入参数来调用编译器。它还将调用链接器以将所有链接捆绑在一起。从一个实现到另一个实现,您的处理方式千差万别,因此“如何创建make文件”与“如何编写程序”差不多。这使得在这里回答问题颇具挑战性。但是,让您开始...
我将Visual Studio用作IDE,并且正在使用NMake。我实际上有2层make文件。当我从IDE中说“ build”时,就是所谓的外层,它很短:
# Pick one of the following (for LOG_PRINTF messages)
#CompileWithLogSys = -DLOGSYS_FLAG
CompileWithLogSys =
all:
$(MAKE) /i /f coreBuild.smk /a TerminalType=$(Configuration) CompileWithLogSys=$(CompileWithLogSys) VMACMode=Multi
$(MAKE) /i /f coreBuild.smk /a TerminalType=$(Configuration) CompileWithLogSys=$(CompileWithLogSys) VMACMode=Single
以#开头的行是注释。
如果要构建其他变体,此外部文件使我很容易切换一些内容。您可以看到我已经关闭了与LogSys的兼容。 2层方法给我带来的更重要的事情是使用一个构建命令即可编译2个不同版本的简便方法。这会将nmake的“ VMACMode”设置为“ Multi”,然后再次运行它(将其设置为“ Single”)。内部make文件将看到该参数,并为每个参数编译到一个不同的根文件夹,因此最后我得到了2个文件夹,每个文件夹都有不同的版本。
您可以在“ nmake参数”上进行网络搜索,以查看/ i和/ f之类的功能以及我在此处未使用的其他选项。不过,我想请您注意TerminalType=$(Configuration)
。在Visual Studio中,如果要“调试”或“发布”,则可以从下拉框中选择。这两个选项是默认选项,但是您可以更改它们。就我而言,我已经将它们修改为“ eVo”和“ Vx”。现在,我只需在下拉框中选择要编译的版本并将其传递。或者,我可以将这两个版本都硬编码到我的外部make文件中。那只是喜好。
我的内部make文件(名为“ coreBuild.smk”)变得更加有趣。 通常,您首先定义变量,例如“包含路径”:
# Includes
SDKIncludes = -I$(EVOSDK)\include
ACTIncludes = -I$(EVOACT)include
VCSIncludes = -I$(EVOVCS)include
EOSIncludes = -I$(EOSSDK)\include\ssl2
和/或库:
#Libraries
ACTLibraries = $(EVOACT)OutPut\RV\Files\Static\Release
#Others you may want to include, but I am not using:
#LOGSYSLibraries = $(EVOVMAC)\Output\RV\Lib\Files\Debug
#EOSLibraries = $(EOSSDK)\lib
以及文件的路径
# App Paths
AppIncludes = .\include
SrcDir = .\source
ObjDir = .\obj
OutDir = .\Output\$(TerminalType)\$(VMACMode)\Files
ResDir = .\Resource
我也想在这里定义我的项目名称:
ProjectName = MakeFileTest
请注意,OutDir
使用我们传入的TerminalType
和VMACMode
来访问唯一的文件夹。
接下来,您通常会设置编译器选项
# Compiler Options
# Switch based on terminal type
!IF "$(TerminalType)"=="eVo"
CompilerCompatibility=-p
DefineTerminalType = -DEVO_TERMINAL
!ELSE
CompilerCompatibility=
DefineTerminalType = -DVX_TERMINAL
!ENDIF
# Switch based on Multi or Single mode (VMACMode)
!if "$(VMACMode)"=="Multi"
VMACIncludes = -I$(EVOVMAC)include
DefineMulti = -DMULTI_APP_ENABLED
!else
VMACIncludes =
DefineMulti =
!endif
上面要注意的一个有趣的事情是-DMULTI_APP_ENABLED
。我编写的程序有一些取决于#ifdef MULTI_APP_ENABLED
的块。这不是什么特别的名字,它只是我想出的一个名字,但是编译器会在开始编译我的代码之前就对其进行定义,因此我可以在此处打开和关闭这些代码块。
接下来,我们将有点'把所有东西收集在一起。我们将从定义一个新的变量“ Includes”开始,它将具有标志“ -I”(表示“ include”,然后是我们上面要包含的所有内容:
Includes = -I$(AppIncludes) $(SDKIncludes) $(ACTIncludes) $(VMACIncludes) $(VCSIncludes)
请注意,您可以直接在此处键入所有内容,而无需首先执行额外的步骤来定义var,但这使它更易于阅读,因此我认为这很正常。
对于编译器选项,我们几乎做同样的事情,尽管请注意,原始var声明中已经包含了特定的标志(例如,“-D”,“-p”),因此我们将其保留在此处:>
COptions =$(CompilerCompatibility) $(CompileWithLogSys) $(DefineTerminalType) $(DefineMulti) -DDEV_TOGGLES_FOR_SYNTAX
接下来,我们设置一个变量,该变量将告诉链接器目标文件需要缝合在一起的位置。请注意,如果像我一样插入新行,则需要'\'告诉它继续在下一行
# Dependencies
AppObjects = \
$(ObjDir)\$(ProjectName).o \
$(ObjDir)\Base.o \
$(ObjDir)\printer.o \
$(ObjDir)\UI.o \
$(ObjDir)\Comm.o
我们还将为要链接的任何库设置一个:
Libs = $(ACTLibraries)\act2000.a
好的,接下来我们必须对文件签名。我们试图告诉nMake我们还将创建资源文件并编译实际代码。 如果我们要进行多应用程序构建,则pseudoOut取决于.res和.out文件。如果不是,则仅取决于.out,因为没有.res。如果从属文件的更改时间比伪输出更新的时间最近,请运行命令vrxhdr ...,filesignature ...和move...。请注意,以下所示的缩进是nMake正常工作所必需的。 / p>
!if "$(VMACMode)"=="Multi"
pseudoOut : $(ResDir)\$(ProjectName).res $(OutDir)\$(ProjectName).out
!else
pseudoOut : $(OutDir)\$(ProjectName).out
!endif
# This calls vrxhdr: the utility program that fixes the executable program’s header required to load and run the program. Vrxhdr is needed when you want to move a shared library around on the terminal.
$(EVOSDK)\bin\vrxhdr -s 15000 -h 5000 $(OutDir)\$(ProjectName).out
# do the signing using the file signature tool and the .fst file associated with this TerminalType.
"$(VSFSTOOL)\filesignature" $(TerminalType)$(VMACMode).fst -nogui
@echo __________________ move files to out directory __________________
# rename the .p7s file we just created
move $(OutDir)\$(ProjectName).out.p7s $(OutDir)\$(ProjectName).p7s
!if "$(VMACMode)"=="Multi"
copy $(ResDir)\imm.ini $(OutDir)\imm.ini
copy $(ResDir)\$(ProjectName).INS $(OutDir)\$(ProjectName).INS
copy $(ResDir)\$(ProjectName).res $(OutDir)\$(ProjectName).res
!endif
@echo *****************************************************************
请注意,“ echo”命令只是为了帮助我根据需要读取输出日志。
好的,现在我们链接。
“等等!”我能听到您说:“我们还没有编译,我们已经发出了签名命令,现在我们要链接?这完全乱了!”是的,没有。我们实际上还没有发出要签名的命令,我们只是告诉nmake我们可能想要这样做以及如果我们决定这样做的话该怎么做。同样,我们还没有发出链接命令,只是告诉nmake准备就绪后如何做。
# Link object files
$(OutDir)\$(ProjectName).out : $(AppObjects)
$(EVOSDK)\bin\vrxcc $(COptions) $(AppObjects) $(Libs) -o $(OutDir)\$(ProjectName).out
请记住,mutli-app程序需要一个.res文件。单个应用程序没有。下面将根据需要实际构建.res文件。
!if "$(VMACMode)"=="Multi"
# compile resource file
$(ResDir)\$(ProjectName).res : $(ResDir)\$(ProjectName).rck
$(EVOTOOLS)rck2 -S$(ResDir)\$(ProjectName) -O$(ResDir)\$(ProjectName) -M
!endif
还记得那些AppObjects吗?我们终于准备好制造它们了。我正在使用以下标志
-c
=仅编译-o
=输出文件名-e"-"
=> -e
将错误输出从子工具重定向到... "-"
到stdout。 (然后全部通过管道|重定向)同样,无论您在哪里获得VRXSDK,都应该能够从VeriFone获得一些文档。有关标志的更多详细信息,请参见第59页的“ Verix_eVo_volume 3”
$(ObjDir)\$(ProjectName).o : $(SrcDir)\$(ProjectName).c
!IF !EXISTS($(OutDir))
!mkdir $(OutDir)
!ENDIF
-$(EVOSDK)\bin\vrxcc -c $(COptions) $(Includes) -o $(ObjDir)\$(ProjectName).o $(SrcDir)\$(ProjectName).c -e"-" | "$(EVOTOOLS)fmterrorARM.exe"
$(ObjDir)\Base.o : $(SrcDir)\Base.c
$(EVOSDK)\bin\vrxcc -c $(COptions) $(Includes) -o $(ObjDir)\base.o $(SrcDir)\Base.c -e"-" | "$(EVOTOOLS)fmterrorARM.exe"
$(ObjDir)\myprinter.o : $(SrcDir)\printer.c
$(EVOSDK)\bin\vrxcc -c $(COptions) $(Includes) -o $(ObjDir)\printer.o $(SrcDir)\printer.c -e"-" | "$(EVOTOOLS)fmterrorARM.exe"
$(ObjDir)\UI.o : $(SrcDir)\UI.c
$(EVOSDK)\bin\vrxcc -c $(COptions) $(Includes) -o $(ObjDir)\UI.o $(SrcDir)\UI.c -e"-" | "$(EVOTOOLS)fmterrorARM.exe"
$(ObjDir)\Comm.o : $(SrcDir)\Comm.c
$(EVOSDK)\bin\vrxcc -c $(COptions) $(Includes) -o $(ObjDir)\Comm.o $(SrcDir)\Comm.c -e"-" | "$(EVOTOOLS)fmterrorARM.exe"