Building the MQTT client for C libraries
Follow these steps to build the MQTT client for C libraries. The topic includes the compile and link switches for a number of platforms, and examples of building the libraries on iOS and Windows.
Before you begin
- Build the C client library only when necessary. Link the pre-built client libraries in the (Software Development Kit) SDK in the SDK\clients\c subdirectory if one matches your target platform.
- Configure an MQTT server to test the library you build with the MQTT client sample C app. See Getting started with MQTT servers. Verify the server configuration by running one of the MQTT client sample apps.
- If you are building a secure version of the C library, which supports
(Secure Sockets Layer) SSL, you must also build the OpenSSL library.
See Building the OpenSSL package.Important: Download and redistribution of the OpenSSL package is subject to stringent import and export regulation, and open source licensing conditions. Take careful note of the restrictions and warnings before you decide whether to download the package.
About this task
Follow the instructions in Building the OpenSSL package to download and build the OpenSSL library. You must build the OpenSSL to build a secure version of the MQTT client for C library. You do not require OpenSSL to build an unsecured version of the MQTT library. The steps include examples of building the library for iOS and Windows.
Procedure
MQTT build options for different platforms
The following table lists the compiler and build options to build the MQTT client for C libraries on various platforms.
Platform | Compiler |
Compiler Options |
Linker Options |
Extra Options |
---|---|---|---|---|
AIX® | gcc |
-fPIC -Os -Wall -DREVERSED |
-Wl,-G |
|
Linux s390x | -shared -Wl,-soname, libmqttv3c.so |
-m64 |
||
Linux x86-64 | -fPIC -Os -Wall -I MQTTCLIENT_DIR |
|||
Linux x86-32 | -m32 |
|||
Linux ARM (glibc) | arm-linux-gcc |
|||
Linux ARM (uclibc) | arm-unknown-linux |
|||
Windows 32-bit | cl | /D "WIN32" /D "_UNICODE" /D "UNICODE" |
/nologo /machine:x86 /manifest |
|
iOS ARMv7 | gcc -arch armv7 | -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE -DOPENSSL -isysroot /Applications/Xcode.app/\ |
-L/Applications/Xcode.app/ |
|
iOS ARMv7s | gcc -arch armv7s | |||
iOS ARMi386 | gcc -arch i386 | -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE -DOPENSSL -isysroot /Applications/Xcode.app/\ |
-L/Applications/Xcode.app/ |
Building the MQTT client libraries for C on an Apple Mac for use with iOS devices
Follow these steps to write a makefile to build the MQTT client libraries for C on an Apple Mac, for subsequent use with iOS devices.
Before you begin
- Install build tools, develop, and run the makefile on Apple Mac with OS X 10.8.2, or later.
- Install the command-line tools for Xcode, which include the make program. Download the command-line tools from Xcode.
About this task
Create a makefile that builds MQTT client libraries for C for iPhone or iPad running an ARMv7 or ARMv7s processor, and the iPhone simulator that runs on an i386-64 bit processor. See List of iOS devices.
Procedure
Results
libmqttv3c.a.armv7
libmqttv3c.a.armv7s
libmqttv3c.a.i386
libmqttv3c.a
libmqttv3a.a.armv7
libmqttv3a.a.armv7s
libmqttv3a.a.i386
libmqttv3a.a
libmqttv3cs.a.armv7
libmqttv3cs.a.armv7s
libmqttv3cs.a.i386
libmqttv3cs.a
libmqttv3as.a.armv7
libmqttv3as.a.armv7s
libmqttv3as.a.i386
libmqttv3as.a
MQTTios.mak makefile listing
# Build output is produced in the current directory.
# MQTTCLIENT_DIR must point to the base directory containing the MQTT client source code.
# Default MQTTCLIENT_DIR is the current directory
# Default TOOL_DIR is /Applications/Xcode.app/Contents/Developer/Platforms
# Default OPENSSL_DIR is sdkroot/openssl, relative to sdkroot/sdk/clients/c/mqttv3c/src
# OPENSSL_DIR must point to the base directory containing the OpenSSL build.
# Example: make -f MQTTios.mak MQTTCLIENT_DIR=sdkroot/sdk/clients/c/mqttv3c/src all
ifndef MQTTCLIENT_DIR
MQTTCLIENT_DIR = ${CURDIR}
endif
VPATH = ${MQTTCLIENT_DIR}
ifndef OPENSSL_DIR
OPENSSL_DIR = ${MQTTCLIENT_DIR}/../../../../../openssl-1.0.1c
endif
ALL_SOURCE_FILES = ${wildcard ${MQTTCLIENT_DIR}/*.c}
ifndef TOOL_DIR
TOOL_DIR = /Applications/Xcode.app/Contents/Developer/Platforms endif
IPHONE_SDK = iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk
IPHONESIM_SDK = iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk
SDK_ARM = ${TOOL_DIR}/${IPHONE_SDK}
SDK_i386 = ${TOOL_DIR}/${IPHONESIM_SDK}
MQTTLIB = mqttv3c
SOURCE_FILES = ${filter-out ${MQTTCLIENT_DIR}/MQTTAsync.c ${MQTTCLIENT_DIR}/SSLSocket.c, ${ALL_SOURCE_FILES}}
MQTTLIB_DARWIN = darwin_x86_64/lib${MQTTLIB}.a
MQTTLIB_S = mqttv3cs
SOURCE_FILES_S = ${filter-out ${MQTTCLIENT_DIR}/MQTTAsync.c, ${ALL_SOURCE_FILES}}
MQTTLIB_DARWIN_S = darwin_x86_64/lib${MQTTLIB_S}.a
MQTTLIB_A = mqttv3a
SOURCE_FILES_A = ${filter-out ${MQTTCLIENT_DIR}/MQTTClient.c ${MQTTCLIENT_DIR}/SSLSocket.c, ${ALL_SOURCE_FILES}}
MQTTLIB_DARWIN_A = darwin_x86_64/lib${MQTTLIB_A}.a
MQTTLIB_AS = mqttv3as
SOURCE_FILES_AS = ${filter-out ${MQTTCLIENT_DIR}/MQTTClient.c, ${ALL_SOURCE_FILES}}
MQTTLIB_DARWIN_AS = darwin_x86_64/lib${MQTTLIB_AS}.a
# compiler
CC = iPhoneOS.platform/Developer/usr/bin/gcc
CC_armv7 = ${TOOL_DIR}/${CC} -arch armv7
CC_armv7s = ${TOOL_DIR}/${CC} -arch armv7s
CC_i386 = ${TOOL_DIR}/${CC} -arch i386
CCFLAGS = -Os -Wall -fomit-frame-pointer
CCFLAGS_SO_ARM = ${CCFLAGS} -isysroot ${SDK_ARM} -I${OPENSSL_DIR}/include -L${SDK_ARM}/usr/lib/system
CCFLAGS_SO_i386 = ${CCFLAGS} -isysroot ${SDK_i386} -I${OPENSSL_DIR}/include -L${SDK_i386}/usr/lib/system
# targets
all: ${MQTTLIB_DARWIN} ${MQTTLIB_DARWIN_A} ${MQTTLIB_DARWIN_AS} ${MQTTLIB_DARWIN_S}
${MQTTLIB_DARWIN}: ${SOURCE_FILES}
-mkdir darwin_x86_64
${CC_armv7} ${CCFLAGS_SO_ARM} -c ${SOURCE_FILES} -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_ARM} -o $@.armv7 *.o
rm *.o
${CC_armv7s} ${CCFLAGS_SO_ARM} -c ${SOURCE_FILES} -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_ARM} -o $@.armv7s *.o
rm *.o
${CC_i386} ${CCFLAGS_SO_i386} -c ${SOURCE_FILES} -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_i386} -o $@.i386 *.o
rm *.o
lipo -create $@.armv7 $@.armv7s $@.i386 -output $@
${MQTTLIB_DARWIN_A}: ${SOURCE_FILES_A}
-mkdir darwin_x86_64
${CC_armv7} ${CCFLAGS_SO_ARM} -c ${SOURCE_FILES_A} -DMQTT_ASYNC -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_ARM} -o $@.armv7 *.o
rm *.o
${CC_armv7s} ${CCFLAGS_SO_ARM} -c ${SOURCE_FILES_A} -DMQTT_ASYNC -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_ARM} -o $@.armv7s *.o
rm *.o
${CC_i386} ${CCFLAGS_SO_i386} -c ${SOURCE_FILES_A} -DMQTT_ASYNC -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_i386} -o $@.i386 *.o
rm *.o
lipo -create $@.armv7 $@.armv7s $@.i386 -output $@
${MQTTLIB_DARWIN_S}: ${SOURCE_FILES_S}
-mkdir darwin_x86_64
${CC_armv7} ${CCFLAGS_SO_ARM} -c ${SOURCE_FILES_S} -DOPENSSL -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_ARM} -L${OPENSSL_DIR}/armv7 -lssl -lcrypto -o $@.armv7 *.o
rm *.o
${CC_armv7s} ${CCFLAGS_SO_ARM} -c ${SOURCE_FILES_S} -DOPENSSL -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_ARM} -L${OPENSSL_DIR}/armv7s -lssl -lcrypto -o $@.armv7s *.o
rm *.o
${CC_i386} ${CCFLAGS_SO_i386} -c ${SOURCE_FILES_S} -DOPENSSL -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_ARM} -L${OPENSSL_DIR}/i386 -lssl -lcrypto -o $@.i386 *.o
rm *.o
lipo -create $@.armv7 $@.armv7s $@.i386 -output $@
${MQTTLIB_DARWIN_AS}: ${SOURCE_FILES_AS}
-mkdir darwin_x86_64
${CC_armv7} ${CCFLAGS_SO_ARM} -c ${SOURCE_FILES_AS} -DMQTT_ASYNC -DOPENSSL -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_ARM} -L${OPENSSL_DIR}/armv7 -lssl -lcrypto -o $@.armv7 *.o
rm *.o
${CC_armv7s} ${CCFLAGS_SO_ARM} -c ${SOURCE_FILES_AS} -DMQTT_ASYNC -DOPENSSL -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_ARM} -L${OPENSSL_DIR}/armv7s -lssl -lcrypto -o $@.armv7s *.o
rm *.o
${CC_i386} ${CCFLAGS_SO_i386} -c ${SOURCE_FILES_AS} -DMQTT_ASYNC -DOPENSSL -DUSE_NAMED_SEMAPHORES -DNOSIGPIPE
libtool -static -syslibroot ${SDK_ARM} -L${OPENSSL_DIR}/i386 -lssl -lcrypto -o $@.i386 *.o
rm *.o
lipo -create $@.armv7 $@.armv7s $@.i386 -output $@
.PHONY : clean
clean:
-rm -f *.obj
-rm -f -r darwin_x86_64
Building the MQTT libraries on Windows
Follow these steps to write a makefile to build the MQTT client libraries for C on Windows.
Before you begin
- If necessary, install a version of Make on your build workstation that is compatible with makefiles written for Gnu make; otherwise download Gnu make and build it. See Gnu Make. The website, Make for Windows, provides an installable version of Make for Windows.
- You also require Linux commands for Windows to use the clean target in the makefile example. You can obtain Linux commands for Windows from websites such as Cygwin.
About this task
Create a makefile that builds MQTT client libraries for C for Windows 32 bit.
Procedure
Results
mqttv3a.dll
mqttv3a.dll.manifest
mqttv3a.exp
mqttv3a.lib
mqttv3a.map
mqttv3as.dll
mqttv3as.dll.manifest
mqttv3as.exp
mqttv3as.lib
mqttv3as.map
mqttv3c.dll
mqttv3c.dll.manifest
mqttv3c.exp
mqttv3c.lib
mqttv3c.map
mqttv3cs.dll
mqttv3cs.dll.manifest
mqttv3cs.exp
mqttv3cs.lib
mqttv3cs.map
MQTTwin.mak makefile listing
# Build output is produced in the current directory.
# MQTTCLIENT_DIR must point to the base directory containing the MQTT client source code.
# Default MQTTCLIENT_DIR is the current directory
# Default OPENSSL_DIR is sdkroot\openSSL, relative to sdkroot\sdk\clients\c\mqttv3c\src
# OPENSSL_DIR must point to the base directory containing the OpenSSL build.
# Example: make -f MQTTwin.mak MQTTCLIENT_DIR=sdkroot/sdk/clients/c/mqttv3c/src
# Set the build environment, for example:
# %comspec% /k ""C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"" x86
# set path=%path%;C:\Program Files\GnuWin32\bin;C:\cygwin\bin
ifndef MQTTCLIENT_DIR
MQTTCLIENT_DIR = ${CURDIR}
endif
VPATH = ${MQTTCLIENT_DIR}
ifndef OPENSSL_DIR
OPENSSL_DIR = ${MQTTCLIENT_DIR}/../../../../../openssl-1.0.1c
endif
ALL_SOURCE_FILES = ${wildcard ${MQTTCLIENT_DIR}/*.c}
MQTTLIB = mqttv3c
MQTTDLL = windows_ia32/${MQTTLIB}.dll
SOURCE_FILES = ${filter-out ${MQTTCLIENT_DIR}/MQTTAsync.c ${MQTTCLIENT_DIR}/SSLSocket.c, ${ALL_SOURCE_FILES}}
MANIFEST = mt -manifest ${MQTTDLL}.manifest -outputresource:${MQTTDLL}\;2
MQTTLIB_S = mqttv3cs
MQTTDLL_S = windows_ia32/${MQTTLIB_S}.dll
SOURCE_FILES_S = ${filter-out ${MQTTCLIENT_DIR}/MQTTAsync.c, ${ALL_SOURCE_FILES}}
MANIFEST_S = mt -manifest ${MQTTDLL_S}.manifest -outputresource:${MQTTDLL_S}\;2
MQTTLIB_A = mqttv3a
MQTTDLL_A = windows_ia32/${MQTTLIB_A}.dll
SOURCE_FILES_A = ${filter-out ${MQTTCLIENT_DIR}/MQTTClient.c ${MQTTCLIENT_DIR}/SSLSocket.c, ${ALL_SOURCE_FILES}}
MANIFEST_S = mt -manifest ${MQTTDLL_S}.manifest -outputresource:${MQTTDLL_S}\;2
MQTTLIB_AS = mqttv3as
MQTTDLL_AS = windows_ia32/${MQTTLIB_AS}.dll
SOURCE_FILES_AS = ${filter-out ${MQTTCLIENT_DIR}/MQTTClient.c, ${ALL_SOURCE_FILES}}
MANIFEST_S = mt -manifest ${MQTTDLL_S}.manifest -outputresource:${MQTTDLL_S}\;2
# compiler
CC = cl
CPPFLAGS = /D "WIN32" /D "_UNICODE" /D "UNICODE" /D "_CRT_SECURE_NO_WARNINGS"
CFLAGS = /nologo /c /O2 /W3 /Fd /MD /TC
INC = /I ${MQTTCLIENT_DIR} /I ${MQTTCLIENT_DIR}/..
CPPFLAGS_S = ${CPPFLAGS} /D "OPENSSL"
INC_S = ${INC} /I ${OPENSSL_DIR}/inc32/
# linker
LD = link
LINKFLAGS = /nologo /machine:x86 /manifest /dll
WINLIBS = kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\
advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib\
odbc32.lib odbccp32.lib ws2_32.lib
IMP = /implib:${@:.dll=.lib}
LIBPDB = /pdb:${@:.dll=.pdb}
LIBMAP = /map:${@:.dll=.map}
WINLIBS_S = ${WINLIBS} crypt32.lib ssleay32.lib libeay32.lib
LIBPATH_S = /LIBPATH:${OPENSSL_DIR}/lib
# targets
all: ${MQTTDLL} ${MQTTDLL_A} ${MQTTDLL_AS} ${MQTTDLL_S}
${MQTTDLL}: ${SOURCE_FILES}
-mkdir windows_ia32
-rm ${CURDIR}/MQTTAsync.obj
${CC} ${CPPFLAGS} ${CFLAGS} ${INC} /Fo ${SOURCE_FILES}
${LD} ${LINKFLAGS} ${IMP} ${LIBPDB} ${LIBMAP} ${WINLIBS} *.obj /out:${MQTTDLL}
${MANIFEST}
${MQTTDLL_A}: ${SOURCE_FILES_A}
-mkdir windows_ia32
-rm ${CURDIR}/MQTTClient.obj
${CC} ${CPPFLAGS} ${CFLAGS} ${INC} /Fo ${SOURCE_FILES_A}
${LD} ${LINKFLAGS} ${IMP} ${LIBPDB} ${LIBMAP} ${WINLIBS} *.obj /out:${MQTTDLL_A}
${MANIFEST_A}
${MQTTDLL_S}: ${SOURCE_FILES_S}
-mkdir windows_ia32
-rm ${CURDIR}/MQTTAsync.obj
${CC} ${CPPFLAGS_S} ${CFLAGS} ${INC_S} /Fo ${SOURCE_FILES}
${LD} ${LINKFLAGS} ${IMP} ${LIBPDB} ${LIBMAP} ${WINLIBS_S} ${LIBPATH_S} *.obj /out:${MQTTDLL_S}
${MANIFEST_S}
${MQTTDLL_AS}: ${SOURCE_FILES_AS}
-rm ${CURDIR}/MQTTClient.obj
${CC} ${CPPFLAGS_S} ${CFLAGS} ${INC_S} /Fo ${SOURCE_FILES_AS}
${LD} ${LINKFLAGS} ${IMP} ${LIBPDB} ${LIBMAP} ${WINLIBS_S} ${LIBPATH_S} *.obj /out:$(MQTTDLL_AS}
$(MANIFEST_AS}
.PHONY : clean
clean:
-rm -f *.obj
-rm -f -r windows_ia32
Building the OpenSSL package
Build the OpenSSL package before you build the secure MQTT client libraries for C, mqttv3cs and mqttv3as. The build creates the libraries that are required to build a secure version of the MQTT client for C library, and the OpenSSL certificate management tool.
Before you begin
- The iOS makefile customization is for target devices that run iOS6. The customization might be different for earlier or later versions of iOS.
- The Windows makefile customization is for 32-bit windows.
About this task
Procedure
Results
The build generates the shared libraries, lib, and header files that are required to build secure versions of the MQTT client library for C.