From 0a4808b75ca2b8a8836eccd4d5a2069abebd6181 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 31 Oct 2017 09:30:38 -0400 Subject: [PATCH] linker: use UTIL_LISTIFY macro for dealing with .a files Signed-off-by: Anas Nashif --- include/linker/linker-defs.h | 20 +++++- include/misc/util.h | 130 +++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 2 deletions(-) diff --git a/include/linker/linker-defs.h b/include/linker/linker-defs.h index 0d8c860919b..1f28d4f8506 100644 --- a/include/linker/linker-defs.h +++ b/include/linker/linker-defs.h @@ -21,6 +21,7 @@ #include #include +#include /* include platform dependent linker-defs */ #ifdef CONFIG_X86 @@ -102,9 +103,24 @@ __shell_cmd_end = .; #ifdef CONFIG_APPLICATION_MEMORY -#define KERNEL_INPUT_SECTION(sect) libzephyr.a (sect) kernel/lib.a (sect) + +#ifndef NUM_KERNEL_OBJECT_FILES +#error "Expected NUM_KERNEL_OBJECT_FILES to be defined" +#elif NUM_KERNEL_OBJECT_FILES > 19 +#error "Max supported kernel objects is 19." +/* TODO: Using the preprocessor to do this was a mistake. Rewrite to + scale better. e.g. by aggregating the kernel objects into two + archives like KBuild did.*/ +#endif + +#define X(i, j) KERNEL_OBJECT_FILE_##i (j) +#define Y(i, j) *KERNEL_OBJECT_FILE_##i + +#define KERNEL_INPUT_SECTION(sect) \ + UTIL_LISTIFY(NUM_KERNEL_OBJECT_FILES, X, sect) #define APP_INPUT_SECTION(sect) \ - *(EXCLUDE_FILE (*libzephyr.a *kernel/lib.a) sect) + *(EXCLUDE_FILE (UTIL_LISTIFY(NUM_KERNEL_OBJECT_FILES, Y, ~)) sect) + #else #define KERNEL_INPUT_SECTION(sect) *(sect) #define APP_INPUT_SECTION(sect) *(sect) diff --git a/include/misc/util.h b/include/misc/util.h index ac7ad4df589..ba2938687b7 100644 --- a/include/misc/util.h +++ b/include/misc/util.h @@ -172,6 +172,136 @@ static inline s64_t arithmetic_shift_right(s64_t value, u8_t shift) */ #define _IS_ENABLED3(ignore_this, val, ...) val +/** + * Macros for doing code-generation with the preprocessor. + * + * Generally it is better to generate code with the preprocessor than + * to copy-paste code or to generate code with the build system / + * python script's etc. + * + * http://stackoverflow.com/a/12540675 + */ +#define UTIL_EMPTY(...) +#define UTIL_DEFER(...) __VA_ARGS__ UTIL_EMPTY() +#define UTIL_OBSTRUCT(...) __VA_ARGS__ UTIL_DEFER(UTIL_EMPTY)() +#define UTIL_EXPAND(...) __VA_ARGS__ + +#define UTIL_EVAL(...) UTIL_EVAL1(UTIL_EVAL1(UTIL_EVAL1(__VA_ARGS__))) +#define UTIL_EVAL1(...) UTIL_EVAL2(UTIL_EVAL2(UTIL_EVAL2(__VA_ARGS__))) +#define UTIL_EVAL2(...) UTIL_EVAL3(UTIL_EVAL3(UTIL_EVAL3(__VA_ARGS__))) +#define UTIL_EVAL3(...) UTIL_EVAL4(UTIL_EVAL4(UTIL_EVAL4(__VA_ARGS__))) +#define UTIL_EVAL4(...) UTIL_EVAL5(UTIL_EVAL5(UTIL_EVAL5(__VA_ARGS__))) +#define UTIL_EVAL5(...) __VA_ARGS__ + +#define UTIL_CAT(a, ...) UTIL_PRIMITIVE_CAT(a, __VA_ARGS__) +#define UTIL_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__ + +#define UTIL_INC(x) UTIL_PRIMITIVE_CAT(UTIL_INC_, x) +#define UTIL_INC_0 1 +#define UTIL_INC_1 2 +#define UTIL_INC_2 3 +#define UTIL_INC_3 4 +#define UTIL_INC_4 5 +#define UTIL_INC_5 6 +#define UTIL_INC_6 7 +#define UTIL_INC_7 8 +#define UTIL_INC_8 9 +#define UTIL_INC_9 10 +#define UTIL_INC_10 11 +#define UTIL_INC_11 12 +#define UTIL_INC_12 13 +#define UTIL_INC_13 14 +#define UTIL_INC_14 15 +#define UTIL_INC_15 16 +#define UTIL_INC_16 17 +#define UTIL_INC_17 18 +#define UTIL_INC_18 19 +#define UTIL_INC_19 19 + +#define UTIL_DEC(x) UTIL_PRIMITIVE_CAT(UTIL_DEC_, x) +#define UTIL_DEC_0 0 +#define UTIL_DEC_1 0 +#define UTIL_DEC_2 1 +#define UTIL_DEC_3 2 +#define UTIL_DEC_4 3 +#define UTIL_DEC_5 4 +#define UTIL_DEC_6 5 +#define UTIL_DEC_7 6 +#define UTIL_DEC_8 7 +#define UTIL_DEC_9 8 +#define UTIL_DEC_10 9 +#define UTIL_DEC_11 10 +#define UTIL_DEC_12 11 +#define UTIL_DEC_13 12 +#define UTIL_DEC_14 13 +#define UTIL_DEC_15 14 +#define UTIL_DEC_16 15 +#define UTIL_DEC_17 16 +#define UTIL_DEC_18 17 +#define UTIL_DEC_19 18 + +#define UTIL_CHECK_N(x, n, ...) n +#define UTIL_CHECK(...) UTIL_CHECK_N(__VA_ARGS__, 0,) + +#define UTIL_NOT(x) UTIL_CHECK(UTIL_PRIMITIVE_CAT(UTIL_NOT_, x)) +#define UTIL_NOT_0 ~, 1, + +#define UTIL_COMPL(b) UTIL_PRIMITIVE_CAT(UTIL_COMPL_, b) +#define UTIL_COMPL_0 1 +#define UTIL_COMPL_1 0 + +#define UTIL_BOOL(x) UTIL_COMPL(UTIL_NOT(x)) + +#define UTIL_IIF(c) UTIL_PRIMITIVE_CAT(UTIL_IIF_, c) +#define UTIL_IIF_0(t, ...) __VA_ARGS__ +#define UTIL_IIF_1(t, ...) t + +#define UTIL_IF(c) UTIL_IIF(UTIL_BOOL(c)) + +#define UTIL_EAT(...) +#define UTIL_EXPAND(...) __VA_ARGS__ +#define UTIL_WHEN(c) UTIL_IF(c)(UTIL_EXPAND, UTIL_EAT) + +#define UTIL_REPEAT(count, macro, ...) \ + UTIL_WHEN(count) \ + ( \ + UTIL_OBSTRUCT(UTIL_REPEAT_INDIRECT) () \ + ( \ + UTIL_DEC(count), macro, __VA_ARGS__ \ + ) \ + UTIL_OBSTRUCT(macro) \ + ( \ + UTIL_DEC(count), __VA_ARGS__ \ + ) \ + ) +#define UTIL_REPEAT_INDIRECT() UTIL_REPEAT + +/** + * Generates a sequence of code. + * Useful for generating code like; + * + * NRF_PWM0, NRF_PWM1, NRF_PWM2, + * + * @arg LEN: The length of the sequence. Must be defined and less than + * 20. + * + * @arg F(i, F_ARG): A macro function that accepts two arguments. + * F is called repeatedly, the first argument + * is the index in the sequence, and the second argument is the third + * argument given to UTIL_LISTIFY. + * + * Example: + * + * \#define FOO(i, _) NRF_PWM ## i , + * { UTIL_LISTIFY(PWM_COUNT, FOO) } + * // The above two lines will generate the below: + * { NRF_PWM0 , NRF_PWM1 , } + * + * @note Calling UTIL_LISTIFY with undefined arguments has undefined + * behaviour. + */ +#define UTIL_LISTIFY(LEN, F, F_ARG) UTIL_EVAL(UTIL_REPEAT(LEN, F, F_ARG)) + #ifdef __cplusplus } #endif