1cmake_minimum_required(VERSION 3.5)
2
3include(${IDF_PATH}/tools/cmake/utilities.cmake)
4project(${ULP_APP_NAME} ASM C)
5
6option(ULP_COCPU_IS_RISCV "Use RISC-V based ULP" OFF)
7
8set(version_pattern "[a-z0-9\.-]+")
9
10# Check assembler version
11execute_process(
12    COMMAND ${CMAKE_ASM_COMPILER} --version
13    OUTPUT_VARIABLE as_output
14    ERROR_QUIET)
15
16string(REGEX MATCH "\\(GNU Binutils\\) (${version_pattern})" as_version ${as_output})
17set(as_version ${CMAKE_MATCH_1})
18
19
20message(STATUS "Building ULP app ${ULP_APP_NAME}")
21
22if(ULP_COCPU_IS_RISCV)
23    set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/esp32s2.ulp.riscv.ld)
24else()
25    message(STATUS "ULP assembler version: ${as_version}")
26
27    # Check the supported assembler version
28    file(STRINGS ${IDF_PATH}/components/ulp/toolchain_ulp_version.mk version_file_contents)
29    string(REGEX MATCH
30        "SUPPORTED_ULP_ASSEMBLER_VERSION = (${version_pattern})"
31        as_supported_version
32        ${version_file_contents})
33    set(as_supported_version ${CMAKE_MATCH_1})
34
35    if(NOT as_version STREQUAL as_supported_version)
36        message(WARNING "WARNING: ULP assembler version ${as_version} is not supported. Expected to see version: \
37                        ${as_supported_version}. Please check ESP-IDF ULP setup instructions and update \
38                        the toolchain, or proceed at your own risk.")
39    endif()
40
41    set(ULP_LD_TEMPLATE ${IDF_PATH}/components/ulp/ld/esp32.ulp.ld)
42endif()
43
44
45set(ULP_MAP_GEN ${PYTHON} ${IDF_PATH}/components/ulp/esp32ulp_mapgen.py)
46get_filename_component(sdkconfig_dir ${SDKCONFIG_HEADER} DIRECTORY)
47
48foreach(include ${COMPONENT_INCLUDES})
49    list(APPEND component_includes -I${include})
50endforeach()
51
52list(APPEND ULP_PREPROCESSOR_ARGS ${component_includes})
53list(APPEND ULP_PREPROCESSOR_ARGS -I${COMPONENT_DIR})
54list(APPEND ULP_PREPROCESSOR_ARGS -I${sdkconfig_dir})
55
56include_directories(${COMPONENT_INCLUDES})
57
58list(APPEND ULP_PREPROCESSOR_ARGS -D__ASSEMBLER__)
59
60# Preprocess linker script, pre-linking
61get_filename_component(ULP_LD_SCRIPT ${ULP_LD_TEMPLATE} NAME)
62add_custom_command(OUTPUT ${ULP_LD_SCRIPT}
63                   COMMAND ${CMAKE_C_COMPILER} -E -P -xc -o ${ULP_LD_SCRIPT} ${ULP_PREPROCESSOR_ARGS} ${ULP_LD_TEMPLATE}
64                   WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
65                   DEPENDS ${ULP_LD_TEMPLATE} ${SDKCONFIG_HEADER}
66                   VERBATIM)
67add_custom_target(${ULP_APP_NAME}_ld_script
68                  DEPENDS ${ULP_LD_SCRIPT}
69                  WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
70
71if(ULP_COCPU_IS_RISCV)
72    #risc-v ulp uses extra files for building:
73    list(APPEND ULP_S_SOURCES
74        "${IDF_PATH}/components/ulp/ulp_riscv/start.S"
75        "${IDF_PATH}/components/ulp/ulp_riscv/ulp_riscv_utils.c")
76
77    #dummy loop to force pre-processed linker file generation:
78    foreach(ulp_s_source ${ULP_S_SOURCES})
79        set(noop ${ulp_s_source})
80
81        add_custom_command(OUTPUT ${noop}
82            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
83            COMMAND cmake -E echo
84            DEPENDS ${ULP_LD_SCRIPT}
85            )
86
87        set_source_files_properties(${noop} PROPERTIES NOOP_PROPERTY ${ULP_LD_SCRIPT})
88    endforeach()
89
90    #creates the executable:
91    add_executable(${ULP_APP_NAME} ${ULP_S_SOURCES})
92    set(DUMP_SYMBOL_ARGS -g)
93    set(MAP_GEN_EXTRA_ARGS --riscv)
94    set(EXTRA_LINKER_ARGS "-nostartfiles")
95    list(APPEND EXTRA_LINKER_ARGS "-Wl,--gc-sections")
96    list(APPEND EXTRA_LINKER_ARGS "-Wl,-Map=\"${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.map\"")
97    #Makes the csr utillies for riscv visible:
98    target_include_directories(${ULP_APP_NAME} PRIVATE "${IDF_PATH}/components/ulp/ulp_riscv/include")
99
100else()
101
102    foreach(ulp_s_source ${ULP_S_SOURCES})
103        get_filename_component(ulp_ps_source ${ulp_s_source} NAME_WE)
104        set(ulp_ps_output ${CMAKE_CURRENT_BINARY_DIR}/${ulp_ps_source}.ulp.S)
105        # Generate preprocessed assembly files.
106        add_custom_command(OUTPUT ${ulp_ps_output}
107                           WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
108                           COMMAND ${CMAKE_C_COMPILER} -E -P -xc ${ULP_PREPROCESSOR_ARGS}
109                           -o ${ulp_ps_output} ${ulp_s_source}
110                           DEPENDS ${ulp_s_source} ${ULP_LD_SCRIPT}
111                           VERBATIM)
112        # During assembly file compilation, output listing files as well.
113        set_source_files_properties(${ulp_ps_output}
114                                    PROPERTIES COMPILE_FLAGS
115                                    "-al=${CMAKE_CURRENT_BINARY_DIR}/${ulp_ps_source}.lst")
116        list(APPEND ULP_PS_SOURCES ${ulp_ps_output})
117    endforeach()
118
119    # Create an executable
120    add_executable(${ULP_APP_NAME} ${ULP_PS_SOURCES})
121    set(DUMP_SYMBOL_ARGS -g -f posix)
122    set(MAP_GEN_EXTRA_ARGS .)
123    set(EXTRA_LINKER_ARGS "-Map=\"${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.map\"")
124
125endif()
126
127# Dump the list of global symbols in a convenient format
128add_custom_command(OUTPUT ${ULP_APP_NAME}.sym
129                   COMMAND ${CMAKE_NM} ${DUMP_SYMBOL_ARGS} $<TARGET_FILE:${ULP_APP_NAME}> > ${ULP_APP_NAME}.sym
130                   DEPENDS ${ULP_APP_NAME}
131                   WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
132
133# Dump the binary for inclusion into the project
134add_custom_command(OUTPUT ${ULP_APP_NAME}.bin
135                   COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:${ULP_APP_NAME}> ${ULP_APP_NAME}.bin
136                   DEPENDS ${ULP_APP_NAME}
137                   WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
138
139add_custom_command(OUTPUT ${ULP_APP_NAME}.ld ${ULP_APP_NAME}.h
140                   COMMAND ${ULP_MAP_GEN} ${MAP_GEN_EXTRA_ARGS} -s ${ULP_APP_NAME}.sym -o ${ULP_APP_NAME}
141                   DEPENDS ${ULP_APP_NAME}.sym
142                   WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
143
144# Building the component separately from the project should result in
145# ULP files being built.
146add_custom_target(build
147                DEPENDS ${ULP_APP_NAME} ${ULP_APP_NAME}.bin ${ULP_APP_NAME}.sym
148                        ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.ld
149                        ${CMAKE_CURRENT_BINARY_DIR}/${ULP_APP_NAME}.h
150                WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
151
152target_link_libraries(${ULP_APP_NAME} "-T\"${CMAKE_CURRENT_BINARY_DIR}/${ULP_LD_SCRIPT}\"")
153target_link_libraries(${ULP_APP_NAME} ${EXTRA_LINKER_ARGS})
154set_target_properties(${ULP_APP_NAME} PROPERTIES LINK_DEPENDS ${ULP_LD_SCRIPT})
155