1# CMake fragment for MicroPython rules
2
3set(MICROPY_GENHDR_DIR "${CMAKE_BINARY_DIR}/genhdr")
4set(MICROPY_MPVERSION "${MICROPY_GENHDR_DIR}/mpversion.h")
5set(MICROPY_MODULEDEFS "${MICROPY_GENHDR_DIR}/moduledefs.h")
6set(MICROPY_QSTRDEFS_PY "${MICROPY_PY_DIR}/qstrdefs.h")
7set(MICROPY_QSTRDEFS_LAST "${MICROPY_GENHDR_DIR}/qstr.i.last")
8set(MICROPY_QSTRDEFS_SPLIT "${MICROPY_GENHDR_DIR}/qstr.split")
9set(MICROPY_QSTRDEFS_COLLECTED "${MICROPY_GENHDR_DIR}/qstrdefs.collected.h")
10set(MICROPY_QSTRDEFS_PREPROCESSED "${MICROPY_GENHDR_DIR}/qstrdefs.preprocessed.h")
11set(MICROPY_QSTRDEFS_GENERATED "${MICROPY_GENHDR_DIR}/qstrdefs.generated.h")
12
13# Provide defaults for preprocessor flags if not already defined
14if(NOT MICROPY_CPP_FLAGS)
15    get_target_property(MICROPY_CPP_INC ${MICROPY_TARGET} INCLUDE_DIRECTORIES)
16    get_target_property(MICROPY_CPP_DEF ${MICROPY_TARGET} COMPILE_DEFINITIONS)
17endif()
18
19# Compute MICROPY_CPP_FLAGS for preprocessor
20list(APPEND MICROPY_CPP_INC ${MICROPY_CPP_INC_EXTRA})
21list(APPEND MICROPY_CPP_DEF ${MICROPY_CPP_DEF_EXTRA})
22set(_prefix "-I")
23foreach(_arg ${MICROPY_CPP_INC})
24    list(APPEND MICROPY_CPP_FLAGS ${_prefix}${_arg})
25endforeach()
26set(_prefix "-D")
27foreach(_arg ${MICROPY_CPP_DEF})
28    list(APPEND MICROPY_CPP_FLAGS ${_prefix}${_arg})
29endforeach()
30list(APPEND MICROPY_CPP_FLAGS ${MICROPY_CPP_FLAGS_EXTRA})
31
32find_package(Python3 REQUIRED COMPONENTS Interpreter)
33
34target_sources(${MICROPY_TARGET} PRIVATE
35    ${MICROPY_MPVERSION}
36    ${MICROPY_QSTRDEFS_GENERATED}
37)
38
39# Command to force the build of another command
40
41add_custom_command(
42    OUTPUT MICROPY_FORCE_BUILD
43    COMMENT ""
44    COMMAND echo -n
45)
46
47# Generate mpversion.h
48
49add_custom_command(
50    OUTPUT ${MICROPY_MPVERSION}
51    COMMAND ${CMAKE_COMMAND} -E make_directory ${MICROPY_GENHDR_DIR}
52    COMMAND ${Python3_EXECUTABLE} ${MICROPY_DIR}/py/makeversionhdr.py ${MICROPY_MPVERSION}
53    DEPENDS MICROPY_FORCE_BUILD
54)
55
56# Generate moduledefs.h
57
58add_custom_command(
59    OUTPUT ${MICROPY_MODULEDEFS}
60    COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makemoduledefs.py --vpath="/" ${MICROPY_SOURCE_QSTR} > ${MICROPY_MODULEDEFS}
61    DEPENDS ${MICROPY_MPVERSION}
62        ${MICROPY_SOURCE_QSTR}
63)
64
65# Generate qstrs
66
67# If any of the dependencies in this rule change then the C-preprocessor step must be run.
68# It only needs to be passed the list of MICROPY_SOURCE_QSTR files that have changed since
69# it was last run, but it looks like it's not possible to specify that with cmake.
70add_custom_command(
71    OUTPUT ${MICROPY_QSTRDEFS_LAST}
72    COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py pp ${CMAKE_C_COMPILER} -E output ${MICROPY_GENHDR_DIR}/qstr.i.last cflags ${MICROPY_CPP_FLAGS} -DNO_QSTR cxxflags ${MICROPY_CPP_FLAGS} -DNO_QSTR sources ${MICROPY_SOURCE_QSTR}
73    DEPENDS ${MICROPY_MODULEDEFS}
74        ${MICROPY_SOURCE_QSTR}
75    VERBATIM
76    COMMAND_EXPAND_LISTS
77)
78
79add_custom_command(
80    OUTPUT ${MICROPY_QSTRDEFS_SPLIT}
81    COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py split qstr ${MICROPY_GENHDR_DIR}/qstr.i.last ${MICROPY_GENHDR_DIR}/qstr _
82    COMMAND touch ${MICROPY_QSTRDEFS_SPLIT}
83    DEPENDS ${MICROPY_QSTRDEFS_LAST}
84    VERBATIM
85    COMMAND_EXPAND_LISTS
86)
87
88add_custom_command(
89    OUTPUT ${MICROPY_QSTRDEFS_COLLECTED}
90    COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py cat qstr _ ${MICROPY_GENHDR_DIR}/qstr ${MICROPY_QSTRDEFS_COLLECTED}
91    DEPENDS ${MICROPY_QSTRDEFS_SPLIT}
92    VERBATIM
93    COMMAND_EXPAND_LISTS
94)
95
96add_custom_command(
97    OUTPUT ${MICROPY_QSTRDEFS_PREPROCESSED}
98    COMMAND cat ${MICROPY_QSTRDEFS_PY} ${MICROPY_QSTRDEFS_PORT} ${MICROPY_QSTRDEFS_COLLECTED} | sed "s/^Q(.*)/\"&\"/" | ${CMAKE_C_COMPILER} -E ${MICROPY_CPP_FLAGS} - | sed "s/^\\\"\\(Q(.*)\\)\\\"/\\1/" > ${MICROPY_QSTRDEFS_PREPROCESSED}
99    DEPENDS ${MICROPY_QSTRDEFS_PY}
100        ${MICROPY_QSTRDEFS_PORT}
101        ${MICROPY_QSTRDEFS_COLLECTED}
102    VERBATIM
103    COMMAND_EXPAND_LISTS
104)
105
106add_custom_command(
107    OUTPUT ${MICROPY_QSTRDEFS_GENERATED}
108    COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdata.py ${MICROPY_QSTRDEFS_PREPROCESSED} > ${MICROPY_QSTRDEFS_GENERATED}
109    DEPENDS ${MICROPY_QSTRDEFS_PREPROCESSED}
110    VERBATIM
111    COMMAND_EXPAND_LISTS
112)
113
114# Build frozen code if enabled
115
116if(MICROPY_FROZEN_MANIFEST)
117    set(MICROPY_FROZEN_CONTENT "${CMAKE_BINARY_DIR}/frozen_content.c")
118
119    target_sources(${MICROPY_TARGET} PRIVATE
120        ${MICROPY_FROZEN_CONTENT}
121    )
122
123    target_compile_definitions(${MICROPY_TARGET} PUBLIC
124        MICROPY_QSTR_EXTRA_POOL=mp_qstr_frozen_const_pool
125        MICROPY_MODULE_FROZEN_MPY=\(1\)
126    )
127
128    if(NOT MICROPY_LIB_DIR)
129        set(MICROPY_LIB_DIR ${MICROPY_DIR}/../micropython-lib)
130    endif()
131
132    # If MICROPY_MPYCROSS is not explicitly defined in the environment (which
133    # is what makemanifest.py will use) then create an mpy-cross dependency
134    # to automatically build mpy-cross if needed.
135    set(MICROPY_MPYCROSS $ENV{MICROPY_MPYCROSS})
136    if(NOT MICROPY_MPYCROSS)
137        set(MICROPY_MPYCROSS_DEPENDENCY ${MICROPY_DIR}/mpy-cross/mpy-cross)
138        if(NOT MICROPY_MAKE_EXECUTABLE)
139            set(MICROPY_MAKE_EXECUTABLE make)
140        endif()
141        add_custom_command(
142            OUTPUT ${MICROPY_MPYCROSS_DEPENDENCY}
143            COMMAND ${MICROPY_MAKE_EXECUTABLE} -C ${MICROPY_DIR}/mpy-cross
144        )
145    endif()
146
147    add_custom_command(
148        OUTPUT ${MICROPY_FROZEN_CONTENT}
149        COMMAND ${Python3_EXECUTABLE} ${MICROPY_DIR}/tools/makemanifest.py -o ${MICROPY_FROZEN_CONTENT} -v "MPY_DIR=${MICROPY_DIR}" -v "MPY_LIB_DIR=${MICROPY_LIB_DIR}" -v "PORT_DIR=${MICROPY_PORT_DIR}" -v "BOARD_DIR=${MICROPY_BOARD_DIR}" -b "${CMAKE_BINARY_DIR}" -f${MICROPY_CROSS_FLAGS} ${MICROPY_FROZEN_MANIFEST}
150        DEPENDS MICROPY_FORCE_BUILD
151            ${MICROPY_QSTRDEFS_GENERATED}
152            ${MICROPY_MPYCROSS_DEPENDENCY}
153        VERBATIM
154    )
155endif()
156