问题
I want to use makefile to create my app and .out file and use it in my verifone vx520.
I have makeapp.bat for creating .out file but when I run it get this error: NMAKE : fatal error U1073: don't know how to make 'utils.h'
and this is makeapp.bat file:
@goto Begin
:Begin
@set OLDPATH=%PATH%
@rem set VRXSDKS to the Verix V SDK directory
@set VRXSDK=C:\eVoAps\SDK\1.2.0\VRXSDK
@rem Set RVCTDIR to RVDS2.2
@set RVCTDIR=C:\Program Files\ARM\RVCT\Programs\2.2\349\win_32-pentium
@rem or, Set RVCTDIR to RVDS2.1
@rem set RVCTDIR=C:\Program Files\ARM\RVCT\Programs\2.0.1\277\win_32-pentium
@set PATH=%VRXSDK%\bin\;%RVCTDIR%;%OLDPATH%
@rem use app.mak to buid application
nmake /f app.mak
@rem or, use vrxcc directly here to build a simple application
@rem %VRXSDK%\bin\vrxcc app.c
@set PATH=%OLDPATH%
@set RVCTDIR=
pause
how can i solve that error?
回答1:
So, it looks to me like your bat file here has lots of comments (@rem) and it also sets several variables (@set), but the bulk of the work will be done in the line
nmake /f app.mak
which will reference a different file called app.mak
. That's where the magic happens and it's where you will need to edit something to let nmake
know how to compile and link utils.h
. I suggest you look at c2.com/cgi/wiki?UsingNmake for more details.
As you know, a make file is, for all intents and purposes, a program that you write. When it runs, it builds the VeriFone app (or whatever other program you were working on). As such, there is a multitude of things you can do, some of which you must do if you want nmake to actually build your program. I think the best way to help out would be to share parts of my make file. Note that this started off as just a template from a sample VeriFone project.
Mine starts off just declaring variables, paths, etc., like so:
ProjectName = TestProject
# ****** PATHS ******
# Includes
SDKIncludes = -I$(EVOSDK)\include
ACTIncludes = -I$(EVOACT)include
VCSIncludes = -I$(EVOVCS)include
#Libraries
ACTLibraries = $(EVOACT)OutPut\RV\Files\Static\Release
# App Paths
AppIncludes = .\include
SrcDir = .\source
ObjDir = .\obj
OutDir = .\Output\$(TerminalType)\$(VMACMode)\Files
ResDir = .\Resource
Note that TerminalType
is something I have set Visual Studio to pass into NMAKE when it initiates a build and it is based on my solution configuration. Technically, I have 1 make file calling another and the outer one is setting it like this: TerminalType=$(Configuration)
. You'll see this variable again below as well as a couple others that are similar.
Next, I define some compiler options
# Switch based on terminal type
!IF "$(TerminalType)"=="eVo"
CompilerCompatibility=-p
DefineTerminalType = -DEVO_TERMINAL
!ELSE
CompilerCompatibility=
DefineTerminalType = -DVX_TERMINAL
!ENDIF
The -D
flag defines things in my code as if I had done a #define
. This is useful for turning parts on or off depending one what I'm compiling for. Unless you plan to do that, you won't need to do it yourself. The important part here for anyone compiling for eVo terminals is the CompilerCompatibility
which sets a -p
flag (must be off for Verix V, must be on for for eVo terminals).
Now we consolidate everything we've done thus far into 2 variables:
Includes = -I$(AppIncludes) $(SDKIncludes) $(ACTIncludes) $(VMACIncludes) $(VCSIncludes)
COptions =$(CompilerCompatibility) $(DefineTerminalType)
OK, now here's the part I suspect you are tripping up on: we need to define our dependencies, which I do like so:
# Dependencies
AppObjects = \
$(ObjDir)\$(ProjectName).o \
$(ObjDir)\Base.o \
$(ObjDir)\UI.o \
$(ObjDir)\Comm.o
Libs = $(ACTLibraries)\act2000.a
This could all go on one line, if we wanted to. The \
at the end of each line just means we are breaking that single line up which is done here for readability. Otherwise, it would look like this:
AppObjects = $(ObjDir)\$(ProjectName).o $(ObjDir)\Base.o $(ObjDir)\UI.o $(ObjDir)\Comm.o
Libs = $(ACTLibraries)\act2000.a
OK, so this AppObjects
will be used when we do our linking. First, however, I also want to tell NMAKE to run the file signing program and then copy the files over where I want them.
# Sign the file(s). Tell nMake that we also
# will be creating the resource file and compiling the actual code...
# NOTE: (the indentations seen below are required for nMake to work properly)
# pseudoOut depends on TestProject.res and TestProject.out.
# If TestProject.res or TestProject.out have changed more recently than pseudoOut,
# then run commands vrxhdr..., filesignature..., and move...
!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 *****************************************************************
Now let's define how we will do the linking:
# Link object files
$(OutDir)\$(ProjectName).out : $(AppObjects)
$(EVOSDK)\bin\vrxcc $(COptions) $(AppObjects) $(Libs) -o $(OutDir)\$(ProjectName).out
...and build the .res file...
#This will actually build the .res file. (We only said we were going to do it above)
!if "$(VMACMode)"=="Multi"
# compile resource file
$(ResDir)\$(ProjectName).res : $(ResDir)\$(ProjectName).rck
# SET INCLUDE=$(INCLUDE);$(EVOVMAC)\include;$(EVOVMAC)\template --> I put this into my include path for the project, instead
$(EVOTOOLS)rck2 -S$(ResDir)\$(ProjectName) -O$(ResDir)\$(ProjectName) -M
!endif
and now we can actually run the compilation:
# Compile modules --> -c = compile only, -o = output file name, -e"-" => -e redirect error output from sub-tools to... "-" to stdout. (These are all then redirected via pipe | )
# For more details, see Verix_eVo_volume 3, page 59
$(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)\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"
And that's the last line--there is no other fanfare or what-have-you.
I would like to point something out that you may have noticed, but threw me for a loop when I was getting started on all of this: we kinda' do everything backwards. If I were telling a person how to build the project, I would start by telling them how to compile everything to it's .o
file first, but that's the last step in a make file. Next, I would tell a person how to do the linking, but that's the 2nd to last step, and so on.
If you still need more info, visit the link I included--it's way more authoritative than I am and includes a lot of details I probably missed. Hopefully this is enough to get you going, though.
来源:https://stackoverflow.com/questions/40127882/how-to-add-library-in-makefile-for-verix