Porting Open Source Libraries to Windows for IoT

Microsoft is bringing Windows to a new class of small devices. Riding the crest of the “Internet of Things” movement, Microsoft is looking to capitalize on devices and sensor capabilities of popular development boards. Recently, members of the Windows Developer Program for IoT have been able to gain access to a build of Windows which supports the Intel Galileo chipset.

Bringing Windows to small devices is a huge feat that opens the door to many development opportunities. Of course, this means, a lot of existing code can be brought over to aid in creating IoT solutions. This post aims to identify the specifics of compiling two open source libraries to this new version of Windows.

The libraries in question concern apache-qpid-proton a light-weight messaging framework for sending AMQP messages and OpenSSL , an open-source library for implement Secure Socket Layer protocols.

Why these two libraries? They were necessary for creating a Win32 application capable of sending AMQPS messages up to an Azure Event Hub as part of Galieo device support in the super awesome Connect the Dots project from MSOpenTech . More importantly, we get to encounter two rather distinct compilation exercises. Apache Qpid can send AMQP (without the S) messages on its own, but Azure requires these are sent over SSL. So we need to compile Apache Qpid against OpenSSL to get AMQPS support. In addition, Apache Qpid gives us a Visual Studio Solution to work with while OpenSSL is built using a makefile in combination with Perl and python processors for producing the makefile itself. This post will explain these scenarios and the necessary changes required to target Windows for IoT through the Visual Studio project for Apache Qpid and the makefile for Open SSL.

Let’s begin by looking at the default property configuration for the Apache Qpid Visual Studio Project:

Normally, when compiling a Win32 application for a desktop PC, we will compile against Win32 libraries contained in C:WindowsSystem32. When targeting the Intel Galileo board you will notice that the default Intel Galileo Wiring App template contained in the Windows Developer Program for IoT MSI links against a single library, mincore.lib. Jer’s blog goes into the best known detail on what this is. Long story short, we need to compile against mincore.lib in order to obtain code capable of running on the Galileo as the mappings for System and Win32 functions are completely different in Windows for IoT and contained in this particular lib. This sets the basis for rules #1 and #2.

1. Remove all references to System 32 libs and replace with a reference to Mincore.lib

2. For all references removed in step 1, add these Dlls to the IgnoreDefaultLibraries Collection, this ensures that the linker will not attempt to link to these Dlls, as we want to link to references in Mincore only.

In addition, we need to consider the hardware present on the Galileo board itself. Intel outfits the board with an Intel® Quark™ SoC X1000 application processor, a 32-bit, single-core, single-thread, Intel® Pentium® processor instruction set architecture (ISA)-compatible, operating at speeds up to 400 MHz. This processor does not support enhanced instruction set including SSE, SSE2, AVX, or AVX 2. This set the basis for rule #3.

3. Ensure all code is compiled with the /arch:IA32 compiler flag

You can now build Apache-Qpid-Proton to target Windows for IoT on the Intel Galileo, however, in order to be useful, we need to compile again OpenSSL as Azure event hubs require that we send messages using AMQPS. Without OpenSSL support, we can only send AMQP messages which will be ignored by the Azure event hub.

There is an excellent article on compiling Apache-Qpid Proton against OpenSSL for Windows @ https://code.msdn.microsoft.com/windowsazure/Using-Apache-Qpid-Proton-C-afd76504

I don’t want to reproduce the content there so let’s talk about the changes necessary to target the Windows on the Galileo board.

In step A.3 the author describes the process for compiling the OpenSSL dynamic linking libraries using “nmake –f msntdll.mak install”. Nmake is Microsoft’s build tool for building makefiles. To use the tool you can access it within a Visual Studio command prompt, from it’s actual location in C:Program Files (x86)Microsoft Visual Studio X.XVCbin, or call C:Program Files (x86)Microsoft Visual Studio 12.0Common7Toolsvsvars32.bat in a standard command prompt to allow for the path to nmake to be available in your current shell. The problem is the default makefile is configured to build against Win32, i.e. Win32 on the desktop.

Let’s take what we learned above and apply it to the ntdll makefile:

Inside the untouched ntdll.mak you will see the following:

# Set your compiler options

PLATFORM=VC-WIN32

CC=cl

CFLAG= /MD /Ox /O2 /Ob2 -DOPENSSL_THREADS -DDSO_WIN32 -W3 -Gs0 -GF -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE -DOPENSSL_USE_APPLINK -I. -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_STATIC_ENGINE

APP_CFLAG= /Zi /Fd$(TMP_D)/app

LIB_CFLAG= /Zi /Fd$(TMP_D)/lib -D_WINDLL

SHLIB_CFLAG=

APP_EX_OBJ=setargv.obj $(OBJ_D)applink.obj /implib:$(TMP_D)junk.lib

SHLIB_EX_OBJ=

# add extra libraries to this define, for solaris -lsocket -lnsl would

