Fallback header file for configuration of module Topic is solved

If you have a simple question and just want an answer.
DemoniacMilk
XCore Addict
Posts: 191
Joined: Tue Jul 05, 2016 2:19 pm

Fallback header file for configuration of module

Post by DemoniacMilk »

Some modules (e.g. lib_ethernet) allow the user to create a config header file (e.g. ethernet_conf.h). If this file exists, it will be included. If not, a header file providing default/fallback definitions/values is included.

I would like to use a similar setup, providing a default config header file in a module but allow the user to add a modified header file to a project. If the modified file exists, it should be included before the fallback/default.

custom/user header example (shortened):

Code: Select all

#ifndef __has_error_conf_h__
#define __has_error_conf_h__
#endif

#ifndef ERROR_CONF_H_
#define ERROR_CONF_H_

// List of task ids
enum {
    TASK_1,
    TASK_2,        
    ERR_NUM_TASK_ID  /* keep this as the last element! */
};

// task names
static char *taskNames[] = {
    "task 1",
    "task 2",
    "unknown task"
};

/* more definitions */

#endif /* ERROR_CONF_H_ */
the fallback file has the following structure (enums / arrays ignored if __has_error_conf_h__ is defined, shortened).

Code: Select all

#ifndef ERROR_CONF_EXAMPLE_H_
#define ERROR_CONF_EXAMPLE_H_

#ifdef __has_error_conf_h__
#include "error_conf.h"
#else
    enum {
        TASK_ID0,
        ERR_NUM_TASK_ID  /* keep this as the last element! */
    };

    static char *taskNames[] = {
        "Vogon Constructor",
        "unknown task ID"
    };
#endif

/* default definitions here, #ifndef guarded */

#endif /* ERROR_CONF_EXAMPLE_H_ */
however, with this structure, the default files content is used all the time while im not getting warnings/errors. Maybe there is a build option I have to set, as for now, __has_error_conf_h__ is defined within error_conf.h, that is only included, if __has_error_conf_h__ is defined . So basically the file needs to be included already to to be included. How could I solve this? Does the compiler create a define itsself, if a file exists?


View Solution
User avatar
larry
Respected Member
Posts: 275
Joined: Fri Mar 12, 2010 6:03 pm

Post by larry »

As long as your default header file has a different name than the user header file, e.g. error_conf_default.h, you should be able to use:

Code: Select all

#ifdef __error_conf_h_exists__
DemoniacMilk
XCore Addict
Posts: 191
Joined: Tue Jul 05, 2016 2:19 pm

Post by DemoniacMilk »

Hm, I was able to find something similar in other modules and tried to use what you described, but could not get it to work somehow.

In the source files, only error.h is included. It includes errror_conf_default.h. The first thing done in error_conf_default.h is

Code: Select all

#if __error_conf_h_exists__
#include <error_conf.h>
#else
#warning "error_conf.h not found"
#endif
what generates the warning
"error_conf.h not found" error_conf_default.h /lib_errorLog/src line 15 C/C++ Problem
The file error_conf.h exists in folder project/src/.

I have found something similar done in lib_webserver and it works well (although fallback values are #ifndef #define'd in a source file, not a header file, and the _conf.h file is included in both the source and the main header file). Do I need to make sure error_conf.h is found/processed before error_conf_default.h, otherwise __error_conf_h_exists__ may not be defined at the time it is to be included?
henk
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

Does it matter that you use #if instead of #ifdef?
DemoniacMilk
XCore Addict
Posts: 191
Joined: Tue Jul 05, 2016 2:19 pm

Post by DemoniacMilk »

unfortunately no. Haveing the default header in project/ or project/src/ does not matter either. I tried a clean build.

If you are interested, I can send the library and a test application.
User avatar
larry
Respected Member
Posts: 275
Joined: Fri Mar 12, 2010 6:03 pm

Post by larry »

Sorry I forgot to add that you also need:

Code: Select all

OPTIONAL_HEADERS = error_conf.h
The complete example is:

Code: Select all

==> error_conf.h <==
#define X 2

==> error_conf_default.h <==
#ifdef __error_conf_h_exists__
#include "error_conf.h"
#else
#define X 1
#endif

==> main.xc <==
#include <stdio.h>
#include "error_conf_default.h"
int main(void)
{
  printf("%d\n", X);
  return 0;
}

==> makefile <==
XCC_FLAGS =
OPTIONAL_HEADERS = error_conf.h
TARGET = XCORE-200-EXPLORER
-include $(XMOS_MAKE_PATH)/xcommon/module_xcommon/build/Makefile.common
The exists macro is a feature of the XMOS common makefiles. You can see how it works if you follow OPTIONAL_HEADER_FLAGS in Makefile.common1.

The lib_logging and lib_xassert libraries use this feature too and you can see there how it's used too.
DemoniacMilk
XCore Addict
Posts: 191
Joined: Tue Jul 05, 2016 2:19 pm

Post by DemoniacMilk »

Brilliant, that was the missing piece in the puzzle.

Thanks a lot!