Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trouble compiling using MQTT transport #2435

Open
Umair772 opened this issue Jan 24, 2023 · 11 comments
Open

Trouble compiling using MQTT transport #2435

Umair772 opened this issue Jan 24, 2023 · 11 comments
Labels

Comments

@Umair772
Copy link

Umair772 commented Jan 24, 2023

Development Machine, OS, Compiler (and Other Relevant Toolchain Info)

Cross Compiled on Ubuntu 20.04 using GNU 9.4.0

SDK Version (Please Give Commit SHA if Manually Compiling)

lts_01_2023

Protocol

MQTT/HTTP

Describe the Bug

I'm having the same issue as this person here #1479. I didn't find a solution on his thread regarding the fix. His issue was with the Prov_device_HTTP_Protocol mine is the Prov_device_MQTT_Protocol

undefined reference to Prov_Device_MQTT_Protocol

CMakeFiles/iotd.dir/azure_iot_ctrl.cpp.o: In function `azure_iot_ctrl::iot_provision()':
/home/umair/ASP/asp/iotmgmt/azure_iot_ctrl.cpp:2176: undefined reference to `Prov_Device_MQTT_Protocol'
/home/umair/ASP/asp/iotmgmt/azure_iot_ctrl.cpp:2176: undefined reference to `Prov_Device_MQTT_Protocol'
collect2: error: ld returned 1 exit status
make[3]: *** [iotmgmt/CMakeFiles/iotd.dir/build.make:177: iotmgmt/iotd] Error 1
make[2]: *** [CMakeFiles/Makefile2:919: iotmgmt/CMakeFiles/iotd.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:931: iotmgmt/CMakeFiles/iotd.dir/rule] Error 2
make: *** [Makefile:372: iotd] Error 2

From the same line of code:

PROV_DEVICE_TRANSPORT_PROVIDER_FUNCTION prov_transport = Prov_Device_MQTT_Protocol;

Headers included:

#include <azure_prov_client/prov_device_client.h>
#include <azure_prov_client/prov_security_factory.h>
#include <azure_prov_client/prov_transport_mqtt_client.h>
#include <azure_c_shared_utility/crt_abstractions.h>
#include <azure_c_shared_utility/shared_util_options.h>
#include <azure_c_shared_utility/threadapi.h>
#include <iothub.h>
#include <iothub_client.h>
#include <iothub_client_core.h>
#include <iothub_client_core_common.h>
#include <iothub_client_options.h>
#include <iothub_device_client.h>
#include <iothub_message.h>
#include <iothubtransportmqtt.h>

CMake file:

cmake_minimum_required(VERSION 3.8)

project(iotmgmt)

include(../CommonCMake.txt)

#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azureiot")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/c-utility/inc/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/provisioning_client/inc/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/provisioning_client/inc/azure_prov_client/internal/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/provisioning_client/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/provisioning_client/adapters/")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/c-utility/inc/azure_c_shared_utility/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/iothub_client/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/iothub_client/inc/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/iothub_client/inc/internal/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/deps/umock-c/inc/")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I=/usr/include/azure-iot-sdk-c/deps/azure-macro-utils-c/inc/")
#add_subdirectory(../azure-iot-sdk-c out)
set_source_files_properties(iotmgmt_states.cpp PROPERTIES COMPILE_FLAGS -Wno-psabi)
add_executable(iotd iotmgmt.cpp iotmgmt_states.cpp azure_hsm_client.cpp azure_iot_ctrl.cpp)
target_link_libraries(iotd msg asp gain_config iothub_client aziotsharedutil_dll prov_device_client curl zmq rt z)

# ESX uses Azure IOT SDK 1.3.8 with the following dependencies
if(${PRODUCT} MATCHES "esx")
  target_link_libraries(iotd prov_mqtt_transport umqtt)
endif()

install(TARGETS iotd DESTINATION /usr/bin)
install(FILES iotd.service DESTINATION /lib/systemd/system)
install(FILES iot_conf.json DESTINATION /etc/iot)

I also tried running a nm command on an old version of the SDK shared object and the latest version to see whether that particular function is included in both but it was included in the older version of the shared object and not the new.

 nm --print-file-name --dynamic libprov_device_client.so.1.2.10 | grep Prov_Device_MQTT_Protocol
libprov_device_client.so.1.2.10:000135b0 T Prov_Device_MQTT_Protocol
nm --print-file-name --dynamic libprov_device_client.so.1.10.0 | grep Prov_Device_MQTT_Protocol
No output

Thanks in advance!

Update:

I noticed that when I set the Use_installed_dependencies flag in the cmake file, I get these build errors for azure-macro-utils-c. I think this issue I'm facing with Prov_Device_MQTT_Protocol could be related to this flag not being set before building all the SDK binaries, reason why that function(Prov_Device_MQTT_Protocol) is not found in the shared object.

Capture_new

@benjaesq
Copy link

I see the same problem, I can't find any of the mqtt symbols in the static or dynamic libraries.

Here's the procedure I have to reproduce the problem:

  1. Clone this repository
  2. Follow the build instructions but instead of the plain cmake config do this:
    cmake -Duse_mqtt:BOOL=ON -Dbuild_as_dynamic:BOOL=ON -Duse_prov_client:BOOL=ON ..
  3. make
  4. check the symbols on the new built libprov_device_client.so and grep for MQTT or mqtt.

Result: mqtt symbols are not present in libprov_device_client.so

I also tried removing the build as dynamic config switch and searching for the mqtt symbols in the libprov_device_client.a but they're also not present.

I currently can't link any mqtt functionality, any suggestions?

@danewalton danewalton self-assigned this Jan 27, 2023
@ericwolz
Copy link
Contributor

ericwolz commented Feb 7, 2023

Prov_Device_MQTT_Protocol is in prov_transport_mqtt_client.c

const PROV_DEVICE_TRANSPORT_PROVIDER* Prov_Device_MQTT_Protocol(void)

You need to build prov_device_client with the cmake -Duse_mqtt:BOOL=ON option

@ericwolz
Copy link
Contributor

ericwolz commented Feb 8, 2023

@benjaesq the mqtt symbols will be in the prov_mqtt_transport library.

libprov_device_client does not call directly into MQTT as it can also support AMQP and HTTP protocols (and websockets). This is done via a jump table called PROV_DEVICE_TRANSPORT_PROVIDER.

static PROV_DEVICE_TRANSPORT_PROVIDER prov_mqtt_func =

@benjaesq
Copy link

benjaesq commented Feb 10, 2023

@benjaesq the mqtt symbols will be in the prov_mqtt_transport library.

Hi @ericwol-msft, thanks for your response. Yes, the symbols are indeed in prov_mqtt_transport.a and I can successfully link to it statically but what I noticed is that the build_as_dynamic flag has no effect in the prov_mqtt_transport library, and a shared object is not produced.

The other libraries I use from the SDK produce shared objects so I thought this could be a fix you could consider.

@ericwolz
Copy link
Contributor

@benjaesq Thanks, I understand now and will investigate.

@domasgim
Copy link

domasgim commented Feb 15, 2023

FYI I have the same problem as well, undefined reference to Prov_Device_MQTT_Protocol. I was using static compiling against the SDK with no issues and was later forced to switch to building against SDK's shared object files with -Dbuild_as_dynamic:BOOL=ON due to Parson library issues when using third party JSON parsing libraries. -Duse_mqtt:BOOL=ON option is used.

Development Machine, OS, Compiler (and Other Relevant Toolchain Info)

Cross Compiled on Ubuntu 22.04

SDK Version (Please Give Commit SHA if Manually Compiling)

LTS_07_2022_Ref02 3fd808bee3c88f8578dcc30c0a6d1d396c172070

Protocol

MQTT

@domasgim
Copy link

Any news regarding this issue? Perhaps there is a temporary workaround?

@ericwolz
Copy link
Contributor

There is no current workaround. You would need to build your own .so for this.

@domasgim
Copy link

domasgim commented Mar 1, 2023

For anyone looking for a temporary solution adding SHARED flag to a couple of libraries on provisioning_client/CMakeLists.txt did the trick. It will compile the necessary .so shared libraries. Of course you'd have to link these libraries as well.

From 3fd808bee3c88f8578dcc30c0a6d1d396c172070
--- a/provisioning_client/CMakeLists.txt
+++ b/provisioning_client/CMakeLists.txt
@@ -204,14 +204,14 @@ if(WIN32)
     add_definitions(-D_CRT_SECURE_NO_WARNINGS)
 ENDIF(WIN32)
 
-add_library(hsm_security_client ${HSM_CLIENT_C_FILES} ${HSM_CLIENT_H_FILES})
+add_library(hsm_security_client SHARED ${HSM_CLIENT_C_FILES} ${HSM_CLIENT_H_FILES})
 applyXcodeBuildFlagsIfNeeded(hsm_security_client)
 linkSharedUtil(hsm_security_client)
 target_link_libraries(hsm_security_client ${HSM_CLIENT_LIBRARY})
 set(provisioning_libs ${provisioning_libs} hsm_security_client)
 set(provisioning_headers ${provisioning_headers} ${HSM_CLIENT_H_FILES})
 
-add_library(prov_auth_client ${AUTH_CLIENT_C_FILES} ${AUTH_CLIENT_H_FILES})
+add_library(prov_auth_client SHARED ${AUTH_CLIENT_C_FILES} ${AUTH_CLIENT_H_FILES})
 applyXcodeBuildFlagsIfNeeded(prov_auth_client)
 linkSharedUtil(prov_auth_client)
 target_link_libraries(prov_auth_client hsm_security_client)
@@ -354,7 +354,7 @@ if(${use_prov_client} OR (${use_prov_cli
         set(provisioning_headers ${provisioning_headers} ${PROV_MQTT_WS_CLIENT_H_FILES})
 
         # Provisioning mqtt Transport Client library
-        add_library(prov_mqtt_transport ${PROV_MQTT_CLIENT_C_FILES} ${PROV_MQTT_CLIENT_H_FILES})
+        add_library(prov_mqtt_transport SHARED ${PROV_MQTT_CLIENT_C_FILES} ${PROV_MQTT_CLIENT_H_FILES})
         applyXcodeBuildFlagsIfNeeded(prov_mqtt_transport)
         linkSharedUtil(prov_mqtt_transport)
         target_link_libraries(prov_mqtt_transport umqtt)

@benjaesq
Copy link

benjaesq commented Mar 9, 2023

For anyone looking for a temporary solution adding SHARED flag to a couple of libraries on provisioning_client/CMakeLists.txt did the trick. It will compile the necessary .so shared libraries. Of course you'd have to link these libraries as well.

this workaround is a bit rough, I'm not doubting that it works for your case but it disregards the build_as_dynamic setting and I don't see how this will provide so versioning (might fail under some build systems or exec environments).

@besquivel-pivotal
Copy link

Please review my PR #2505 and kindly let me know if this solution works.

Thanks!

@danewalton danewalton removed their assignment Jul 24, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants
@benjaesq @danewalton @ericwolz @domasgim @Umair772 @besquivel-pivotal and others