You don't explain what the library is doing. It may be the case that your library doesn't need to see/know about the DAC_Handle, all it needs is to know the size of the containing struct. You might consider passing that in as a parameter, or storing it in an extern size_t global variable, or something. (If all you do is memset(0) the struct for initialization, you don't need to know the individual members, right?)
Or, maybe the library needs to know about the DAC_Handle if it's present, and call some routines, but you can control it with a "flags" mask in the struct: create an enum or some #define bit flags for things like HAS_DAC_HANDLE, and use bitwise-or to combine them into a runtime flags field:
Code:
struct {
bool has_dac :1;
bool has_mmu: 1;
bool has_spqr: 1;
bool init_done: 1;
};
Then you can check for the field(s) at runtime in your library, and call the appropriate functions as needed. This is runtime, not compile-time, so it's less efficient. But if you need to compile your library with everything built in, and then pick and choose features at link time or run time, this is a simple way to make it work.
Or, maybe you change the structure of your include files, so the library #include's the DAC features and "provides" them to the application. So when your main.c file does #include "mylibrary.h" it either gets/doesn't get the DAC features based on a #define you put above it:
Code:
// main.c
#define USE_DAC 1
#include "mylibrary.h"
// struct now includes DAC_Handle