In case you haven’t heard, Microsoft has converted the WDK to integrate with Visual Studio 11. What this means for us developers is that the driver projects that we previously built with Win7 WDK build environment will have to be converted to use the new build environment.
When we say that a project needs to be converted, what exactly do we mean? Well, remember that in the previous WDK a driver project had a sources file (SOURCES.) and optionally a makefile.inc. In order to build a driver project in the new build environment you need a Visual Studio project file (.vcxproj). So how do you get of those?
The new version of the WDK introduces a tool called “NMake2MsBuild.” What this tool does is the topic of this article. So without further ado let’s talk about NMake2MsBuild.
NMake2MsBuild
As we mentioned, NMake2MsBuild is a Microsoft-provided utility that is used to convert an existing WDK “Sources.“ based project into a “.vcxproj” based project that can be built by Visual Studio or from the command line directly using MsBuild. While we are sure everyone knows about building projects with Visual Studio, there may be a few people who don’t know about MsBuild.
MsBuild is a utility that is included with Visual Studio that allows a developer to build Visual Studio based projects (.vcxproj files) from the command line, like the “Build” utility did in the Win7 WDK. So whether you want to build your driver project from within Visual Studio or from the Command Line with MsBuild, NMake2MsBuild is the tool you use to convert your Win7 WDK project.
Now that we’ve distinguished between MsBuild and Visual Studio, let’s continue with discussing NMake2MsBuild.
NMake2MsBuild Command Line
NMake2MsBuild is shipped with the new WDK and is typically found in your %SYSTEMROOT%\Program Files\Windows Kits\8.0\bin\[x86,amd64] directory. Run this command from the directory that contains the “Sources.” or “Dirs” file that you want to convert. The syntax of the command is shown in Figure 1, with descriptions as follows:
- Sources or Dirs indicates what is to be converted (i.e. a project that has a “Sources.” file or a project that contains a “DIRS.” file.
- Verbosity is one of the “System.Diagnostics. SourceLevels” which are:
- Off – does not allow any events through
- Critical – Allows only Critical events through
- Error – Allows Critical and Error events through
- Warning – Allows Critical, Error, and Warning events through
- Information – Allows Critical, Error, Warning, and Information events through
- Verbose – Allows Critical, Error, Warning, Informational, and Warning events through
- ActivityTracing – Allows Stop, Start, Suspend, Transfer, and Resume events through
- All – Allows all events through
- SafeMode – does not provide IDE/UI support for Nmake targets but may provide a more accurate conversion for Nmake targets. (Only specify “–SafeMode” if you experience issues during build steps that were previously performed in your project’s Nmake targets)
- Arm – adds ARM as a valid target CPU architecture to the project’s build configurations. The generated project will still require that the installed build environment and WDK support targeting ARM.
NMake2MsBuild <sources|dirs.> [-Log:[<LogFile>]:[<Verbosity>] [-ConsoleLog:<Verbosity>] –SafeMode -Arm
The default logging level for “–Log” is “Verbose” while the default logging level for “–ConsoleLog” is “Information”.
As you can see the NMake2MsBuild command has very few options, but don’t let that fool you. This is a very complex utility that was written to convert very complex driver projects into “.vcxproj” based projects.
You might be wondering if you have to use the command line to do the conversion to a “.vcxproj” based project. The answer is NO! In Visual Studio 11 you can skip doing this conversion from the command line and do the conversion inside Visual Studio via the “Convert Sources/Dirs” option found via the File Open menu item as shown in Figure 2.
Since that is the way most developers are going to do their conversions, we will perform all the conversions of projects described in this article via Visual Studio.
Converting projects with NMake2MSBuild
When you convert a project, NMake2MsBuild will attempt to create a “.vcxproj” project file that you can use to build your driver in the new build environment. When we say “attempt” we mean the conversion utility will do its best to perform the conversion. Most of the time, and certainly for any simple projects we’ve tried, the conversion is performed without a hitch. Unfortunately there will also be times when NMake2MSBuild will not be able to perform the conversion. For example, here at OSR we have projects that been around since NT 4 and we have been hacking, whacking, and patching our sources files to keep the projects building with each subsequent release of newer WDKs. As a result of this “evolution”, these old sources files have a lot of crufty and unused things that NMake2MsBuild doesn’t like. That shouldn’t be very surprising. In fact, it’s more surprising that some of these old files worked with Build at all. So unfortunately for us, we’re probably going to have to create new projects from scratch. Oh well, it was probably time to clean up all the old junk anyway.
Let’s take a look at a couple of example project conversions. For our first example, the project containing the sources file is shown in Figure 3 below. You will notice that this is for a KMDF driver and there are no pre-build or post-build steps (.i.e. there is no “makefile.inc” file with this project).
TARGETNAME=Nothing TARGETTYPE=DRIVER TARGETPATH=obj KMDF_VERSION_MAJOR=1 KMDF_VERSION_MINOR=9 SOURCES=nothing.cpp
From within Visual Studio, we use the “Convert Sources/Dirs” option and get the results shown in Figure 4 below. Notice that we have a small log written to the Output pane describing how the conversion went (truncated to save space), a more detailed log (NMake2MsBuild_Sources.Log) was written out during this conversion and is stored in the directory being converted. In addition you will see that the files of our example “Nothing” project are now visible in the Solutions Explorer window.
As you can see, the conversion operation here was pretty simple. We had a simple sources file that was easily converted into a “.vcxproj” project. Now, let’s look at a little more complicated project.
# UMDF_VERSION_MAJOR controls the headers that the driver uses. # UMDF_VERSION_MAJOR + UMDF_VERSION_MINOR control which version # of UMDF the driver is bound to in the INF and which # update coinstaller it requires (through stampinf). # UMDF_VERSION_MAJOR=1 UMDF_VERSION_MINOR=9 KMDF_VERSION_MAJOR=1 KMDF_VERSION_MINOR=9 TARGETNAME=WUDFOsrNothing TARGETTYPE=DYNLINK USE_MSVCRT=1 WIN32_WINNT_VERSION=$(LATEST_WIN32_WINNT_VERSION) _NT_TARGET_VERSION=$(_NT_TARGET_VERSION_WINXP) NTDDI_VERSION=$(LATEST_NTDDI_VERSION) # # Set the warning level high # MSC_WARNING_LEVEL=/W4 /WX #pragma warning( disable: 4201 ) // nonstandard extension used : nameless struct/union MSC_WARNING_LEVEL=$(MSC_WARNING_LEVEL) /wd4201 # # If you want to use WPP tracing then uncomment the following line. # #C_DEFINES = $(C_DEFINES) /D_UNICODE /DUNICODE /DUSE_WPP=1 C_DEFINES = $(C_DEFINES) /D_UNICODE /DUNICODE DLLENTRY=_DllMainCRTStartup DLLDEF=exports.def INCLUDES=$(INCLUDES);..\inc SOURCES=\ OsrNothing.rc \ dllsup.cpp \ comsup.cpp \ driver.cpp \ device.cpp \ queue.cpp \ ioQueue.cpp TARGETLIBS=\ $(SDK_LIB_PATH)\strsafe.lib \ $(SDK_LIB_PATH)\kernel32.lib \ $(SDK_LIB_PATH)\advapi32.lib NTTARGETFILE1=$(OBJ_PATH)\$(O)\WUDFOsrNothing.inf # # This sets up the WPP preprocessor and tells it to scan internal.h to find # the trace function definition that's in there. # RUN_WPP= $(SOURCES) -dll -scan:nothing.h TARGET_DESTINATION=wudf
For our next conversion we will convert a UMDF driver from the Win7 WDK to a “.vcxproj” based project. The sources file for this project is shown in Figure 5. In looking at this sources file you should notice a couple of things:
- The project uses WPP tracing
- The project has a custom build step (NTTARGETFILE1) which requires a makefile.inc file shown in Figure 6.
.SUFFIXES: .inx STAMP=stampinf # $(OBJ_PATH)\$(O)\$(INF_NAME).inf: $(_INX)\$(INF_NAME).inx .inx{$(OBJ_PATH)\$(O)}.inf: copy $(@B).inx $@ $(STAMP) -f $@ -a $(_BUILDARCH) -k $(KMDF_VERSION_MAJOR).$(KMDF_VERSION_MINOR) -u $(UMDF_VERSION_MAJOR).$(UMDF_VERSION_MINOR).0
For this conversion, Nmake2MsBuild has to take both the WPP tracing and the custom build steps into account when performing the conversion. We’ll skip showing the conversion output since it worked without a problem, but what we will show you is the output of a build of our converted project.
See Figure 7 for output of the converted project in Visual Studio.
See Figure 8 (next page)for the output of the converted project in MsBuild.
Notice that the NTTARGETFILE1 step that was created to do a StampInf call was successfully imported into the “.vcxproj” project and performed when we built the project.
Once the conversion is complete, you can build the new project from within Visual Studio just like you build an application. Or, if you prefer, you can build your project outside of Visual Studio by invoking MsBuild directly via the command line. Either way, notice (and this is a big dealif you ask me) the new WDK automatically adds project steps to sign your driver (you can configure it to either use a test signing certificate or your release signing cert), and optionally even automatically copies your driver to a test system and install it. You really can’t ask for much more than that. The key to getting these features is using the Win8 WDK. And the key to using the Win8 WDK is converting your project from sources/dirs. to “.vcxproj” format.
Summary
In this article on NMake2MsBuild, we have shown that, in general, converting simple driver projects from traditional dirs/sources format to the new “.vcxproj” format used in the Win8 WDK is pretty simple. Whether you choose to do your conversion from the command line with Nmake2Msbuild or from within Visual Studio, this Microsoft utility strives to do the right thing. And as we mentioned, there are going to be projects that may not be able to be converted, but hey, if it were easy, this conversion to Visual Studio would have been done a long time ago.