a9183756-gh / Arduino-CMake-Toolchain

CMake toolchain for all Arduino compatible boards
MIT License
135 stars 40 forks source link

[Question/Bug] target_link_arduino_libraries - possible bug #43

Open Jonas18175 opened 3 years ago

Jonas18175 commented 3 years ago

Hello,

I dedected a problem in using of target_link_arduino_libraries. I installed the ESPAsyncWiFiManager lib and added it to the target_link_arduino_libraries in cmake. Other libs that I had downloaded and installed works without problems, but on this it had a problem with including/finding DNSServer.h header - which is a lib from Arduino Core.

Is there a workaround for this? My workaround is very ugly:

## WiFiManager Fix

set(wifiManagerLibName _arduino_lib_WiFiManager)
set(wifiManagerLibDeps ESP8266WebServer)

if (USE_ASYNC_WEBSERVER)
find_arduino_library(ESPAsyncWiFiManager WiFiManagerLibPath)
set(wifiManagerLibName _arduino_lib_ESPAsyncWiFiManager)
set(wifiManagerLibDeps ESPAsyncWebServer)
else()
find_arduino_library(WiFiManager WiFiManagerLibPath)
endif()

file(GLOB_RECURSE _arduino_lib_WiFiManager_source_list "${WiFiManagerLibPath}/.cpp" "${WiFiManagerLibPath}/.hpp" "${WiFiManagerLibPath}/*.h")

add_library(${wifiManagerLibName} "${_arduino_lib_WiFiManager_source_list}")
target_link_libraries(${wifiManagerLibName} PUBLIC _arduino_lib_DNSServer)
target_include_directories(${wifiManagerLibName} PUBLIC "${DNSServerLibPath}/src")
target_link_arduino_libraries(${wifiManagerLibName} PRIVATE core ${wifiManagerLibDeps})

#message(STATUS "WiFiManagerLibPath: ${WiFiManagerLibPath}")

target_link_libraries(${MAIN_TARGET} PUBLIC _arduino_lib_WiFiManager)
target_include_directories(${MAIN_TARGET} PUBLIC "${WiFiManagerLibPath}")`

There are a other way to import finding and import this header? I tried already to add the DNSServer directly to target_link_arduino_libraries.

a9183756-gh commented 3 years ago

Rather than a hacky workaround, it will be easier if you can share a short script that reproduces the problem, the exact error message and the exact library (github url) that caused the issue.

For reproducing the issue, I tried including ESPAsyncWiFiManager.h (library cloned from https://github.com/alanswx/ESPAsyncWiFiManager), and it required more dependencies ESPAsyncWebServer.h and ESPAsyncTCP.h (cloned from https://github.com/me-no-dev/ESPAsyncWebServer.git and https://github.com/me-no-dev/ESPAsyncTCP.git).

With this, I got the error "DNSServer.h:3:21: fatal error: WiFiUdp.h: No such file or directory".

This error means that DNSServer library could not auto-link with ESP8266WiFi library (Note: WiFiUdp.h is part of ESP8266WiFi). This is because, as discussed for a similar issue in issue 19, auto linking process in the toolchain won't be able to identify WiFiUdp.h as part of ESP8266WiFi library. DNSServer library should have actually included ESP8266WiFi.h, which is the interface file, and not WiFiUdp.h, which is not listed by the library as the interface file.

A simple workaround is to link ESP8266WiFi to DNSServer. I added the below line to the script and it worked.

target_link_arduino_libraries(DNSServer PUBLIC ESP8266WiFi)
Jonas18175 commented 3 years ago

Thank you for your response - sorry for my bad issue request, but I hadn't no idea how I should describe my problem in english... But yes I forgot to Include the compiler output. That seem a easy fix - but when I try this I get an CMake Error: " DNSServer is not a CMake target". Does a fix like this come permanently into the project for things like that? It would be nice if the "ESPLib" is properly supported.

EDIT: It worked I forgot to remove my previous CMake Code.

a9183756-gh commented 3 years ago

Good to hear that it worked for you.

Yes, supporting all the libraries out of the box without such a workaround is something that is in the pipeline. Although it is not a good practice to include a non-interface header file (as done in the DNSServer library), such a scenario is supported by Arduino IDE (unfortunately) and the issue escapes detection. The reason why the toolchain currently does not support this scenario is because it requires hooking into the CMake compilation stage, whereas the current auto-link solution is implemented within the CMake configuration stage itself.

There is a plan to fix this issue permanently in one of the following ways

  1. Hook into the CMake compilation stage and make the auto-link solution compatible with Arduino IDE. (or)
  2. Maintain a database of hints to such issues within the toolchain, so that it is not required to add this workaround in the project script.

Either ways, there will not be a need to remove the above suggested workaround (using target_link_arduino_libraries) from the project script, and this will remain compatible in the future.