Wednesday, April 20, 2011

How to automatically generate C header file using CMake?

I'm looking for a way to automatically generate a header file. This file is the public interface of a library and i want to "fill" some structures and stuff before compilation.

For example, in the private header I have a structure with useful fields :

typedef struct mystuff_attr_t {
  int                      _detachstate;
  mystuff_scope_t          _scope;
  cpu_set_t                _cpuset;
  size_t                   _stacksize;
  void*                    _stackaddr;
} mystuff_attr_t;

And I would like to have this structure in the public header without the fields but with the same size (currently done manually) this way :

typedef struct mystuff_attr_t {
  char _opaque[ 20 ]; 
} mystuff_attr_t;

I would like to have this automatically generated by CMake when creating the build system in order to avoid bad size struct in public interface when I change the struct in private header.

From stackoverflow
  • I would write an exe that creates the header.

    for example:

    #include <stdio.h>
    
    #define PUBLIC(TYPE) \
    printf( "typedef struct %s { char _opaque[ %d ]; } %s;\n", #TYPE, sizeof(TYPE), #TYPE )
    
    int main()
      {
      // start header stuff
    
      PUBLIC(mystuff_attr_t);
    
      // end header stuff
      }
    
    claferri : I already thought of that but I was wondering if a tool like cmake had some usefull module to help me doing this. By the way, I would rather write a shell script instead of an exe as long as it's for unix platforms.
    David Allan Finch : Thanks. The advantage of using a bin is that you can get the compiler to work out the sizes for you. Using a script you will need to do it yourself and you might get it wrong.
    claferri : That's right, gonna think about it!
  • In fact, CMake allow you to generate files (using configure_file (file.h.in file.h) ) and also to check a type size (using check_type_size ("type" header.h)) so it's easy to combine those two to have a proper public header. Here is the piece of code I use in CMakeList.txt :

    # Where to search for types :
    set (CMAKE_EXTRA_INCLUDE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/private_type.h)
    
    # Type1 :
    check_type_size ("type1_t" MY_SIZEOF_TYPE1_T)
    
    # Generate public header :
    configure_file (${CMAKE_CURRENT_SOURCE_DIR}/pub_type.h.in ${CMAKE_CURRENT_BINARY_DIR}/pub_type.h)
    
    # Need to set this back to nothing :
    set (CMAKE_EXTRA_INCLUDE_FILES)
    

    And in the public header pub_type.h.in :

    #define MY_SIZEOF_TYPE1_T ${MY_SIZEOF_TYPE1_T}
    

    This works pretty good :)

  • The Makeheaders tool (manual).

0 comments:

Post a Comment