/** * @file headers.c * @brief Checks that a public header can be the first thing a caller includes. * * The assertion here is the compile, not anything main() does. `akgl/controller.h` * declares its binding handlers as taking an `akgl_Actor *` and once did not * declare that type, so every translation unit that reached for it before * `akgl/actor.h` failed with "unknown type name 'akgl_Actor'". `src/controller.c` * never noticed, because it includes `akgl/game.h` first. * * One header per file, deliberately. A second `#include` after the first proves * nothing about the second: by then the first has already dragged its * dependencies in. So every other public header gets its own generated * translation unit -- `CMakeLists.txt` writes one per entry in * `AKGL_PUBLIC_HEADERS` and links them all into this program. That list also * drives `install()`, so a header that ships is a header that is checked. * * This file stays hand-written because it asserts something the generated ones * cannot: that `akgl_Actor` is *complete* here rather than merely declared. */ #include #include int main(void) { akgl_Control control; // Enough to require the akgl_Actor declaration to be complete rather than // merely present: the handler signature names it, and a control map holds // one by value. memset(&control, 0x00, sizeof(akgl_Control)); control.key = SDLK_LEFT; control.handler_on = &akgl_actor_cmhf_left_on; if ( control.handler_on == NULL ) { return 1; } if ( sizeof(akgl_controlmaps) != (sizeof(akgl_ControlMap) * AKGL_MAX_CONTROL_MAPS) ) { return 1; } return 0; }