dvidelabs / flatcc

FlatBuffers Compiler and Library in C for C
Apache License 2.0
646 stars 182 forks source link

flatcc generates header files with "alignas" even after recompiling flatcc with FLATCC_PORTABLE #229

Closed jmzorko closed 2 years ago

jmzorko commented 2 years ago

I'm trying to use flatcc in an embedded ARM-based FreeRTOS system. On my Ubuntu host, I created a schema and ran flatcc to generate the header files, but they use "alignas" on certain struct elements. The version of gcc we're using to generate the embedded ARM app does not support this. I tried recompiling flatcc with FLATCC_PORTABLE, and verified that -std=c11 was not being specified, but even after this, flatcc still generates header files with "alignas". Is there a way around this?

mikkelfj commented 2 years ago

Flatcc has been used by other users on FreeRTOS as I recall. The generated code will always use C11 constructs such as alignas. The portable library implements macros to emulate this behaviour on other platforms. To the best of my knowledge GCC has had support of such constructs for a very long time. The use of -std=c11 will largely disable use of use such macros in favor of the real thing, but since some features in C11 are optional, and some are just plain not implemented in glibc for example, even with -std=c11, some portable macros are necessary in most cases.

So, to try solving your problem, you first need to identity what your actual problem is in terms of actual error messages.

It appears that might think the generated code should change when FLATCC_PORTABLE is enabled, and therefore alignas by default is a problem while it might not be a problem at all. If it is a problem, we can see if portable needs to be extended to better support your platform. In that case a test and contribution from your side will be important.

Now, there is an ancient way to not use alignas by padding structs instead and relying in the non-standard pragma pack feature. But it has never ever been necessary and therefore untested and unlikely to be relevant. It can be enabled via a FLATCC config flag for the flatcc compiler itself. It will remove alignas.

mikkelfj commented 2 years ago

I forgot to mention:

https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/portable/pstdalign.h

You can try to 1) read the comments in the header that mentions various problems being solved, and 2) insert #error directives to figures out which alignas implementation you are using.

jmzorko commented 2 years ago

Understood - many thanks for the clarification! I did find that, in a quick test separate from flatcc, the #define for alignas in pstdalign.h (#define alignas(t) attribute((aligned(t)))) worked. I grepped through the flatcc-generated headers to see if that #define was added, but it wasn't. Perhaps it's in a different header. I'll see if I can get this working today.

mikkelfj commented 2 years ago

Macros that support C11, such as alignas, are not generated. They are defined by including certain header files in include/flatcc, and these will typically also include some files from include/flatcc/portable, such as the pstdalign.h I mentioned. This file will detect the current platform and try to define alignas appropriately. As I mentioned, if you insert #error into pstdalign.h, you can get an error message telling you which line was triggered, and thereby see exactly how alignas is defined on your system.

The generated headers will make sure to include the above predefined headers. This mostly happens through https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/flatcc_flatbuffers.h as I recall.

mikkelfj commented 2 years ago

To put this in another way: the generated code is generally portable. The magic of platform detection happens during compilation of the final product when the flatcc headers are included. You should be able to compile the exact same code on another platform with a different compiler with a different level of C standard support.

In a few cases you may have to manually add support for allocation functions if your platform does not support the C stdlib.h library, notably if malloc is not supported.

In your case that could be true because FLATCC_ALLOC macros were added to support FreeRTOS I think:

https://github.com/dvidelabs/flatcc/blob/master/include/flatcc/flatcc_alloc.h

The above file is included so if you change the definitions somewhere in your build system, that will be taken into account. You can also replace flatcc_alloc.h directly. I am not sure this is available in the latest release, but it is on the master branch.

jmzorko commented 2 years ago

Indeed, it all works now. Once I figured out a few things, it works well so far under FreeRTOS. I still need to test a lot more, but so far so good, Many thanks! I think you can close this issue, as it was basically an error in my understanding and not in flatcc itself.