threadx icon indicating copy to clipboard operation
threadx copied to clipboard

CMake project include directories should be "system" ones

Open gdelazzari opened this issue 4 years ago • 9 comments

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.

gdelazzari avatar Sep 22 '21 09:09 gdelazzari

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

ryanwinter avatar Sep 23 '21 05:09 ryanwinter

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.

ryanwinter avatar Sep 23 '21 05:09 ryanwinter

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

ryanwinter avatar Sep 23 '21 05:09 ryanwinter

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

gdelazzari avatar Sep 25 '21 15:09 gdelazzari

@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.

MarkAtBosch avatar May 18 '22 15:05 MarkAtBosch

@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 avatar May 20 '22 22:05 ryanwinter

@ryanwinter @goldscott Any news on this topic? Is there anything I can help with?

MarkAtBosch avatar May 31 '22 13:05 MarkAtBosch

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 avatar Jun 01 '22 14:06 MarkAtBosch

@MarkAtBosch I added @gdelazzari's fix to the common/CMakeLists.txt file and it will be in the next ThreadX release.

goldscott avatar Jun 01 '22 19:06 goldscott

The common/CMakeLists.txt file was updated in 6.1.12: https://github.com/azure-rtos/threadx/blob/master/common/CMakeLists.txt

goldscott avatar Oct 28 '22 15:10 goldscott