(as reported downstream at https://bugs.gentoo.org/show_bug.cgi?id=455108)
Due to multiple definitions of various enums and structs (MirageDisc, MirageTrack, MirageSector, MirageSession, etc.), libmirage cannot be built with gcc-4.5.
Later gcc-4.6 or later apparently do not treat these multiple definitions as an error.
I am not sure what the best solution would be; on the one hand, multiple definitions are bad style, but on the other hand, explicitly resolving them would result in circular includes in mirage headers, which is also undesirable - e.g. mirage-track.h would have to #include "mirage-sector.h" (for MirageSector), but mirage-sector.h would have to #include "mirage-track.h" (for MirageTrackModes).
[ 1%] Building C object CMakeFiles/filter-cso.dir/src/filters/filter-cso/filter-cso-plugin.c.o /usr/bin/gcc-4.5.4 -DHAVE_CONFIG_H -Dfilter_cso_EXPORTS -DNDEBUG -march=native -O2 -pipe -fPIC -I/var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage -I/var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0_build -I/var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0_build/src/libmirage -std=c99 -Wall -Wextra -Wshadow -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wcast-align -Wno-sign-compare -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -o CMakeFiles/filter-cso.dir/src/filters/filter-cso/filter-cso-plugin.c.o -c /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso-plugin.c In file included from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage.h:35:0, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso.h:29, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso-plugin.c:20: /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-contextual.h:25:28: error: redefinition of typedef ‘MirageDisc’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-context.h:25:28: note: previous declaration of ‘MirageDisc’ was here In file included from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage.h:40:0, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso.h:29, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso-plugin.c:20: /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-disc.h:82:36: error: redefinition of typedef ‘MirageDisc’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-contextual.h:25:28: note: previous declaration of ‘MirageDisc’ was here In file included from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage.h:47:0, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso.h:29, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso-plugin.c:20: /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-parser.h:25:28: error: redefinition of typedef ‘MirageDisc’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-disc.h:82:36: note: previous declaration of ‘MirageDisc’ was here In file included from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage.h:49:0, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso.h:29, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso-plugin.c:20: /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-sector.h:25:29: error: redefinition of typedef ‘MirageTrack’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-disc.h:26:29: note: previous declaration of ‘MirageTrack’ was here /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-sector.h:79:40: error: redefinition of typedef ‘MirageSector’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-disc.h:27:30: note: previous declaration of ‘MirageSector’ was here In file included from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage.h:50:0, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso.h:29, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso-plugin.c:20: /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-session.h:25:29: error: redefinition of typedef ‘MirageTrack’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-sector.h:25:29: note: previous declaration of ‘MirageTrack’ was here /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-session.h:26:32: error: redefinition of typedef ‘MirageLanguage’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-language.h:78:40: note: previous declaration of ‘MirageLanguage’ was here /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-session.h:88:40: error: redefinition of typedef ‘MirageSession’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-disc.h:25:31: note: previous declaration of ‘MirageSession’ was here In file included from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage.h:51:0, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso.h:29, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso-plugin.c:20: /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-track.h:25:32: error: redefinition of typedef ‘MirageFragment’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-fragment.h:74:40: note: previous declaration of ‘MirageFragment’ was here /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-track.h:26:29: error: redefinition of typedef ‘MirageIndex’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-index.h:37:36: note: previous declaration of ‘MirageIndex’ was here /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-track.h:27:32: error: redefinition of typedef ‘MirageLanguage’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-session.h:26:32: note: previous declaration of ‘MirageLanguage’ was here /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-track.h:28:30: error: redefinition of typedef ‘MirageSector’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-sector.h:79:40: note: previous declaration of ‘MirageSector’ was here /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-track.h:77:3: error: redefinition of typedef ‘MirageTrackModes’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-sector.h:26:32: note: previous declaration of ‘MirageTrackModes’ was here /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-track.h:130:36: error: redefinition of typedef ‘MirageTrack’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-session.h:25:29: note: previous declaration of ‘MirageTrack’ was here In file included from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage.h:52:0, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso.h:29, from /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/filters/filter-cso/filter-cso-plugin.c:20: /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-utils.h:25:32: error: redefinition of typedef ‘MirageTrackModes’ /var/tmp/portage/dev-libs/libmirage-2.0.0/work/libmirage-2.0.0/src/libmirage/mirage-track.h:77:3: note: previous declaration of ‘MirageTrackModes’ was here make[2]: *** [CMakeFiles/filter-cso.dir/src/filters/filter-cso/filter-cso-plugin.c.o] Error 1
This issue also pops up when using Clang or gcc-4.4.
I guess the way I'd fix it would be to remove the duplicate typedefs and include the header file with the definition.
The rationale would be that header file guards (#ifdef THIS_H #define THIS_H / content / #endif) would be sufficient to prevent any recusion issues.
But as you point out it's not good coding-style, so perhaps the better fix would be move the offending typedefs either to mirage.h or a new mirage-common.h file (included by mirage.h)?
Second opinion?
If it can be done by removing duplicated tyepedefs and including corresponding headers instead, then I think I would favor that option; however, I think we will run into problem with circular dependencies. Note that before library cleanup, all GObject-derived objects were passed as GObject pointers, so it was less of an issue (at the price of having to recast in the actual code, which I found rather annoying...).
Moving all typedef declarations to mirage.h would be an option, too, even though most projects using GObject seem to manage to keep them in objects' headers. But if it does not break gtk-doc, and if you find it cleaner, I would not mind going this way either.
I did...
I don't know if gtk-doc will be an issue but I guess so. I'll fix it with macro guards around the duplicate definitions. It's a wee bit ugly but it should work nicely.
This issue should be fixed; all the typedefs that had been declared multiple times have been moved to a common header. Tested with gcc 3.4.