PelionIoT / mbed-cloud-client-example

Reference example application using Izuma Device Management Client library
https://izumanetworks.com
Apache License 2.0
30 stars 97 forks source link

Build problem: inadequate handling of cyclic dependencies #75

Open egrimley-arm opened 4 years ago

egrimley-arm commented 4 years ago

This recipe for reproducing the problem isn't ideal because it's a bit over-complicated and Bullseye is not yet released so may change significantly, but perhaps it will continue working for long enough to be useful:

docker run -it debian:bullseye /bin/bash

apt-get update
apt-get install --no-install-recommends -y \
  ca-certificates cargo cmake g++ git libclang-dev make \
  mercurial python3-click python3-pip

python3 -m pip install mbed-cli

cd
git clone https://github.com/ARMmbed/mbed-cloud-client-example
cd mbed-cloud-client-example
mbed deploy
perl -i -pe 's/^/# / if !/^#/ && /DEVELOPER_MODE/;' define.txt
python3 pal-platform/pal-platform.py deploy \
  --target=x86_x64_NativeLinux_mbedtls generate
cd __x86_x64_NativeLinux_mbedtls
cmake -G "Unix Makefiles" \
  -DPARSEC_TPM_SE_SUPPORT=ON -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_TOOLCHAIN_FILE=../pal-platform/Toolchain/GCC/GCC.cmake \
  -DEXTERNAL_DEFINE_FILE=../define_linux_psa.txt
make -j8
make VERBOSE=1

The error I see is:

storage_psa.cpp:(.text+0x153d): undefined reference to `g_fcc_bootstrap_device_private_key_name'

It comes from the -Wl,--start-group and the -Wl,--end-group not being in the right places: there are a lot of libraries listed after the -Wl,--end-group. If you take the g++ command that is shown by VERBOSE=1 and move the -Wl,--end-group to the end then the command works.

The -Wl,--start-group and the -Wl,--end-group come from pal-platform/mbedCloudClientCmake.txt, where they are inserted using TARGET_LINK_LIBRARIES. This is an ugly hack because those arguments are not libraries. There's plenty of discussion of this problem on cmake.org and stackoverflow.com. But it's not clear what the correct solution is.

Probably it ought to be possible to link without those linker options. See: https://cmake.org/cmake/help/v3.3/command/target_link_libraries.html#cyclic-dependencies-of-static-libraries

In this particular case the undefined symbol is defined in the library factory-configurator-client and used in fccstorage. So I tried adding this line in mbed-cloud-client/factory-configurator-client/CMakeLists.txt:

add_dependencies(fccstorage factory-configurator-client)

However I then got the following error from cmake, which confuses me because it looks like a cyclic dependency of static libraries, which ought to be allowed according to the documentation linked to above:

CMake Error: The inter-target dependency graph contains the following strongly connected component (cycle):
  "factory-configurator-client" of type STATIC_LIBRARY
    depends on "fccstorage" (weak)
    depends on "key-config-manager" (weak)
    depends on "pal" (weak)
    depends on "palTLS" (weak)
    depends on "palTime" (weak)
    depends on "key-config-manager" (strong)
    depends on "fccstorage" (strong)
    depends on "pal" (strong)
  "key-config-manager" of type STATIC_LIBRARY
    depends on "fccstorage" (weak)
    depends on "fccstorage" (strong)
  "fccstorage" of type STATIC_LIBRARY
    depends on "key-config-manager" (weak)
    depends on "factory-configurator-client" (strong)
  "palTime" of type STATIC_LIBRARY
    depends on "fccstorage" (weak)
    depends on "key-config-manager" (weak)
    depends on "fccstorage" (strong)
  "pal" of type STATIC_LIBRARY
    depends on "palTLS" (weak)
    depends on "palTime" (weak)
    depends on "fccstorage" (weak)
    depends on "key-config-manager" (weak)

So probably this is something for CMake experts.

teetak01 commented 3 years ago

@egrimley-arm we are currently looking in the CMake issues. We aim to resolve these in future.

teetak01 commented 3 years ago

Internal ref: https://armiot.atlassian.net/browse/IOTCLT-4986