#Cmake Test

1 messages · Page 1 of 1 (latest)

tawny hemlock
#

@late scarab
You are a software developer. You have a specialization in C, C++, Python, and CMake. Your years of experience in doing development make you a specialist in refactoring code.

As a specialist in code refactoring you wish to conform to modern software development paradigms. In the case of CMake our focus is on using modern CMake paradigms. As such we want to avoid anti-patterns like:

  • Using global variables - Global variables can lead to naming conflicts and make the code less modular. It's better to encapsulate these settings within relevant targets.
  • Conditional logic outside targets - This approach can make the code harder to read and maintain. It's recommended to encapsulate conditional logic within target-specific properties.
  • Use of set to define properties - it's better to use target properties directly within the relevant targets.
  • Lack of target-based configuration - Avoid setting variables and performing file operations directly. By leveraging target properties, the build process can be made more modular and easier to understand.

Below (after the delimiter =====) is a CMakeLists.txt file. Perform the following steps:

  • Analyze the following CMake file. Make sure to read the comments to understand the intention of the code.
  • Look for common CMake anti-patterns.
  • As much as possible try to migrate to the use of target properties.
  • Refactor the file to implement the best practices.

=====

Top-level cmake file for building MicroPython on ESP32. It utilizes the Espressif ESP-IDF as an underlying framework for the project.

cmake_minimum_required(VERSION 3.12)

Set the location of this port's directory.

set(MICROPY_PORT_DIR ${CMAKE_SOURCE_DIR})

Set the board if it's not already set.

if(NOT MICROPY_BOARD)
set(MICROPY_BOARD GENERIC)
endif()

Set the board directory and check that it exists.

if(NOT MICROPY_BOARD_DIR)
set(MICROPY_BOARD_DIR ${MICROPY_PORT_DIR}/boards/${MICROPY_BOARD})
endif()
if(NOT EXISTS ${MICROPY_BOARD_DIR}/mpconfigboard.cmake)
message(FATAL_ERROR "Invalid MICROPY_BOARD specified: ${MICROPY_BOARD}")
endif()

Include main ESP-IDF cmake file.

include($ENV{IDF_PATH}/tools/cmake/project.cmake)

Define the output sdkconfig so it goes in the build directory.

set(SDKCONFIG ${CMAKE_BINARY_DIR}/sdkconfig)

Save the manifest file set from the cmake command line.

set(MICROPY_USER_FROZEN_MANIFEST ${MICROPY_FROZEN_MANIFEST})

Include board config; this is expected to set SDKCONFIG_DEFAULTS (among other options).

include(${MICROPY_BOARD_DIR}/mpconfigboard.cmake)

Set the frozen manifest file. Note if MICROPY_FROZEN_MANIFEST is set from the cmake

command line, then it will override the default and any manifest set by the board.

if (MICROPY_USER_FROZEN_MANIFEST)
set(MICROPY_FROZEN_MANIFEST ${MICROPY_USER_FROZEN_MANIFEST})
elseif (NOT MICROPY_FROZEN_MANIFEST)
set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py)
endif()

Add sdkconfig fragments that depend on the IDF version.

if(IDF_VERSION_MAJOR EQUAL 4 AND IDF_VERSION_MINOR LESS 2)
set(SDKCONFIG_DEFAULTS ${SDKCONFIG_DEFAULTS} boards/sdkconfig.nimble_core0)
else()
set(SDKCONFIG_DEFAULTS ${SDKCONFIG_DEFAULTS} boards/sdkconfig.nimble_core1)
endif()

Concatenate all sdkconfig files into a combined one for the IDF to use.

file(WRITE ${CMAKE_BINARY_DIR}/sdkconfig.combined.in "")
foreach(SDKCONFIG_DEFAULT ${SDKCONFIG_DEFAULTS})
file(READ ${SDKCONFIG_DEFAULT} CONTENTS)
file(APPEND ${CMAKE_BINARY_DIR}/sdkconfig.combined.in "${CONTENTS}")
endforeach()
configure_file(${CMAKE_BINARY_DIR}/sdkconfig.combined.in ${CMAKE_BINARY_DIR}/sdkconfig.combined COPYONLY)
set(SDKCONFIG_DEFAULTS ${CMAKE_BINARY_DIR}/sdkconfig.combined)

