evo-crypter
 
Loading...
Searching...
No Matches
Adding Custom Commands in CMake

This document explains how to add custom commands to the evo-crypter project's CMake build system.

Why Use Custom Commands?

Custom commands are useful for automating various tasks in your build process, such as:

  • Running code generators
  • Preprocessing files
  • Executing custom scripts
  • Integrating external tools

Basic Structure of <tt>add_custom_command</tt>

The primary CMake command for adding custom commands is add_custom_command. It has two main forms:

1. Adding a custom command to generate an output file:

add_custom_command(OUTPUT output_file
COMMAND command1 [ARGS] [arguments1...]
[COMMAND command2 [ARGS] [arguments2...] ...]
[MAIN_DEPENDENCY main_dependency]
[DEPENDS [depends...]]
[BYPRODUCTS [files...]]
[IMPLICIT_DEPENDS <lang1> depend1
<lang2> depend2]
[WORKING_DIRECTORY dir]
[COMMENT comment]
[VERBATIM] [APPEND])

2. Adding a custom command to a target (e.g., executable or library):

add_custom_command(TARGET target
PRE_BUILD | PRE_LINK | POST_BUILD
COMMAND command1 [ARGS] [arguments1...]
[COMMAND command2 [ARGS] [arguments2...] ...]
[BYPRODUCTS [files...]]
[WORKING_DIRECTORY dir]
[COMMENT comment]
[VERBATIM])

Commonly Used Options:

  • **OUTPUT output_file:** Specifies the output file(s) generated by the command.
  • **COMMAND command1 [ARGS] [arguments1...]:** Defines the command to execute along with its arguments. You can have multiple COMMAND clauses, which will be executed in order.
  • **DEPENDS [depends...]:** Lists the dependencies of the custom command. The command will be re-run if any of the dependencies change.
  • **WORKING_DIRECTORY dir:** Sets the working directory for the command.
  • **COMMENT comment:** Adds a comment that will be displayed during the build process.
  • **VERBATIM:** Ensures that all arguments are passed to the command exactly as specified, without any special interpretation by CMake.
  • **TARGET target:** Specifies the target (executable or library) to which the custom command is attached.
  • **PRE_BUILD:** Runs the command before the target is built.
  • **PRE_LINK:** Runs the command before the target is linked.
  • **POST_BUILD:** Runs the command after the target is built.

Example: Adding a Version Script Command

Let's add a custom command that executes the scripts/update_version.sh script to update the project's version before the build starts.

  1. Edit CMakeLists.txt:

    # ... (other CMake code)
    # Custom command to update the version
    add_custom_command(
    OUTPUT ${CMAKE_SOURCE_DIR}/version.txt
    COMMAND ${CMAKE_SOURCE_DIR}/scripts/update_version.sh ${NEW_VERSION}
    DEPENDS ${CMAKE_SOURCE_DIR}/scripts/update_version.sh
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    COMMENT "Updating project version to ${NEW_VERSION}"
    VERBATIM
    )
    # Make sure the target depends on the updated version file
    add_dependencies(evo ${CMAKE_SOURCE_DIR}/version.txt)
    # ... (rest of your CMake code)
  2. How to Use:
    • To update the version before building, you can run:

      bash cmake -DNEW_VERSION=0.2.0 .. cmake --build .

Example: Adding a Command to Run a Script

Let's add a custom command that executes the scripts/lint.sh script to run the linter after the evo executable is built.

  1. Edit CMakeLists.txt:

    # ... (other CMake code)
    # Custom command to run the linter after building the target
    add_custom_command(TARGET evo
    POST_BUILD
    COMMAND ${CMAKE_SOURCE_DIR}/scripts/lint.sh
    COMMENT "Running linter"
    VERBATIM)
    # ... (rest of your CMake code)
  2. How to Use:
    • The linter will be executed automatically after the evo executable is built.

Tips

  • Error Handling: Make sure your custom scripts handle errors properly and return non-zero exit codes on failure. This will cause the CMake build to fail as well.
  • Dependencies: Carefully consider the dependencies of your custom commands. Use DEPENDS to ensure that the commands are re-run when necessary.
  • Output Files: If your custom command generates output files, declare them using OUTPUT so that CMake can track them for dependency management.
  • Readability: Use COMMENT to make your custom commands more understandable.
  • Portability: If you're using external tools or scripts, try to make your custom commands as portable as possible by using CMake variables for paths and avoiding hardcoded values that might be specific to a particular system.

Conclusion

Custom commands are a powerful tool for extending the CMake build system. They allow you to automate a wide range of tasks and customize your build process to meet the specific needs of your project. By understanding the different options and best practices, you can effectively use add_custom_command to enhance your development workflow.