When I use clang to build elfutils, I got /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf_begin.c:1054:3: error: function definition is not allowed here { ^ /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf_begin.c:1086:11: warning: implicit declaration of function 'lock_dup_elf' is invalid in C99 [-Wimplicit-function-declaration] retval = lock_dup_elf (); ^ /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf_begin.c:1086:9: warning: incompatible integer to pointer conversion assigning to 'Elf *' (aka 'struct Elf *') from 'int' [-Wint-conversion] retval = lock_dup_elf (); ^ ~~~~~~~~~~~~~~~ /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf_begin.c:1107:13: warning: incompatible integer to pointer conversion assigning to 'Elf *' (aka 'struct Elf *') from 'int' [-Wint-conversion] retval = lock_dup_elf (); ^ ~~~~~~~~~~~~~~~ 3 warnings and 1 error generated. Makefile:934: recipe for target 'elf_begin.os' failed make[2]: *** [elf_begin.os] Error 1 make[2]: *** Waiting for unfinished jobs.... /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf_getarsym.c:205:15: error: fields must have a constant size: 'variable length array in structure' extension will never be supported uint32_t u32[n]; ^ /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf_getarsym.c:206:15: error: fields must have a constant size: 'variable length array in structure' extension will never be supported uint64_t u64[n]; ^ 2 errors generated. Makefile:934: recipe for target 'elf_getarsym.os' failed make[2]: *** [elf_getarsym.os] Error 1 In file included from /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf64_updatefile.c:30: /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf32_updatefile.c:297:4: error: function definition is not allowed here { ^ /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf32_updatefile.c:331:7: warning: implicit declaration of function 'fill_mmap' is invalid in C99 [-Wimplicit-function-declaration] fill_mmap (dl->data.d.d_off); ^ /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf32_updatefile.c:297:4: error: function definition is not allowed here { ^ /build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161/libelf/elf32_updatefile.c:331:7: warning: implicit declaration of function 'fill_mmap' is invalid in C99 [-Wimplicit-function-declaration] fill_mmap (dl->data.d.d_off); ^ 1 warning and 1 error generated. Makefile:934: recipe for target 'elf64_updatefile.os' failed make[2]: *** [elf64_updatefile.os] Error 1 1 warning and 1 error generated. Makefile:934: recipe for target 'elf32_updatefile.os' failed make[2]: *** [elf32_updatefile.os] Error 1 make[2]: Leaving directory '/build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161-.amd64/libelf' Makefile:464: recipe for target 'all-recursive' failed make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory '/build/falco/tmp/portage/dev-libs/elfutils-0.161/work/elfutils-0.161-.amd64' Makefile:379: recipe for target 'all' failed make: *** [all] Error 2
Use a compiler that supports the GNU extensions used by the package then. elfutils uses GNU nested functions as well as variable length structures, that clang folks didn't bother to implement.
You mean flexible array members? That's C99, not even GNU extension. I'm somewhat surprised they are not supported. Other than that, I don't think it's unreasonable to ask that elfutils sticks to standard language. But if there are other (standard) features that we use anyway that clang doesn't support, why bother.
Yeah, that is nasty. Apparently clang claims to support -std=gnu99, which we explicitly check with a configure check, but doesn't actually implement all language extensions, producing these cryptic error messages. I proposed a patch upstream to some extra added explicit checks for some of the language extensions I know the code is using (Mixed Declarations and Code https://gcc.gnu.org/onlinedocs/gcc/Mixed-Declarations.html Nested Functions https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html Arrays of Variable Length https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html) to hopefully catch versions of clang which don't support them early. https://lists.fedorahosted.org/pipermail/elfutils-devel/2015-April/004723.html Could you see if that catches the issue for you? As soon as clang implements those extensions I think the configure check should pass and everything should build fine. BTW. I wouldn't mind alternatives that make the code also compile with clang versions that don't implement all these extensions. As long as the code isn't too ugly and the whole code base builds and the testsuite still PASSes. But apparently that is hard because nobody managed to come up with such a patch (some patches were posted in the past, but they all were incomplete and the resulting binaries just didn't work correctly).
commit aba6d762ed1f3a9c318ebee20cd08bcd069a3f75 Author: Mark Wielaard <mjw> Date: Tue Apr 14 10:18:37 2015 +0200 configure: Add explicit checks for all GNU99 extensions used. Some compilers (clang) claim to support -std=gnu99 but don't actually implement all extensions we use in the code. Producing really hard to parse errors. Add explicit checks for some of the other language extensions we use, Nested Functions and Arrays of Variable Length, to the configure check to catch such issues early. https://bugzilla.redhat.com/show_bug.cgi?id=1211357 Signed-off-by: Mark Wielaard <mjw>
I have a patch to compile elfutls with clang/llvm and it passed all elfutils uni t tests. My tests were on x86 host. My goal is to make elfutils run on Android w ith clang compiler. I have not contribute to elfutils before. Could someone help or show me how to make this patch into elfutils? The patch contains mainly three kinds of changes: (1) Add simple type casts or declarations because clang gives more warnings than gcc. This should not change output code. (2) Change some on-stack variable length arrays to fixed length with dynamic all oca or malloc. I saw a few changes like this already made into the last two vers ions of elfutls. I used similar patterns to get all compiled with clang. (3) Nested functions are conditionally changed to clang "Blocks" (closures). Please see spec at http://clang.llvm.org/docs/BlockLanguageSpec.html. This should not change output code from gcc. The change pattern is simple enough to verify and merge like this: +#include "nested_func.h" /* get macros __BLOCK and NESTED_FUNC */ { // body of the enclosing function - int nbkpts = 0; + __BLOCK int nbkpts = 0; - int add_bkpt (Dwarf_Addr pc) + NESTED_FUNC(int, add_bkpt, (Dwarf_Addr), (Dwarf_Addr pc)) { // body of the nested function, can update nbkpts - } + };
Patches should be sent to the mailing list elfutils-devel-at-lists.fedorahosted.org.
(In reply to Chih-Hung Hsieh from comment #5) > I have a patch to compile elfutls with clang/llvm and it passed all elfutils > unit tests. Very nice. > My tests were on x86 host. My goal is to make elfutils run on > Android w > ith clang compiler. > > I have not contribute to elfutils before. > Could someone help or show me how to make this patch into elfutils? Please see: https://git.fedorahosted.org/cgit/elfutils.git/plain/CONTRIBUTING > The patch contains mainly three kinds of changes: It is probably best to split the patch up in at least 3 parts in that case. Then they can be reviewed and tested independently. > (1) Add simple type casts or declarations because clang gives more warnings > than > gcc. This should not change output code. That should be fine. Ideally we add any warning flags needed for gcc to give similar warnings so such issues don't creep back in. > (2) Change some on-stack variable length arrays to fixed length with dynamic > all > oca or malloc. I saw a few changes like this already made into the last two > vers > ions of elfutls. I used similar patterns to get all compiled with clang. Some of those on-stack variable length arrays could cause unbounded stack usage. So it is often good to fix them. > (3) Nested functions are conditionally changed to clang "Blocks" (closures). > Please see spec at http://clang.llvm.org/docs/BlockLanguageSpec.html. > This should not change output code from gcc. > The change pattern is simple enough to verify and merge like this: > > +#include "nested_func.h" /* get macros __BLOCK and NESTED_FUNC */ > > { // body of the enclosing function > - int nbkpts = 0; > + __BLOCK int nbkpts = 0; > > - int add_bkpt (Dwarf_Addr pc) > + NESTED_FUNC(int, add_bkpt, (Dwarf_Addr), (Dwarf_Addr pc)) > { > // body of the nested function, can update nbkpts > - } > + }; I must say that I don't think this improves readability of the code. But please do post on the list and we can discuss if there is a way to make it look a bit nicer.
Thanks for the suggestions. I have started sending patches to the list. The first few will be simpler changes and only the last one will change the config files to enable clang compiler.