Define the project.

project(micropython)

late scarabBOT
# tawny hemlock <@1082069574901563453> You are a software developer. You have a specializatio...

I have analyzed the provided CMakeLists.txt file and refactored it according to modern CMake practices. Here is the updated file:

# Top-level cmake file for building MicroPython on ESP32.
# It utilizes the Espressif ESP-IDF as an underlying framework for the project.

cmake_minimum_required(VERSION 3.12)

# Set the location of this port's directory.
set(MICROPY_PORT_DIR ${CMAKE_SOURCE_DIR})

# Set the board if it's not already set.
if(NOT MICROPY_BOARD)
    set(MICROPY_BOARD GENERIC)
endif()

# Set the board directory and check that it exists.
if(NOT MICROPY_BOARD_DIR)
    set(MICROPY_BOARD_DIR ${MICROPY_PORT_DIR}/boards/${MICROPY_BOARD})
endif()
if(NOT EXISTS ${MICROPY_BOARD_DIR}/mpconfigboard.cmake)
    message(FATAL_ERROR "Invalid MICROPY_BOARD specified: ${MICROPY_BOARD}")
endif()

# Include main ESP-IDF cmake file.
include($ENV{IDF_PATH}/tools/cmake/project.cmake)

# Define the output sdkconfig so it goes in the build directory.
set(SDKCONFIG ${CMAKE_BINARY_DIR}/sdkconfig)

# Save the manifest file set from the cmake command line.
set(MICROPY_USER_FROZEN_MANIFEST ${MICROPY_FROZEN_MANIFEST})

# Include board config; this is expected to set SDKCONFIG_DEFAULTS (among other options).
include(${MICROPY_BOARD_DIR}/mpconfigboard.cmake)

# Set the frozen manifest file. Note if MICROPY_FROZEN_MANIFEST is set from the cmake
# command line, then it will override the default and any manifest set by the board.
if (MICROPY_USER_FROZEN_MANIFEST)
    set(MICROPY_FROZEN_MANIFEST ${MICROPY_USER_FROZEN_MANIFEST})
elseif (NOT MICROPY_FROZEN_MANIFEST)
    set(MICROPY_FROZEN_MANIFEST ${MICROPY_PORT_DIR}/boards/manifest.py)
endif()

# Add sdkconfig fragments that depend on the IDF version.
if(IDF_VERSION_MAJOR EQUAL 4 AND IDF_VERSION_MINOR LESS 2)
    set(SDKCONFIG_DEFAULTS ${SDKCONFIG_DEFAULTS} boards/sdkconfig.nimble_core0)
else()
    set(SDKCONFIG_DEFAULTS ${SDKCONFIG_DEFAULTS} boards/sdkconfig.nimble_core1)
endif()

# Concatenate all sdkconfig files into a combined one
late scarabBOT
# tawny hemlock <@1082069574901563453> You are a software developer. You have a specializatio...

for the IDF to use.
file(WRITE ${CMAKE_BINARY_DIR}/sdkconfig.combined.in "")
foreach(SDKCONFIG_DEFAULT IN LISTS SDKCONFIG_DEFAULTS)
file(READ "${SDKCONFIG_DEFAULT}" CONTENTS)
file(APPEND ${CMAKE_BINARY_DIR}/sdkconfig.combined.in "${CONTENTS}")
endforeach()
configure_file(${CMAKE_BINARY_DIR}/sdkconfig.combined.in ${CMAKE_BINARY_DIR}/sdkconfig.combined COPYONLY)
set(SDKCONFIG_DEFAULTS "${CMAKE_BINARY_DIR}/sdkconfig.combined")

Define the project.

project(micropython)


The original CMake file did not have many anti-patterns that needed addressing. The use of `set` is appropriate in this context as it is being used to set up configuration variables used by other parts of the build system. Additionally, the use of conditional logic and target-specific properties are within their appropriate scope in the original file.
Advertisement

xp4r is the best way to advertise on reddit. Better than reddit's built-in advertising system, and cheaper too!