# be added

EX_LIBS=ws2_32.lib gdi32.lib advapi32.lib crypt32.lib user32.lib

# The OpenSSL directory

SRC_D=.

LINK=link

LFLAGS=/nologo /subsystem:console /opt:ref /debug

We essentially have a section of the makefile which outlines compiler flags and linker flags. Here we can apply the rules from above to create a makefile that will produce a Win32 compatible library which targets the Intel Galileo.

Applying Rule #1 we remove the libs mentioned in EX_LIBS and replace with mincore.lib

Applying Rule #2 we take the libs that were in EX_LIBS and add to the linker flags (LFLAG): /NODEFAULTLIB:NAMEOFLIBARY

Applying Rule #3 we add /arch:IA32 to each compiler flag (*CFLAG)

This yields the following changes:

# Set your compiler options

PLATFORM=VC-WIN32

CC=cl

CFLAG= /arch:IA32 /MD /Ox /O2 /Ob2 -DOPENSSL_THREADS -DDSO_WIN32 -W3 -Gs0 -GF -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE -DOPENSSL_USE_APPLINK -I. -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_STATIC_ENGINE

APP_CFLAG= /arch:IA32 /Zi /Fd$(TMP_D)/app

LIB_CFLAG= /arch:IA32 /Zi /Fd$(TMP_D)/lib -D_WINDLL

SHLIB_CFLAG= /arch:IA32

APP_EX_OBJ=setargv.obj $(OBJ_D)applink.obj /implib:$(TMP_D)junk.lib

SHLIB_EX_OBJ=

# add extra libraries to this define, for solaris -lsocket -lnsl would

# be added

EX_LIBS=mincore.lib

# The OpenSSL directory

SRC_D=.

LINK=link

LFLAGS=/NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ws2_32.lib /NODEFAULTLIB:gdi32.lib /NODEFAULTLIB:advapi32.lib /NODEFAULTLIB:crypt32.lib /NODEFAULTLIB:user32.lib /nologo /subsystem:console /opt:ref /debug

RSC=rc

I have posted the the complete changes made to ntdll.mak compatible with the Windows for IoT on Intel Galileo @ https://gist.github.com/toolboc/490d53bdddc6626bce04

We can now build the OpenSSL libraries, but you will notice you receive a variety of errors. This is due to missing functions in mincore.lib that were available in the original System32 dlls.

For example:

Creating library out32dlllibeay32.lib and object out32dlllibeay32.exp

cryptlib.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _OPENSSL_showfatal

cryptlib.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _OPENSSL_showfatal

cryptlib.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _OPENSSL_showfatal

cryptlib.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _OPENSSL_isservice

cryptlib.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _OPENSSL_isservice

cryptlib.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _OPENSSL_showfatal

cryptlib.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _OPENSSL_isservice

rand_win.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _readscreen

rand_win.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _readscreen

rand_win.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _readscreen

rand_win.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _readscreen

rand_win.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _readscreen

rand_win.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _readscreen

rand_win.obj : error LNK2019: unresolved external symbol [email protected] referenced in function _readscreen

You will notice that these errors actually kind of make sense. Recall Window for IoT (mincore) is stripped down to approximately 171 MB. As a result, many unnecessary functions are removed, such as GetProessWindow and MessageBox as shown above (as there isn’t a GUI available on the stripped down mincore). We now need to modify the source (as safely as possible) to resolve these externals. In my case, I simply commented out the missing method where necessary. Of course, this may have unintended side effects, but due to the fact that most of the missing calls deal with the GUI, you are probably okay.

Continue this until the only errors you receive are in creating the e_capi.obj

Capi is one of the engines used by OpenSSL and it is probably important but I could not get around the compilation errors without essentially breaking it completely so I left it out. This will still produce a valid libeay32.dll and ssleay32.dll. You can verify by copying these dlls along with the created openssl.exe and not that it runs on the Galileo! (Note: you can resolve the error mentioned by copying the produced openssl.cnf to the directory mentioned)

Now to truly compile Apache-Qpid_Proton with OpenSSL support, you would continue forward from step B of https://code.msdn.microsoft.com/windowsazure/Using-Apache-Qpid-Proton-C-afd76504

Upon recreating and opening the Apache-Qpid-Proton Visual Studio solution, you would need to modify all the proton project using Rules #1 – #3 as defined above.

Of course, if you wish to obtain the precompiled binaries and see an example of using Apache-Qpid-Proton with OpenSSL support in a Galileo Wiring app, you may refer to this pull request in the Connect the Dots Project by MS OpenTech: https://github.com/MSOpenTech/connectthedots/pull/20

Happy Hacking! Here’s to a great ideas and developments on Windows for IoT!

稿源:WinCoder Blog (源链) | 关于 | 阅读提示

本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » 后端存储 » Porting Open Source Libraries to Windows for IoT

喜欢 (0)or分享给?

专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录