# Is there a way to get the build command line?

**URL:** https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891
**Category:** Usage
**Created:** [November 17, 2022, 1:59pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891 "2022-11-17T13:59:46Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![Jack](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jack/32/2926_2.png) [@Jack](https://discourse.cmake.org/u/Jack)
#### Post date: [November 17, 2022, 1:59pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/1 "2022-11-17T13:59:46Z")

</div>

CMake obviously knows what the command build line would be because it is executing it. Can I get what that build line would be through the CMake system so that I can interrogate it?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [November 17, 2022, 3:21pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/2 "2022-11-17T15:21:11Z")

</div>

CMake does _not_ know in all cases. In particular, IDEs are fields of properties that CMake sets and then the IDE creates the actual command line.

Even for non-IDE generators, CMake only knows at generation time, so `CMakeLists.txt` code cannot use it. You can use [`CMAKE_EXPORT_COMPILE_COMMANDS`](https://cmake.org/cmake/help/latest/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.html) to create a [compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) which has the full command lines though.

---

<div class="post-metadata">

### Author: ![scivision](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/s/a87d85/32.png) [@scivision](https://discourse.cmake.org/u/scivision)
#### Post date: [November 17, 2022, 4:09pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/3 "2022-11-17T16:09:44Z")

</div>

If you’re able to programmatically run CMake twice, you can retrieve the compile command from the JSON array, iterating the array to compare “file” field vs target name.

This is roughly akin to how I use CMake file API.

```cmake
cmake_minimum_required(VERSION 3.19)

project(Hello LANGUAGES C)

set(CMAKE_EXPORT_COMPILE_COMMANDS true)

if(EXISTS ${PROJECT_BINARY_DIR}/compile_commands.json)
  file(READ ${PROJECT_BINARY_DIR}/compile_commands.json cmds)
  string(JSON L LENGTH ${cmds})
  math(EXPR L "${L} - 1")
  foreach(i RANGE ${L})
    string(JSON c GET ${cmds} ${i} "command")
    message(STATUS "Command ${i}: ${c}")
  endforeach()
endif()

if(NOT EXISTS main.c)
  file(WRITE main.c "int main(void) { return 0; }")
endif()
if(NOT EXISTS main2.c)
  file(WRITE main2.c "int main(void) { return 0; }")
endif()

add_executable(main main.c)
add_executable(main2 main2.c)

```

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [November 17, 2022, 4:23pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/4 "2022-11-17T16:23:06Z")

</div>

Note that as of CMake 3.26, the `compile_commands.json` will have the `output` field present to be able to tell apart different compilations of the same input file.

---

<div class="post-metadata">

### Author: ![Jack](https://discourse.cmake.org/user_avatar/discourse.cmake.org/jack/32/2926_2.png) [@Jack](https://discourse.cmake.org/u/Jack)
#### Post date: [November 17, 2022, 6:16pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/5 "2022-11-17T18:16:29Z")

</div>

Yeah, unfortunately I don’t have access to [`CMAKE_EXPORT_COMPILE_COMMANDS`](https://cmake.org/cmake/help/latest/envvar/CMAKE_EXPORT_COMPILE_COMMANDS.html). I’m using Green Hills and Visual Studio.

---

<div class="post-metadata">

### Author: ![hsattler](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/59ef9b/32.png) [@hsattler](https://discourse.cmake.org/u/hsattler)
#### Post date: [November 18, 2022, 7:31am UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/6 "2022-11-18T07:31:37Z")

</div>

Why is it not possible for cmake with e.g. Visual Studio generator to always generate the .json file? After all, cmake pretty much knows everything. Why does it matter if it outputs a ninja.build or a VS solution?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [November 18, 2022, 12:32pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/7 "2022-11-18T12:32:45Z")

</div>

With `Ninja` and `Makefiles` generators, CMake is indeed making the final command line. With Xcode and VS, CMake is playing MadLibs with IDE property sheets to convince the IDE to make a suitable command line; it doesn’t know the exact line that will be made.

---

<div class="post-metadata">

### Author: ![hsattler](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/h/59ef9b/32.png) [@hsattler](https://discourse.cmake.org/u/hsattler)
#### Post date: [November 18, 2022, 1:11pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/8 "2022-11-18T13:11:55Z")

</div>

Is the exact line needed when running analysis tools like clang\_tidy?

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [November 18, 2022, 2:43pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/9 "2022-11-18T14:43:02Z")

</div>

Generally, yes.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [November 21, 2022, 7:38pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/10 "2022-11-21T19:38:49Z")

</div>

you may try [bear](https://github.com/rizsotto/Bear) (at least under `linux`):

```nohighlight
BEAR(1) BEAR(1)

NAME
       Bear - a tool to generate compilation database for Clang tooling.

SYNOPSIS
       bear [options] -- [build command]

DESCRIPTION
       The JSON compilation database <http://clang.llvm.org/docs/JSONCompilationDatabase.html> is used in Clang project to provide information how a single compilation unit was
       processed. When that is available then it is easy to re-run the compilation with different programs.

       Bear executes the original build command and intercept the command executions issued by the build tool. From the log of command executions it tries to identify the compiler
       calls and creates the final compilation database.

```

---

<div class="post-metadata">

### Author: ![ben.boeckel](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/b/ea5d25/32.png) [@ben.boeckel](https://discourse.cmake.org/u/ben.boeckel)
#### Post date: [November 21, 2022, 7:47pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/11 "2022-11-21T19:47:09Z")

</div>

Seeing as Linux doesn’t support either of the IDEs in question, something else is likely necessary.

---

<div class="post-metadata">

### Author: ![ClausKlein](https://discourse.cmake.org/user_avatar/discourse.cmake.org/clausklein/32/352_2.png) [@ClausKlein](https://discourse.cmake.org/u/ClausKlein)
#### Post date: [November 21, 2022, 7:53pm UTC](https://discourse.cmake.org/t/is-there-a-way-to-get-the-build-command-line/6891/12 "2022-11-21T19:53:04Z")

</div>

I would use **GHS** under `Linux` with `Ninja` .

And `Microsoft cl` with `Nina` under `Windows`.

Both works fine 😉

And `ninja clean && and ninja -nv` show all you want to see.
