Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy compile_commands.json to project root folder

Tags:

cmake

I have a CMakeLists.txt in the root of my project with CMAKE_EXPORT_COMPILE_COMMANDS turned on.

I am building target inside a folder and is called via add_subdirectory. The folder has its own CMakeLists.txt file.

compile_commands.json is built in the root of the binary directory, and I want to copy it to root of source directory after running the cmake command.

I have tried two approaches.

  1. add_custom_target and add_custom_command. I created a dummy target. I used this target for add_custom_command to copy the file but it does not trigger command in add_custom_command.

  2. file(COPY ...) The first time the command is triggered, the compile_commands.json is not created via cmake. I don't want to run cmake command twice to get copy compile_commands.json to root of source folder.

CMAKE_MINIMUM_REQUIRED(VERSION 3.8)
project(exec LANGUAGES CXX)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_subdirectory("DirectoyWithTarget")

add_custom_target(copy_compile_commands
  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json)
add_custom_command(
  TARGET copy_compile_commands
  PRE_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy_if_different
    ${CMAKE_CURRENT_BINARY_DIR}/compile_commands.json
    ${CMAKE_CURRENT_SOURCE_DIR}/compile_commands.json
  )   

The compile_commands.json file is not copied to ${CMAKE_CURRENT_SOURCE_DIR}. This means the add_custom_command is not triggered.

like image 637
Akshit Sharma Avatar asked Aug 12 '19 16:08

Akshit Sharma


Video Answer


1 Answers

Haven't tested these much, but here are two cmake based solutions I came up with.

Option 1

Less code, but always runs.

add_custom_target(
    copy-compile-commands ALL
    ${CMAKE_COMMAND} -E copy_if_different
        ${CMAKE_BINARY_DIR}/compile_commands.json
        ${CMAKE_CURRENT_LIST_DIR}
    )

Option 2

More code, but sets up dependencies so doesn't run unless need to. Can handle case where you delete compile_commands.json in binary directory.

# Copy to source directory
add_custom_target(
    copy-compile-commands ALL
    DEPENDS
        ${CMAKE_CURRENT_LIST_DIR}/compile_commands.json
    )
add_custom_command(
    OUTPUT ${CMAKE_CURRENT_LIST_DIR}/compile_commands.json
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
        ${CMAKE_BINARY_DIR}/compile_commands.json
        ${CMAKE_CURRENT_LIST_DIR}/compile_commands.json
    DEPENDS
        # Unlike "proper" targets like executables and libraries, 
        # custom command / target pairs will not set up source
        # file dependencies, so we need to list file explicitly here
        generate-compile-commands
        ${CMAKE_BINARY_DIR}/compile_commands.json
    )

# Generate the compilation commands. Necessary so cmake knows where it came
# from and if for some reason you delete it.
add_custom_target(generate-compile-commands
    DEPENDS
        ${CMAKE_BINARY_DIR}/compile_commands.json
    )
add_custom_command(
    OUTPUT ${CMAKE_BINARY_DIR}/compile_commands.json
    COMMAND ${CMAKE_COMMAND} -B${CMAKE_BINARY_DIR} -S${CMAKE_SOURCE_DIR}
    )

like image 187
grifcj Avatar answered Sep 28 '22 21:09

grifcj