CMake project include directories should be "system" ones
I'm working on a C++ project where this repository is added as a CMake subdirectory. I have enabled various compiler warnings and made them into errors (-Werror), however this doesn't play well with the fact that the PUBLIC include directories that the threadx CMake project declares are not flagged as SYSTEM. When my C++ source files include tx_api.h, -Werror=old-style-cast triggers all over the place. If the include directories were flagged as system ones, the compiler would be prevented from doing this.
Currently I'm using a workaround on my CMakeLists.txt, which I leave here for reference:
# Include ThreadX after setting the needed configuration variables
set(THREADX_ARCH "cortex_m0")
set(THREADX_TOOLCHAIN "gnu")
set(TX_USER_FILE ${CMAKE_CURRENT_LIST_DIR}/src/tx_user.h)
add_subdirectory(vendor/threadx)
# WORKAROUND: make all the public/interface include directories of the ThreadX submodule
# be considered system include directories. This makes gcc/g++ not emit warnings (which would
# then turn into errors) for all the files inside of them. This is important since the ThreadX include
# files do indeed trigger various warning messages.
get_property(THREADX_INCLUDE_DIRECTORIES TARGET threadx PROPERTY INCLUDE_DIRECTORIES)
set_property(TARGET threadx APPEND PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${THREADX_INCLUDE_DIRECTORIES})
I would like to ask if it is possible to make the public include directories of ThreadX be considered system ones.
Adding the SYSTEM flag to the Common/inc declaration in common/CMakeLists.txt as follows
target_include_directories(${PROJECT_NAME}
SYSTEM
PUBLIC
${CMAKE_CURRENT_LIST_DIR}/inc
)
is enough to solve the issue for me. I guess it might make sense to make the same change to the various ports include folders.
I know this issue can be solved in other ways, for instance with #pragma GCC diagnostic ignored "-Wold-style-cast" before including the file, however I think the proposed change might make sense, assuming it doesn't break anything else.
Thank you for your attention.
Hi @gdelazzari,
Thanks for your detailed issue, I think I can see what is going on here.
Are you adding the -Wold-style-cast to the CMAKE_C_FLAGS CMake property in your toolchain? This warning type is not valid for C files. I'm assuming you are getting an error for each file stating something like:
cc1.exe: warning: command-line option '-Wold-style-cast' is valid for C++/ObjC++ but not for C
Can you try adding this warning type to CMAKE_CXX_FLAGS instead so that it only triggers for c++ files?
Thanks Ryan
Oh I just read this again, and I see that the error is when you are compiling c++ files that then include tx_api.h. Let me investigate further.
Hi @gdelazzari,
Can you paste the error you are seeing when compiling your c++ file? I can't reproduce any errors on my end.
Ryan
Sorry for the late reply.
I see that the error is when you are compiling c++ files that then include tx_api.h
This is indeed the case.
Can you paste the error you are seeing when compiling your c++ file?
Sure, here is some of the output when compiling a file:
In file included from src/main.cpp:11:
src/tx/byte_pool.hpp: In member function 'T* tx::BytePool::allocate(ULONG)':
vendor/threadx/common/inc/tx_api.h:169:49: error: use of old-style cast to 'UINT' {aka 'unsigned int'} [-Werror=old-style-cast]
169 | #define TX_SUCCESS ((UINT) 0x00)
| ^~~~
src/tx/byte_pool.hpp:28:34: note: in expansion of macro 'TX_SUCCESS'
28 | return this->_res != TX_SUCCESS ? nullptr : ptr;
| ^~~~~~~~~~
src/tx/byte_pool.hpp: In member function 'void* tx::BytePool::allocate(ULONG, ULONG)':
vendor/threadx/common/inc/tx_api.h:169:49: error: use of old-style cast to 'UINT' {aka 'unsigned int'} [-Werror=old-style-cast]
169 | #define TX_SUCCESS ((UINT) 0x00)
| ^~~~
src/tx/byte_pool.hpp:37:34: note: in expansion of macro 'TX_SUCCESS'
37 | return this->_res != TX_SUCCESS ? nullptr : ptr;
| ^~~~~~~~~~
src/drivers/can.hpp: At global scope:
vendor/threadx/common/inc/tx_api.h:118:51: error: use of old-style cast to 'ULONG' {aka 'long unsigned int'} [-Werror=old-style-cast]
118 | #define TX_NO_WAIT ((ULONG) 0)
| ^
src/drivers/can.hpp:32:57: note: in expansion of macro 'TX_NO_WAIT'
32 | auto send(const frame_t& frame, ULONG wait_option = TX_NO_WAIT) -> UINT;
| ^~~~~~~~~~
vendor/threadx/common/inc/tx_api.h:119:51: error: use of old-style cast to 'ULONG' {aka 'long unsigned int'} [-Werror=old-style-cast]
119 | #define TX_WAIT_FOREVER ((ULONG) 0xFFFFFFFFUL)
| ^~~~~~~~~~~~
src/drivers/can.hpp:33:53: note: in expansion of macro 'TX_WAIT_FOREVER'
33 | auto receive(frame_t& into, ULONG wait_option = TX_WAIT_FOREVER) -> UINT;
| ^~~~~~~~~~~~~~~
src/tx/event_flags.hpp: In member function 'UINT tx::EventFlags::set(ULONG)':
vendor/threadx/common/inc/tx_api.h:122:51: error: use of old-style cast to 'UINT' {aka 'unsigned int'} [-Werror=old-style-cast]
122 | #define TX_OR ((UINT) 0)
| ^
src/tx/event_flags.hpp:27:61: note: in expansion of macro 'TX_OR'
27 | return tx_event_flags_set(&this->_flags, flags, TX_OR);
| ^~~~~
src/tx/event_flags.hpp: In member function 'UINT tx::EventFlags::clear(ULONG)':
vendor/threadx/common/inc/tx_api.h:120:51: error: use of old-style cast to 'UINT' {aka 'unsigned int'} [-Werror=old-style-cast]
120 | #define TX_AND ((UINT) 2)
| ^
src/tx/event_flags.hpp:32:62: note: in expansion of macro 'TX_AND'
32 | return tx_event_flags_set(&this->_flags, ~flags, TX_AND);
| ^~~~~~
src/main.cpp: In function 'void blinker_thread_entry(uint32_t)':
vendor/threadx/common/inc/tx_api.h:119:51: error: use of old-style cast to 'ULONG' {aka 'long unsigned int'} [-Werror=old-style-cast]
119 | #define TX_WAIT_FOREVER ((ULONG) 0xFFFFFFFFUL)
| ^~~~~~~~~~~~
src/main.cpp:47:54: note: in expansion of macro 'TX_WAIT_FOREVER'
47 | const auto res = spi1.transaction(tx, rx, 5, TX_WAIT_FOREVER);
| ^~~~~~~~~~~~~~~
In file included from src/main.cpp:11:
src/main.cpp: In function 'void tx_application_define(void*)':
vendor/threadx/common/inc/tx_api.h:132:51: error: use of old-style cast to 'UINT' {aka 'unsigned int'} [-Werror=old-style-cast]
132 | #define TX_AUTO_ACTIVATE ((UINT) 1)
| ^
vendor/threadx/common/inc/tx_api.h:1329:96: note: in definition of macro 'tx_timer_create'
1329 | #define tx_timer_create(t,n,e,i,c,r,a) _txe_timer_create((t),(n),(e),(i),(c),(r),(a),(sizeof(TX_TIMER)))
| ^
src/main.cpp:109:81: note: in expansion of macro 'TX_AUTO_ACTIVATE'
109 | tx_timer_create(&hal_tick_timer, nullptr, hal_tick_timer_callback, 0, 1, 1, TX_AUTO_ACTIVATE);
| ^~~~~~~~~~~~~~~~
In file included from src/main.cpp:11:
vendor/threadx/common/inc/tx_api.h:118:51: error: use of old-style cast to 'ULONG' {aka 'long unsigned int'} [-Werror=old-style-cast]
118 | #define TX_NO_WAIT ((ULONG) 0)
| ^
src/main.cpp:112:58: note: in expansion of macro 'TX_NO_WAIT'
112 | void* blinker_thread_stack = heap_pool.allocate(512, TX_NO_WAIT);
| ^~~~~~~~~~
In file included from src/main.cpp:11:
vendor/threadx/common/inc/tx_api.h:129:51: error: use of old-style cast to 'ULONG' {aka 'long unsigned int'} [-Werror=old-style-cast]
129 | #define TX_NO_TIME_SLICE ((ULONG) 0)
| ^
vendor/threadx/common/inc/tx_api.h:1306:105: note: in definition of macro 'tx_thread_create'
1306 | #define tx_thread_create(t,n,e,i,s,l,p,r,c,a) _txe_thread_create((t),(n),(e),(i),(s),(l),(p),(r),(c),(a),(sizeof(TX_THREAD)))
| ^
src/main.cpp:119:9: note: in expansion of macro 'TX_NO_TIME_SLICE'
119 | TX_NO_TIME_SLICE, TX_AUTO_START
| ^~~~~~~~~~~~~~~~
vendor/threadx/common/inc/tx_api.h:130:51: error: use of old-style cast to 'UINT' {aka 'unsigned int'} [-Werror=old-style-cast]
130 | #define TX_AUTO_START ((UINT) 1)
| ^
vendor/threadx/common/inc/tx_api.h:1306:109: note: in definition of macro 'tx_thread_create'
1306 | #define tx_thread_create(t,n,e,i,s,l,p,r,c,a) _txe_thread_create((t),(n),(e),(i),(s),(l),(p),(r),(c),(a),(sizeof(TX_THREAD)))
| ^
src/main.cpp:119:27: note: in expansion of macro 'TX_AUTO_START'
119 | TX_NO_TIME_SLICE, TX_AUTO_START
| ^~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
Sorry for not being more specific before about the errors. Maybe you were not able to reproduce this since, as I have now noticed, the errors arise when using ThreadX's "constants" (like TX_AUTO_START, etc...).
Hope this helps and thanks for looking at this.
Giacomo
@ryanwinter I also ran into this exact problem using latest ThreadX. Can I help with fixing the issue?
The solution proposed by @gdelazzari works great for me. I also think it does not have negative side effects.
@goldscott, the request here is to include the SYSTEM flag for Azure RTOS include directories which would result in CMake converting the includes from a "-I" to a "-i system" for GCC.
As a system header, all warnings are suppressed.
@ryanwinter @goldscott Any news on this topic? Is there anything I can help with?
Here is monkey patch for the user's CMakelists.txt to work around the issue. 🚀
set_target_properties(threadx
PROPERTIES
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/<path to your threadx>/threadx/common/inc"
)
Yet, an official patch would be nice. 🙏
@MarkAtBosch I added @gdelazzari's fix to the common/CMakeLists.txt file and it will be in the next ThreadX release.
The common/CMakeLists.txt file was updated in 6.1.12: https://github.com/azure-rtos/threadx/blob/master/common/CMakeLists.txt