# cmake imported library and precompiled headers

**URL:** https://discourse.cmake.org/t/cmake-imported-library-and-precompiled-headers/2459
**Category:** Usage
**Created:** [January 2, 2021, 4:38pm UTC](https://discourse.cmake.org/t/cmake-imported-library-and-precompiled-headers/2459 "2021-01-02T16:38:35Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![elpie89](https://discourse.cmake.org/user_avatar/discourse.cmake.org/elpie89/32/1057_2.png) [@elpie89](https://discourse.cmake.org/u/elpie89)
#### Post date: [January 2, 2021, 4:38pm UTC](https://discourse.cmake.org/t/cmake-imported-library-and-precompiled-headers/2459/1 "2021-01-02T16:38:35Z")

</div>

I have a simple CMake project organized like this:

```auto
ExternalDependencies
 ->glm
   CMakeLists.txt

MasterFolder
CMakeLists.txt (A)
->src
 CMakeLists.txt (B)
 ->include
  precompiled_header.h

```

(A) looks like this:

```auto
project(coffeecup VERSION 0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)

include(ExternalProject)

ExternalProject_Add(glm_project
        PREFIX glm-lib
        GIT_REPOSITORY "git@github.com:g-truc/glm.git"
        GIT_TAG "24a4befe80171966758983173f381ce1ef6c839f"
        SOURCE_DIR "${PROJECT_SOURCE_DIR}/../ExternalDependencies/glm"
        CMAKE_ARGS "-DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/libs/glm"
        CMAKE_CACHE_ARGS -DBUILD_STATIC_LIBS:BOOL=ON
                            -DBUILD_SHARED_LIBS:BOOL=OFF
                            -DGLM_TEST_ENABLE:BOOL=OFF
        UPDATE_COMMAND ""
        INSTALL_COMMAND ""
        )
ExternalProject_Get_property(glm_project BINARY_DIR)
ExternalProject_Add_Step(glm_project custom_install_glm
        WORKING_DIRECTORY "${BINARY_DIR}"
        COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/libs/glm/lib" "${CMAKE_BINARY_DIR}/libs/glm/include/glm"
        COMMAND ${CMAKE_COMMAND} -E copy glm/glm_static.lib "${CMAKE_BINARY_DIR}/libs/glm/lib"
        COMMAND ${CMAKE_COMMAND} -E copy_directory "${PROJECT_SOURCE_DIR}/../ExternalDependencies/glm/glm" "${CMAKE_BINARY_DIR}/libs/glm/include/glm"
        COMMAND ${CMAKE_COMMAND} -E remove -f "${CMAKE_BINARY_DIR}/libs/glm/include/glm/CMakeLists.txt"
        DEPENDEES build
        COMMENT "custom installation process glm_project"
        ALWAYS TRUE
        )

SET(CMAKE_CONFIGURATION_TYPES "Debug;Release")

file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/libs/glm/include")

add_library (glm STATIC IMPORTED)
set_target_properties (glm PROPERTIES IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/libs/glm/lib/glm_static.lib)
target_include_directories(glm INTERFACE ${CMAKE_BINARY_DIR}/libs/glm/include)

add_dependencies(glm glm_project)
add_subdirectory(src)

```

in the (B) CMakeLists.txt:

```auto
list(APPEND EXTERNAL_DEPENDENCIES_INCLUDES
        ../../ExternalDependencies/VulkanMemoryAllocator/src
        )

add_executable(coffeecup
        include/PrecompiledHeader.h
        Window.cpp )
set_target_properties(coffeecup PROPERTIES DEBUG_POSTFIX "d")

target_include_directories(coffeecup 
        PUBLIC 
           include
        )

target_link_libraries(coffeecup 
        PUBLIC 
           glm
        )

target_precompile_headers(coffeecup
        PUBLIC
            include/PrecompiledHeader.h
        )

```

and finally, the precompiled header looks like this:

```auto
#pragma once

// >>> GLM <<<
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/quaternion.hpp>

// >>> STL <<<
#include <unordered_map>

```

So the problem here is that the precompiled header is actually built before the static library GLM so it only works if I previously build my GLM library How can I force the precompiled header to be built only if the library is there? I’m missing something as I am really new with CMake, probably there is an issue with the usage of PRIVATE|INTERFACE|PUBLIC

---

<div class="post-metadata">

### Author: ![McMartin](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mcmartin/32/150_2.png) [@McMartin](https://discourse.cmake.org/u/McMartin)
#### Post date: [January 2, 2021, 6:30pm UTC](https://discourse.cmake.org/t/cmake-imported-library-and-precompiled-headers/2459/2 "2021-01-02T18:30:10Z")

</div>

The first thing I would change is

```diff
-ExternalProject_Add_Step(glm_project custom_install_glm
+ExternalProject_Add_Step(glm_project install

```

because the [documentation of `ExternalProject_Add_Step`](https://cmake.org/cmake/help/latest/module/ExternalProject.html#command:externalproject_add_step) says:

> The specified `<step>` must not be one of the pre-defined steps (`mkdir` , `download` , `update` , `patch` , `configure` , `build` , `install` or `test` )

Then, you can use [`ExternalProject_Add_StepTargets`](https://cmake.org/cmake/help/latest/module/ExternalProject.html#command:externalproject_add_steptargets) to create a CMake target that “represents” installing glm and make your own target depend on it.

I hope this helps!

---

<div class="post-metadata">

### Author: ![elpie89](https://discourse.cmake.org/user_avatar/discourse.cmake.org/elpie89/32/1057_2.png) [@elpie89](https://discourse.cmake.org/u/elpie89)
#### Post date: [January 2, 2021, 6:56pm UTC](https://discourse.cmake.org/t/cmake-imported-library-and-precompiled-headers/2459/3 "2021-01-02T18:56:55Z")

</div>

Sorry but I do not understand…the documentation says _must not be_  
in fact, if I do what you say I have an error

```auto
CMake Error at ...cmake-3.17/Modules/ExternalProject.cmake:2224 (add_custom_command): 
  Attempt to add a custom rule to output
...
which already has a custom rule.

```

what am I missing?

---

<div class="post-metadata">

### Author: ![McMartin](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mcmartin/32/150_2.png) [@McMartin](https://discourse.cmake.org/u/McMartin)
#### Post date: [January 2, 2021, 6:58pm UTC](https://discourse.cmake.org/t/cmake-imported-library-and-precompiled-headers/2459/4 "2021-01-02T18:58:57Z")

</div>

My bad, I completely misread the documentation 😅

Please skip that part and focus on `ExternalProject_Add_StepTargets` only.

---

<div class="post-metadata">

### Author: ![elpie89](https://discourse.cmake.org/user_avatar/discourse.cmake.org/elpie89/32/1057_2.png) [@elpie89](https://discourse.cmake.org/u/elpie89)
#### Post date: [January 2, 2021, 7:03pm UTC](https://discourse.cmake.org/t/cmake-imported-library-and-precompiled-headers/2459/5 "2021-01-02T19:03:56Z")

</div>

no problem…so yes looking on the documentation for [ExternalProject\_Add\_StepTargets](https://cmake.org/cmake/help/latest/module/ExternalProject.html#command:externalproject_add_steptargets)  
It seems there is a dependence system  
But how can I make my precompiled header dependent on the library?

---

<div class="post-metadata">

### Author: ![McMartin](https://discourse.cmake.org/user_avatar/discourse.cmake.org/mcmartin/32/150_2.png) [@McMartin](https://discourse.cmake.org/u/McMartin)
#### Post date: [January 2, 2021, 7:23pm UTC](https://discourse.cmake.org/t/cmake-imported-library-and-precompiled-headers/2459/6 "2021-01-02T19:23:16Z")

</div>

I would guess something like this:

```auto
# In (A) CMakeLists.txt:
ExternalProject_Add_StepTargets(glm_project custom_install_glm)

# In (B) CMakeLists.txt:
add_dependencies(coffeecup glm_project-custom_install_glm)

```
