Hey everyone, I have a question which is heavily geared towards Cmake. I've done a lot of research on the topic but can't seem to find a solution. My project Structure is as follows:
Proj:
-main(main folder)
-main.cpp/.hpp(file inside main)
-cmakelist.txt(file inside main
-ui(folder inside main)
-ui.c(file inside ui)
-cmakelist.txt(file inside ui)
Currently I have used the add_library() function in Cmake so that main can access all the methods of ui. What i want to do now is do the opposite, so that UI can access all the methods of main. I've made some progress but my main.cpp file has a lot of #includes so I always run into cannot find file/file does not exist when trying to access it from the ui.c.
Thanks in advance!
Cmake issues
Re: Cmake issues
If CMakeLists.txt in ui subdirectory is declaring a library (using "add_library(your-library-name)"), then you can use "target_link_libraries(your-library-name PRIVATE idf::main)" to add a dependency of "ui" on "main".
Note that cyclic dependencies may require setting LINK_INTERFACE_MULTIPLICITY property to let the linker resolve the cyclic references.
Note that cyclic dependencies may require setting LINK_INTERFACE_MULTIPLICITY property to let the linker resolve the cyclic references.
Re: Cmake issues
Thank you Igrr for your response. I believe I have already done that with no luck, maybe I am missing something? I forgot to provide my cmakecode so here it is:
Cmakelist.txt in main
CmakeList.txt inside UI
again, I am very new to Cmake and have been struggling with this issue for about a week. After consulting the documentation, I have not found many resources(if any) that try to accomplish what I am doing. Maybe I am looking in the wrong place
Cmakelist.txt in main
Code: Select all
#add_subdirectory(ui)
idf_component_register(SRCS "main.cpp"
"widgets/tux_panel.c"
"images/dev_bg.c"
#"ui/ui.c"
# Status icons like BLE
"fonts/font_fa_14.c"
# Weather icons like clouds etc
# "fonts/font_fa_weather_32.c"
"fonts/font_fa_weather_42.c"
# "fonts/font_fa_weather_48.c"
# "fonts/font_fa_weather_56.c"
# "fonts/font_fa_weather_64.c"
# Mototype font used in device info
# "fonts/font_robotomono_12.c"
"fonts/font_robotomono_13.c"
# 7Seg font used for time
# "fonts/font_7seg_64.c"
# "fonts/font_7seg_60.c"
# "fonts/font_7seg_58.c"
"fonts/font_7seg_56.c"
INCLUDE_DIRS "." "devices" "helpers" "pages" "widgets" "images" "ui"
REQUIRES json LovyanGFX lvgl fatfs fmt SettingsConfig OpenWeatherMap spi_flash
app_update ota esp_event esp_timer esp_wifi wifi_provisioning spiffs esp_partition
esp_hw_support
)
add_library(main2 ${SOURCES})
#target_include_directories(ui)
add_subdirectory(ui)
#add_library(main SRCS)
target_link_libraries(${COMPONENT_LIB} INTERFACE ui)
spiffs_create_partition_image(storage ${PROJECT_DIR}/fatfs FLASH_IN_PROJECT)
#fatfs_create_spiflash_image(storage ${PROJECT_DIR}/fatfs FLASH_IN_PROJECT PRESERVE_TIME)
Code: Select all
# Add the include directory for the main directory
SET(SOURCES screens/ui_Screen1.c
screens/ui_Screen2.c
screens/ui_Screen3.c
screens/ui_Screen4.c
ui_events.c
ui.c
components/ui_comp_hook.c
ui_helpers.c
images/ui_img_omxlogo_png.c
images/ui_img_om_test_1_img_png.c
images/ui_img_earth_png.c
images/ui_img_frame_png.c)
add_library(ui ${SOURCES})
target_include_directories(ui PUBLIC $[CMAKE_CURRENT_SOURCE_DIR])
#should get the main library(which contains gui.hpp and such)
target_link_libraries(${COMPONENT_LIB} INTERFACE main2)
#target_include_directories(ui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../main")
Re: Cmake issues
I don't have the rest of the project to check if this works, but it should be something along these lines:
There were a couple things which looked odd to me in your version of the code:
1. Calling idf_component_register already defines a CMake library ("idf::main" in this case, since the component name is "main") so you don't need to introduce "main2". Likewise, "ui" should link to "idf::main".
2. Are you intentionally calling target_link_libraries with INTERFACE argument? I don't know how your two libraries (main and ui) use each other's APIs, but most likely you need either "PRIVATE" (if they use the API of another library only in source files) or "PUBLIC" if they also include another library's headers in their own public headers. I have changed to "PRIVATE" in this version, you can change it to "PUBLIC" if needed.
3. target_link_libraries(${COMPONENT_LIB}...) in ui/CMakeLists.txt probably didn't do what you intended, since ${COMPONENT_LIB} was set to "main" from main/CMakeLists.txt file. You can use the library name ("ui") instead, as shown above.
In general, it might be cleaner to move all the UI files into components/ui/ subdirectory of the project, where you can register them as an IDF component (via idf_component_register). Then you can use REQUIRES or PRIV_REQUIRES arguments of idf_component_register to express dependencies between the two libraries.
Code: Select all
idf_component_register(
SRCS "main.cpp"
"widgets/tux_panel.c"
"images/dev_bg.c"
# Status icons like BLE
"fonts/font_fa_14.c"
# Weather icons like clouds etc
"fonts/font_fa_weather_42.c"
# Mototype font used in device info
"fonts/font_robotomono_13.c"
# 7Seg font used for time
"fonts/font_7seg_56.c"
INCLUDE_DIRS "." "devices" "helpers" "pages" "widgets" "images" "ui"
REQUIRES json LovyanGFX lvgl fatfs fmt SettingsConfig OpenWeatherMap spi_flash
app_update ota esp_event esp_timer esp_wifi wifi_provisioning spiffs esp_partition
esp_hw_support
)
add_subdirectory(ui)
target_link_libraries(${COMPONENT_LIB} PRIVATE ui)
spiffs_create_partition_image(storage ${PROJECT_DIR}/fatfs FLASH_IN_PROJECT)
Code: Select all
set(SOURCES screens/ui_Screen1.c
screens/ui_Screen2.c
screens/ui_Screen3.c
screens/ui_Screen4.c
ui_events.c
ui.c
components/ui_comp_hook.c
ui_helpers.c
images/ui_img_omxlogo_png.c
images/ui_img_om_test_1_img_png.c
images/ui_img_earth_png.c
images/ui_img_frame_png.c)
add_library(ui ${SOURCES})
target_include_directories(ui PUBLIC .)
#should get the main library(which contains gui.hpp and such)
target_link_libraries(ui PRIVATE idf::main)
There were a couple things which looked odd to me in your version of the code:
1. Calling idf_component_register already defines a CMake library ("idf::main" in this case, since the component name is "main") so you don't need to introduce "main2". Likewise, "ui" should link to "idf::main".
2. Are you intentionally calling target_link_libraries with INTERFACE argument? I don't know how your two libraries (main and ui) use each other's APIs, but most likely you need either "PRIVATE" (if they use the API of another library only in source files) or "PUBLIC" if they also include another library's headers in their own public headers. I have changed to "PRIVATE" in this version, you can change it to "PUBLIC" if needed.
3. target_link_libraries(${COMPONENT_LIB}...) in ui/CMakeLists.txt probably didn't do what you intended, since ${COMPONENT_LIB} was set to "main" from main/CMakeLists.txt file. You can use the library name ("ui") instead, as shown above.
In general, it might be cleaner to move all the UI files into components/ui/ subdirectory of the project, where you can register them as an IDF component (via idf_component_register). Then you can use REQUIRES or PRIV_REQUIRES arguments of idf_component_register to express dependencies between the two libraries.
Re: Cmake issues
Really appreciate your help. I did not get it working but I will troubleshoot it with the information you have provided me. My ui is from squareline and it displays correctly, but I want a squareline/lvgl slider to work with some code that I already have defined in my main.cpp. Figured it wouldn't be that hard but clearly I was wrong. Thanks again for your help, I will touch back when I have triumphed or failed miserably
Who is online
Users browsing this forum: MicroController and 106 guests