1. 安装VS2008/DDK Wizard 。
2. Copy ddkbuild.cmd 到WinDDK 根目录。
3. 设置系统环境变量 :
XP设置 : WXPBASE :C:\WinDDK\7600.16385.1
4. 在VS2008 中添加 include /lib/executale 目录
===============================================
上述设置后,VS 编译一直不过。
手动使用WDK 的CMD 编译,发现编译错误,把项目路径中的所有空格去掉。
再次使用VS编译仍然无法编译通过,所以狠下决心直接分析编译脚本。
问题1: echo "FINDSTR is a prerequisite but wasn't found!"
查看ddkbuild.cmd 脚本后发现为:
findstr /? > NUL 2>&1 || echo "FINDSTR is a prerequisite but wasn't found!" && goto :EOF
失败,手动执行在console上执行findstr 提示“区域语言无法设置”,查看自己区域语言设置发现,中文语言未安装,安装后该问题OK 。
这时已经可以使用VS2008 编译生成sys文件。
问题2:虽然设置为WXP,但编译出来的目录为objchk_win7_x86
既然是参数的问题,不得不解读完整的脚本了。脚本分析如下:
a. ddkbuild.cmd 脚本 剖析!
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: / MAIN function of the script
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:MAIN
:: Building "stack frame"
setlocal ENABLEEXTENSIONS & pushd .
:: Check whether the REG utility is available
reg /? > NUL 2>&1 && set OSR_REGAVAILABLE=1
:: This is set by client-side keyword substitution
set SVN_REVISION=$Revision: 60 $
:: Extract the revision number from the revision keyword
set SVN_REVISION=%SVN_REVISION:~0,-2%
set SVN_REVISION=%SVN_REVISION:~11%
:: This is set by client-side keyword substitution
set SVN_REVDATE=$Date: 2009-11-28 04:28:01 +0000 (Sat, 28 Nov 2009) $
:: Extract the date from the Date keyword
set SVN_REVDATE=%SVN_REVDATE:~7,10%
set VERSION=%VERSION%/r%SVN_REVISION%
:: Init some special variables
set OSR_VERSTR=OSR DDKBUILD.CMD %VERSION% (%SVN_REVDATE%) - OSR, Open Systems Resources, Inc.
set OSR_PREBUILD_SCRIPT=ddkprebld.cmd
set OSR_POSTBUILD_SCRIPT=ddkpostbld.cmd
set OSR_SETENV_SCRIPT=ddkbldenv.cmd
set OSR_ECHO=@echo DDKBLD:
set OSR_RANDEXT=%RANDOM%%RANDOM%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
Set error messages
:: Possible codes: 1
set ERR_UnknownBuildType=Unknown type of build. Please recheck parameters.
:: Possible codes: 2
set ERR_NoWdfRoot=WDF_ROOT is not defined, are you using 00.01.5054 or later?
:: Possible codes: 3
set ERR_BaseDirNotSet=To build using type %%OSR_TARGET%% you need to set the %%%%%%BASEDIRVAR%%%%%% environment variable to point to the %%BASEDIROS%% DDK base directory!
:: Possible codes: 4
set ERR_NoBASEDIR=NT4BASE, W2KBASE, WXPBASE, WNETBASE and/or W7BASE environment variable(s) not set. Environment variable(s) must be set by user according to DDK version(s) installed.
:: Possible codes: 5
set ERR_BadMode=^<build type^> must be 'checked', 'free', 'chk' or 'fre' (case-insensitive).
:: Possible codes: 6
set ERR_NoTarget=Target directory must have a SOURCES+MAKEFILE or DIRS file.
:: Possible codes: 7, 8
set ERR_NoDir=The ^<directory^> parameter must be a valid directory.
:: Possible codes: 9
set ERR_SetEnvFailed=The SETENV script failed.
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Clear the error code variable
set OSR_ERRCODE=0
set PREFAST_BUILD=0
:: Turn on tracing, use %OSR_TRACE% instead of ECHO
if /i "%OSR_DEBUG%" == "on" (set OSR_TRACE=%OSR_ECHO% [TRACE]) else (set OSR_TRACE=rem)
:: Turn on echoing of current line if %OSR_DEBUG% is set to "on"
@echo %OSR_DEBUG%
:: 调用传入参数:
::ddkbuild.cmd -WXP checked . -cZ |
:: %1 %2 %3 %4
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: If the user wants to suppress the header part ... or the info about hook scripts
if /i "%~1" == "/nologo" (shift & set OSR_NOLOGO=1)
if /i "%~1" == "/notquiet" (shift & set OSR_NOTQUIET=1)
:: The next line is *not* a mistake or bug ... it ensures that the order does not matter
if /i "%~1" == "/nologo" (shift & set OSR_NOLOGO=1)
:: Set the target platform variable
set OSR_TARGET=%~1
:: Remove any dashes in the target
if not "%OSR_TARGET%" == "" set OSR_TARGET=%OSR_TARGET:-=%
//执行后结果OSR_TARGET =WXP
:: Output version string
@if not DEFINED OSR_NOLOGO echo %OSR_VERSTR%
%OSR_TRACE% ^(Current module: ^"%~f0^"^)
@if not DEFINED OSR_NOLOGO echo.
:: Show help if the target parameter is empty after removal of the dashes
if "%OSR_TARGET%" == "" goto :USAGE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: In the build directory check for this script and call it if it exists.
:: This allows to override any global system variable setting, if desired.
:: It also checks whether a DIRS/SOURCES file exists ...
if not "%3" == ""
call :GetCustomEnvironment "%~f3" //Call GetCustomEnvironment 并传入工程位置目录
//call :GetCustomEnvironment "d:\Visual_Studio_2008\Projects\Driver1\Driver1" |
//c
heck
目录及文件环境是否OK
if DEFINED HOOK_ABORT goto :END
if %OSR_ERRCODE% neq 0 goto :USAGE
:: Additional error handling for better usability
:: These subroutines will also attempt to locate the requested DDK!!!
set OSR_ERRCODE=3
%OSR_TRACE% Checking whether the environment variable for the build type was set
:: Calling as a subroutine has 2 advantages:
:: 1. the script does not quit if the label was not found
:: 2. we return to the line after the call and can check variables there
call :%OSR_TARGET%Check > NUL 2>&1 //Call WXPCheck
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: These labels are for compatibility with the respective
:: modes supported by another flavor of DDKBUILD.
:XPCheck
:XP64Check
:XPW2KCheck
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:WXP64Check
:WXPI64Check
:WXPCheck
:WXP2KCheck
set BASEDIROS=Windows XP
set BASEDIRVAR=WXPBASE //从函数的实现看,我们知道为何要在环境变量中增加
WXPBASE了
:: Other flavor of DDKBUILD
if not DEFINED WXPBASE if DEFINED XPBASE set
BASEDIRVAR=XPBASE
:: Return to caller if the BASEDIR is already defined (either customized or global)
if DEFINED %BASEDIRVAR% goto :CommonCheckNoErrorWithReturn
call :DetectBaseDirTemp "2600.1106 2600"
if DEFINED BASEDIRTEMP if exist "%BASEDIRTEMP%" goto :CommonCheckSetVarWithReturn
goto :CommonCheckErrorNotDetectedWithReturn
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: If the BASEDIROS/BASEDIRVAR variable is not defined, it means the subroutine did not exist!
if not DEFINED BASEDIROS call :ShowErrorMsg 1 "%ERR_UnknownBuildType% (BASEDIROS)" & goto :USAGE
if not DEFINED BASEDIRVAR call :ShowErrorMsg 1 "%ERR_UnknownBuildType% (BASEDIRVAR)" & goto :USAGE
if %OSR_ERRCODE% neq 0 call :ShowErrorMsg %OSR_ERRCODE% "%ERR_BaseDirNotSet%" & goto :USAGE
%OSR_TRACE% BASEDIROS=%BASEDIRVAR% BASEDIRVAR=%BASEDIRVAR% OSR_ERRCODE =%OSR_ERRCODE%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
set BASEDIR=%%%BASEDIRVAR%%%
call :ResolveVar BASEDIR
call :MakeShort BASEDIR "%BASEDIR%"
:: Check for existing %BASEDIR%
if "%BASEDIR%" == "" call :ShowErrorMsg 4 "%ERR_NoBASEDIR%" & goto :USAGE
set PATH=%BASEDIR%\bin;%PATH%
%OSR_TRACE% Now jump to the initialization of the commandline
:: Calling as a subroutine has 2 advantages:
:: 1. the script does not quit if the label was not found
:: 2. we return to the line after the call and can check variables there
call :%OSR_TARGET%Build //call
WXPBuild
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: WXP build for 32bit using WXP DDK
:XPBuild
:WXPBuild
set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% WXP
goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
//WXP 为我添加,会传入setenv.bat 控制编译XP版本
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
%OSR_TRACE% We returned from the variable initialization
if not DEFINED OSR_CMDLINE call :ShowErrorMsg 1 "%ERR_UnknownBuildType% (OSR_CMDLINE)" & goto :USAGE
%OSR_TRACE% Hurrah, all the variables have been initialized, continuing
:: Proceed with common build steps
goto :CommonBuild
:CommonBuild
:: Remove first command line arg
shift
call :SetMode %1 //设置模式 check or free
if %OSR_ERRCODE% neq 0 call :ShowErrorMsg %OSR_ERRCODE% "%ERR_BadMode%" & goto :USAGE
set OSR_BUILDNAME=%OSR_TARGET% (%BuildMode%) using the %BASEDIROS% DDK and %%%BASEDIRVAR%%%
call :CheckTargets %2
if %OSR_ERRCODE% equ 6 call :ShowErrorMsg %OSR_ERRCODE% "%ERR_NoTarget%" & goto :USAGE
if %OSR_ERRCODE% neq 0 call :ShowErrorMsg %OSR_ERRCODE% "%ERR_NoDir%" & goto :USAGE
:: Resolve any variables in the command line string
call :ResolveVar OSR_CMDLINE
pushd .
set ERRORLEVEL=0
:: This external script prepares the build environment (e.g. setenv.bat)
call %OSR_CMDLINE% //==》setenv.bat 入口,这里会有控制是编译和那种版本的driver
b. setenv.bat脚本 剖析!
查看 setenv.bat 脚本的默认设置如下:
set _FreeBuild=true
set _IA64bit=false
set _AMD64bit=false
set _BscMake=FALSE
set _RunOacr=TRUE
set _VersionedHeaders=TRUE
set _LatestOsTarget=WIN7
set RAZZLETOOLPATH=%BASEDIR%\Bin
set separate_object_root=FALSE
set DDK_TARGET_OS=Win7
REM This default value will be overridden if one of the legacy
REM build environments is invoked.
set _title=Windows Win7
/////////////////////////////////////////////////////////////////
//下面循环会检测传入参数重新设置编译参数
:NextArg
REM
REM Ways to get script usage
REM
if /I "%1"=="/?" goto usage
if /I "%1"=="-?" goto usage
if /I "%1"=="\?" goto usage
if /I "%1"=="-help" goto usage
if /I "%1"=="/help?" goto usage
REM
REM Valid target architectures
REM (undecoracted '64' implies IA-64)
REM
if /I "%1"=="64" goto ArgOK
if /I "%1"=="x64" goto ArgOK
if /I "%1"=="I386" goto ArgOK
if /I "%1"=="IA64" goto ArgOK
if /I "%1"=="IA32" goto ArgOK
if /I "%1"=="x86" goto ArgOK
if /I "%1"=="x32-64" goto ArgOK
REM
REM Checked or Free builds
REM
if /I "%1"=="f" goto ArgOK
if /I "%1"=="fre" goto ArgOK
if /I "%1"=="free" goto ArgOK
if /I "%1"=="c" goto ArgOK
if /I "%1"=="chk" goto ArgOK
if /I "%1"=="CHK" goto ArgOK
if /I "%1"=="checked" goto ArgOK
REM
REM Valid target operating system versions
REM
if /I "%1"=="Wlh" goto ArgOK
if /I "%1"=="WNet" goto ArgOK
if /I "%1"=="WXP" goto ArgOK
if /I "%1"=="WIN7" goto ArgOK
REM
REM Valid subkit build environments
REM
if /I "%1"=="hal" goto ArgOK
REM
REM Final checks
REM
if /I "%1"=="bscmake" goto ArgOK
if /I "%1"=="hdr_ver" goto ArgOK
if /I "%1"=="no_oacr" goto ArgOK
if /I "%1"=="oacr" goto ArgOK
if /I "%1"=="separate_object_root" goto ArgOK
if /I "%1"=="objs" goto ArgOK
if NOT "%1"=="" goto usage
if "%1" == "" goto :GetStarted
:ArgOK
if /I "%1"=="64" set _IA64bit=true
if /I "%1"=="x64" set _AMD64bit=true
if /I "%1"=="I386" set _IA32bit=true
if /I "%1"=="IA64" set _IA64bit=true
if /I "%1"=="IA32" set _IA32bit=true
if /I "%1"=="x86" set _IA32bit=true
if /I "%1"=="x32-64" set _AMD64bit=true
if /I "%1"=="f" set _FreeBuild=true
if /I "%1"=="fre" set _FreeBuild=true
if /I "%1"=="free" set _FreeBuild=true
if /I "%1"=="c" set _FreeBuild=false
if /I "%1"=="chk" set _FreeBuild=false
if /I "%1"=="CHK" set _FreeBuild=false
if /I "%1"=="checked" set _FreeBuild=false
if /I "%1"=="Wlh" set DDK_TARGET_OS=WinLH
if /I "%1"=="WNet" set DDK_TARGET_OS=WinNET
if /I "%1"=="WXP" set DDK_TARGET_OS=WinXP //假设传入WXP ,则会重新设置DDK_TARGET_OS =WinXP
if /I "%1"=="win7" set DDK_TARGET_OS=Win7
if /I "%1"=="bscmake" set _BscMake=TRUE
if /I "%1"=="no_oacr" set _RunOacr=False
if /I "%1"=="oacr" set _RunOacr=TRUE
if /I "%1"=="hdr_ver" set _VersionedHeaders=TRUE
if /I "%1"=="separate_object_root" set separate_object_root=TRUE
if /I "%1"=="objs" set separate_object_root=TRUE
shift
goto :NextArg