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

Issues cross-compiling using an ARM custom toolchain #58

Closed
mmdsantos opened this issue Feb 6, 2017 · 24 comments
Closed

Issues cross-compiling using an ARM custom toolchain #58

mmdsantos opened this issue Feb 6, 2017 · 24 comments
Assignees

Comments

@mmdsantos
Copy link

Hello all,

I am trying to compile the SDK for C, using Cmake and a toolchain for an ARM processor. I am having the following error:

CMake Error at /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
  Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
  system variable OPENSSL_ROOT_DIR (missing: OPENSSL_LIBRARIES
  OPENSSL_INCLUDE_DIR)
Call Stack (most recent call first):
  /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:388 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake-3.5/Modules/FindOpenSSL.cmake:370 (find_package_handle_standard_args)
  c-utility/CMakeLists.txt:132 (find_package)

Any tips on how to keep going from here?

Thank you

@anporumb
Copy link
Contributor

anporumb commented Feb 6, 2017

Hello @mmdsantos ,

We suspect that you do not have OpenSSL pointed to by your compilation environment. It looks like your custom toolchain needs to find some environment variables called "OPENSSL_LIBRARIES" and/or "OPENSSL_INCLUDE_DIR".

How do we repro your error locally?

Best Regards,
Andrei Porumb

@mmdsantos
Copy link
Author

Hello @anporumb ,

Thank you very much for your fast answer. I followed the guide to setup a Linux development environment, https://github.com/Azure/azure-iot-sdk-c/blob/master/doc/devbox_setup.md#linux, and I used a custom cmake file to link my compiler, the same I use for compiling other libraries. And instead of "cmake ..", i used the command:
"cmake .. -DCMAKE_TOOLCHAIN_FILE=arm926ejs.cmake -DCMAKE_INSTALL_PREFIX=/usr/local/arm926ejs-gcc446-x86/arm-unknown-linux-gnueabi/"

Do you have any ideia how can I point the OpenSSL by the compilation environment? Or what should I do differently from the guide, to compile it with my cross-compiler?

Best Regards,
Miguel

@vjrantal
Copy link
Contributor

vjrantal commented Feb 7, 2017

@mmdsantos: I run into this recently and in my case, was able to solve it by setting the use_openssl flag off. You can see the build script and cmake file I used at https://github.com/vjrantal/azure-iot-sdk-c/tree/latest-rtos-sdk/build_all/esp8266 and the most relevant line is https://github.com/vjrantal/azure-iot-sdk-c/blob/latest-rtos-sdk/build_all/esp8266/build.sh#L37 where you see the mentioned flag being set.

@anporumb
Copy link
Contributor

anporumb commented Feb 7, 2017

Hello @mmdsantos ,

We believe that your cross compile toolchain isn't informing CMake about the location openssl. We'd recommend taking two actions:

  1. download the openssl for your platform that you intend to crosscompile for.
  2. when using CMake, add -DOPENSSL_ROOT_DIR=<<location_where_openssl_is>>

Best Regards,
Andrei Porumb

@mmdsantos
Copy link
Author

@vjrantal and @anporumb , thank you very much for your answers.

You were right about openssl, and I managed to fix it. The cmake command went well, no errors, but now the "cmake --build ." command is giving me some new problems.

It says:

/home/miguel/Desktop/Azure/c-sdk/azure-iot-sdk-c-arm926/c-utility/adapters/uniqueid_linux.c:7:23: error: uuid/uuid.h: No such file or directory
/home/miguel/Desktop/Azure/c-sdk/azure-iot-sdk-c-arm926/c-utility/adapters/uniqueid_linux.c: In function 'UniqueId_Generate':

Any idea what I did wrong? Thank you

@vjrantal
Copy link
Contributor

The cmake files has the following section:

         if (${use_default_uuid})
              set(UNIQUEID_C_FILE ${c_shared_dir}/adapters/uniqueid_stub.c PARENT_SCOPE)

