commschamp / cc.mqttsn.libs

CommsChampion Ecosystem MQTT-SN client / gateway libraries and applications
Mozilla Public License 2.0
63 stars 16 forks source link

Add to existing CMake project #1

Closed a1lu closed 4 years ago

a1lu commented 4 years ago

Hi, I tried to add this library into my existing CMake project to compile it for my bare metal platform. I had two issues doing this:

  1. comms_champion cannot be compiled because arm-none-eabi-gcc.exe: error: unrecognized option '-rdynamic' I solved this by adding -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY to the external project CMAKE_ARGS (in https://github.com/arobenko/mqtt-sn/blob/ee28c7e06568758f227bbaf2f61c75379715f57f/CMakeLists.txt#L181-L182)

  2. The option.h file could not be included because the include directory is set for a standalone project (https://github.com/arobenko/mqtt-sn/blob/ee28c7e06568758f227bbaf2f61c75379715f57f/client/CMakeLists.txt#L131) Changing this line to ${CMAKE_CURRENT_SOURCE_DIR}/../protocol/include solves this and the library compiles on my end.

I am not sure if the first one does not break other builds, since this forces the compiler to generate a static lib. I have no experience with ExternalProject. . Maybe it's a better way to use the BUILD_SHARED option (https://cmake.org/cmake/help/v3.0/variable/BUILD_SHARED_LIBS.html).

The second fix should work for standalone project.

If you like I can create a pull request with the second change, the first needs some discussion IMO.

kind regards

arobenko commented 4 years ago

Hi @a1lu For the first problem, can you compile this project separately using your arm toolchain (sourcing the whole build environment preparation file provided by your toolchain)?

As for the second reported problem I don't recommend using my project as a submodule (or similar). Instead, try to use ExternalProject_Add() inside you cmake files and then update your dependencies accordingly.

a1lu commented 4 years ago

Hi @arobenko I tried to compile this project using the cmake call from build two custom client libraries and added my toolchain file.

cmake -DCMAKE_BUILD_TYPE=Release -DCC_MQTTSN_CLIENT_DEFAULT_LIB=OFF \
    -DCC_MQTTSN_BUILD_GATEWAY=OFF \
    -DCC_MQTTSN_CUSTOM_CLIENT_CONFIG_FILES=config1.cmake 
    -DCMAKE_TOOLCHAIN_FILE=../../arm-gcc-toolchain.cmake ..

Result:

% make -j
Scanning dependencies of target bare_metal_client.cpp.tgt
Scanning dependencies of target bare_metal_client.h.tgt
Scanning dependencies of target comms_champion_external
[  7%] Generating bare_metal_client.cpp
[ 15%] Creating directories for 'comms_champion_external'
[ 23%] Generating bare_metal_client.h
[ 23%] Built target bare_metal_client.cpp.tgt
[ 23%] Built target bare_metal_client.h.tgt
[ 30%] Performing download step (git clone) for 'comms_champion_external'
Clone to 'src' ...
Note: checking out 'v1.3'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at af045db... Release v1.3
[ 38%] No patch step for 'comms_champion_external'
[ 46%] Performing update step for 'comms_champion_external'
[ 53%] Performing configure step for 'comms_champion_external'
-- The C compiler identification is GNU 7.3.1
-- The CXX compiler identification is GNU 7.3.1
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc
-- Check for working C compiler: /usr/bin/arm-none-eabi-gcc -- broken
CMake Error at CMakeTestCCompiler.cmake:60 (message):
  The C compiler

    "/usr/bin/arm-none-eabi-gcc"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: mqtt-sn/build/comms_champion/build/CMakeFiles/CMakeTmp

    Run Build Command(s):/usr/bin/make cmTC_960a8/fast && make[3]: Verzeichnis „mqtt-sn/build/comms_champion/build/CMakeFiles/CMakeTmp“ wird betreten
    /usr/bin/make -f CMakeFiles/cmTC_960a8.dir/build.make CMakeFiles/cmTC_960a8.dir/build
    make[4]: Verzeichnis „mqtt-sn/build/comms_champion/build/CMakeFiles/CMakeTmp“ wird betreten
    Building C object CMakeFiles/cmTC_960a8.dir/testCCompiler.c.o
    /usr/bin/arm-none-eabi-gcc    -o CMakeFiles/cmTC_960a8.dir/testCCompiler.c.o   -c mqtt-sn/build/comms_champion/build/CMakeFiles/CMakeTmp/testCCompiler.c
    Linking C executable cmTC_960a8
    cmake -E cmake_link_script CMakeFiles/cmTC_960a8.dir/link.txt --verbose=1
    /usr/bin/arm-none-eabi-gcc      -rdynamic CMakeFiles/cmTC_960a8.dir/testCCompiler.c.o  -o cmTC_960a8 
    arm-none-eabi-gcc: error: unrecognized command line option '-rdynamic'
    CMakeFiles/cmTC_960a8.dir/build.make:86: die Regel für Ziel „cmTC_960a8“ scheiterte
    make[4]: *** [cmTC_960a8] Fehler 1
    make[4]: Verzeichnis „mqtt-sn/build/comms_champion/build/CMakeFiles/CMakeTmp“ wird verlassen
    Makefile:121: die Regel für Ziel „cmTC_960a8/fast“ scheiterte
    make[3]: *** [cmTC_960a8/fast] Fehler 2
    make[3]: Verzeichnis „mqtt-sn/build/comms_champion/build/CMakeFiles/CMakeTmp“ wird verlassen

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)

-- Configuring incomplete, errors occurred!

I tried to compile comms_champion by itself using the arm toolchain file and it builds.

% cmake -DCMAKE_TOOLCHAIN_FILE=arm-gcc-toolchain.cmake -DCC_COMMS_LIB_ONLY=ON -DCMAKE_INSTALL_PREFIX=install ..

I figured out, that the ExternalProject call sets the variables CMAKE_C_COMPILER and CMAKE_CXX_COMPILER but not the CMAKE_SYSTEM_NAME to Generic for bare metal. If I change the CMAKE_ARGS to

CMAKE_ARGS 
    -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${install_dir} 
    -DCC_NO_UNIT_TESTS=ON -DCC_NO_WARN_AS_ERR=ON -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
    -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
    ${cc_qt_dir_opt} ${ct_lib_only_opt}

it works as expected.

Best regards a1lu

arobenko commented 4 years ago

I don't understand, the bottom line: does it or does it NOT work for you?

a1lu commented 4 years ago

If I build it out of the box it does not work. If I pass the toolchain file into the comms_champions project through CMAKE_ARGS it works.

arobenko commented 4 years ago

Hi @a1lu At this moment I'm a bit busy with my other projects, and thanks to the fact that you can make it work for you using CMAKE_ARGS, this issue becomes of low priority now. I don't know when I'll have a time to introduce proper fix.

a1lu commented 4 years ago

Alright, thanks for your work!

a1lu commented 4 years ago

I sent you PR #2

arobenko commented 4 years ago

Is this problem still relevant for v0.9 release?

a1lu commented 4 years ago

Hi, sorry for the delay. Yes this is still relevant.

I still get the error about -rdynamic cmake.txt make.txt

I had two possible solutions for this in my first post here ( add -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY or use BUILD_SHARED). After adding -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY i could make the project.

arobenko commented 4 years ago

Hi @a1lu, Sorry for the delay on this issue, was busy with something else. At this moment the "develop" branch contains the following modifications:

I'll appreciate it if you could test it and tell me if it works "out of the box" for you without any patches on your side. I'm planning to do v0.11 release soon with current modifications.

Thanks

a1lu commented 4 years ago

Hi @arobenko thanks for the update. I checked the code and it looks good so far for the toolchain file. I hope to find some time to test it in the following days.

What about the -rdynamic issue? Am I supposed to pass -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY in the toolchain?

Regards a1lu

arobenko commented 4 years ago

I don't have a definite answer for you, I don't have your environment / configuration. Just try it, pass it in the toolchain file or as extra CMake arguments to relevant external project I'm using inside. Maybe using a toolchain file passed to other projects won't emit the "-rdynamic any more. I don't know.

a1lu commented 4 years ago

I tried it and did not get the -rdynamic error anymore, since all calls to add_library() in this and the externals specify either STATIC or INTERFACE. Seems this was fixed in CommsChampions?

It works for me now, thanks.