So, if you define use_default_uuid (something like this https://github.com/vjrantal/azure-iot-sdk-c/blob/latest-rtos-sdk/build_all/esp8266/build.sh#L17) you should end up with a stub that worked at least in my case.

@mmdsantos
Copy link
Author

@vjrantal

Thanks for the tip, I set the use_default_uuid to ON, but now I have more errors, regarding curl:
error: curl/curl.h: No such file or directory
I just want to try to send and receive simple MQTT messages from my device, to see if the SDK works on it, but it is not being easy at all :(

@vjrantal
Copy link
Contributor

@mmdsantos For the curl error, you could try turning off building the HTTP transport https://github.com/vjrantal/azure-iot-sdk-c/blob/latest-rtos-sdk/build_all/esp8266/build.sh#L12.

@mmdsantos
Copy link
Author

@vjrantal, thanks for your answer, but I still can't do it. To me isn't clear the exact steps I need to do in order to compile the SDK using a custom toolchain. What steps did you follow to end up with the esp8266 directory in the build_all directory? I am assuming that following the same steps I would end up with an equivalent to my toolchain? But the whole process is not clear at all for me

@vjrantal
Copy link
Contributor

@mmdsantos May I ask what is the target hardware and software stack that you are targeting with the custom toolchain?

I started from https://github.com/Azure/azure-iot-sdk-c/blob/master/doc/SDK_cross_compile_example.md but since with a custom toolchain one may get "custom errors", I ended up doing some amount of "trial and error"-style debugging.

Are you still stuck with error: curl/curl.h: No such file or directory or did it help to turn off HTTP transport?

@mmdsantos
Copy link
Author

@vjrantal Sure,

Processor	: ARM926EJ-S rev 4 (v5l)
Linux version 2.6.39.2

I managed to successfully compile the SDK by setting use_http:BOOL=OFF in the CMakeCache.txt file.

I tried to run the iothuv_client_sample_mqtt on my hardware. The program ran, but it received no response from the Hub. Can it be for having http disabled, or can it be something else? I changed the .c file to include the connection string from a device I created. I will look into it to try to understand what went wrong

@mmdsantos
Copy link
Author

@vjrantal When you cross compile, what files do you copy to your target device? I just copied the Executable file, but maybe I didn't copy some other required files, such as libraries, or certificates? It is not clear in the documentation what files need to be in the device

@vjrantal
Copy link
Contributor

@mmdsantos In my case, the toolchain creates a flashable image that contains everything.

Do you have any output from the program when you run it? Or, does it crash when you run it?

@mmdsantos
Copy link
Author

@vjrantal No, the program doesn't crash. It runs, tries to send the messages, and keeps waiting for feedback, but the messages are not arriving to IoT Hub. In the IoT Hub Portal dashboard, I see no increase in the number of messages. The output is:

# ./iothub_client_sample_mqtt 
Info: IoT Hub SDK for C, version 1.1.7
IoTHubClient_LL_SetMessageCallback...successful.
IoTHubClient_LL_SendEventAsync accepted message [0] for transmission to IoT Hub.
IoTHubClient_LL_SendEventAsync accepted message [1] for transmission to IoT Hub.
IoTHubClient_LL_SendEventAsync accepted message [2] for transmission to IoT Hub.
IoTHubClient_LL_SendEventAsync accepted message [3] for transmission to IoT Hub.
IoTHubClient_LL_SendEventAsync accepted message [4] for transmission to IoT Hub.

And it stays in this state until I terminate the program.

@dcristoloveanu
Copy link
Member

Hi @mmdsantos,

I understand the latest is that you were able to run the MQTT sample on your OS/device.
Many Linux distros do not have all the certificates or OpenSSL does not use the default OS store.

In those cases it is needed to pass the certificate information to the SDK by using:

            if (IoTHubClient_LL_SetOption(iotHubClientHandle, "TrustedCerts", certificates) != IOTHUB_CLIENT_OK)
            {
                printf("failure to set option \"TrustedCerts\"\r\n");
            }

The certificates are in the certs.c file in our repo.
If you are already doing that then you have a different issues, but it is worth checking this first.

Let me know.

Thanks,
/Dan

@mmdsantos
Copy link
Author

@dcristoloveanu, thank you for your answer. It worked but I had to copy the certificates variable inside the certs.c file to the iothub_client_sample_mqtt.c file. I believe that this is not the cleanest way to do it and it should exist a better solution.

The code you referred to is inside a conditional "#ifdef MBED_BUILD_TIMESTAMP". Where should I define this variable so that it includes the certificates variable? Sorry if this is a basic question :)

Thanks for the help,

Miguel

@dcristoloveanu
Copy link
Member

@mmdsantos glad to hear it worked.

If you want to also compile the certs.c file in the mqtt sample you have to add it in the CMakeLists for that sample. Then you would not need to copy/paste the certificates in the sample.

The reason setting the trusted certs is guarded by MBED_BUILD_TIMESTAMP is that typically for Linux distros that do have updated certs that is not needed, but it was always needed for our ARM MBED sample (which runs on an RTOS without an OS supported cert store).

We planned a change to simply set the TrustedCerts in all cases (as it cannot hurt), but that did not make it to be a priority right now.

If this makes it easier for you, feel free to submit a PR to have the TrustedCerts option set all the time and we'll pull this in (The only problem is that for consistency it should be done on all samples ...).

Thanks,
/Dan

@mmdsantos
Copy link
Author

@dcristoloveanu , thank you very much for your help

For now I will just try to build something, using the sample as the starting point.

Regards, Miguel

@dcristoloveanu
Copy link
Member

@mmdsantos No worries. I will close this issue now, if you hit more problems, feel free to open new issue.

@HarishKavali
Copy link

what is the difference between use_default_uuid = on and use_default_uuid = off.

@vjrantal
Copy link
Contributor

@HarishKavali the flag is used to determine which file gets included as the implementation of UUID generation (see https://github.com/Azure/azure-c-shared-utility/blob/8c9173f4ad7eb528efbc3f6a929e01d65aa77cd1/devdoc/uniqueid_requirements.md) and with use_default_uuid = on the stub gets used (see https://github.com/Azure/azure-c-shared-utility/blob/6f2e173407031b147bab3492edcf407ffeb87c81/configs/azure_c_shared_utilityFunctions.cmake#L513).

The stub might not meet production requirements of a system and the suggestion to try with the stub (in a comment above) was just for testing purposes.

@HarishKavali
Copy link

Hi vjrantal.

you mean to say that "use_default_uuid=on" flag can be used only for testing purpose.
then to resolve uuid dependency in production should i build lib uuid for my device.
currently uuid is not there for my machine.

Thanks,
Harish

@vjrantal
Copy link
Contributor

@HarishKavali I don't have the authority to say when it can be used, but you can search for UniqueId_Generate in the codebase you are building and see where the generated UUID is used and try to evaluate how important randomness in these cases is for your scenario.

@markrad
Copy link
Member

markrad commented Aug 25, 2017

libuuid is part of the Linux kernel utilities. If you have the library in your cross compile toolchain then you could simply add the header file to the appropriate location in your sysroot, typically /usr/uuid/uuid.h. If you don't have the library then you always have the option of cross compiling it first. You can find it in here https://www.kernel.org/pub/linux/utils/util-linux/v2.30/ or you might try using a version that has been extracted as a stand alone module such as this https://sourceforge.net/projects/libuuid/. I have no idea if the versions outside the kernel are reliable though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants