# cmake: forcing build type for a specific library fails

**URL:** https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332
**Category:** Code
**Tags:** os:linux
**Created:** [October 25, 2021, 6:34am UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332 "2021-10-25T06:34:45Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Serbenet](https://discourse.cmake.org/user_avatar/discourse.cmake.org/serbenet/32/1904_2.png) [@Serbenet](https://discourse.cmake.org/u/Serbenet)
#### Post date: [October 25, 2021, 6:34am UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332/1 "2021-10-25T06:34:45Z")

</div>

Hi,

I have a c++ project made of several executables and libraries. I use cmake for the compilation. Also in debug mode, I add “\_d” as postfix for the libraries (i.e.: libfoo\_d.so).

Now, one of those libraries (say lib1) is so slow in debug mode that I want to always build it in release mode. So, in the CMakeLists.txt of lib1 I am forcing the CMAKE\_BUILD\_TYPE to Release:

```auto
set(CMAKE_BUILD_TYPE "Release")

```

This library has dependencies (say lib2). Of course, lib2 should still be compiled in debug mode and its name should be liblib2\_d.so (I only want lib1 to be in release mode).

Unfortunately, when building (in debug mode), I get the following error message:

`[build] make[3]: *** No rule to make target 'binaries/lib/liblib2.so', needed by 'binaries/lib/liblib1_d.so'. Stop.`

Here is the CMakeLists.txt file for lib1:

```auto
cmake_minimum_required(VERSION 2.8.9)

if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
   project (lib1)
endif()

if (NOT TARGET lib2)
   add_subdirectory(../lib2 lib2)
endif()

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/binaries/lib/)

set(CMAKE_BUILD_TYPE "Release")

include_directories(include)
include_directories(../lib2/include lib2)

add_library(lib1 SHARED src/src1.cpp include/lib1.h)

target_link_libraries(lib1 lib2)

```

I am using cmake version 3.18.4.

I have also uploaded [here](https://wetransfer.com/downloads/de6d9ad2898c79436ab41c422c74ba6e20211022124833/2113e5), a sample that shows the issue. Just unzip the content and run:

`mkdir build && cd build && cmake --configure ../app -DCMAKE_BUILD_TYPE=Debug && cmake --build .`

I don’t know how to solve this. Please can you help me?

---

<div class="post-metadata">

### Author: ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)
#### Post date: [October 25, 2021, 12:52pm UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332/2 "2021-10-25T12:52:42Z")

</div>

You cannot do that. Build type is global.

But you can, for the target `lib1`, change the compilation options (for example adding optimization flag) in debug mode to speed up execution of this library:

```cmake
add_library(lib1 ...)
set_property(TARGET lib1 PROPERTY COMPILE_OPTIONS "$<$<CONFIG:Debug>:-O2>")

```

---

<div class="post-metadata">

### Author: ![Serbenet](https://discourse.cmake.org/user_avatar/discourse.cmake.org/serbenet/32/1904_2.png) [@Serbenet](https://discourse.cmake.org/u/Serbenet)
#### Post date: [October 26, 2021, 9:36am UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332/4 "2021-10-26T09:36:05Z")

</div>

Thanks.

This is not the ideal solution for me. I want lib1 to be exactly built as if I was in Release mode. This means:

- The compiler flags should be exactly the same than in release mode (it’s not only about -O2). Those flags might be defined at a higher level. I want to lib1 to be compiled with those flags exactly.
- Same for the linker flags
- I also might be using cuda in lib1, and I want the cuda stuff to be compiled in release mode as well.

In the end, I don’t want to have to worry about how a release build is done and which flags or options should be set. I just want lib1 to be built exactly as if we were in Release mode.

Is there not a better way to do this?

---

<div class="post-metadata">

### Author: ![marc.chevrier](https://discourse.cmake.org/letter_avatar_proxy/v4/letter/m/ecb155/32.png) [@marc.chevrier](https://discourse.cmake.org/u/marc.chevrier)
#### Post date: [October 26, 2021, 9:41am UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332/5 "2021-10-26T09:41:47Z")

</div>

In this case, have a look at [ExternalProject](https://cmake.org/cmake/help/latest/module/ExternalProject.html) or [FetchContent](https://cmake.org/cmake/help/latest/module/FetchContent.html) modules.

These modules can be used to implement the concept of `superbuild`.

---

<div class="post-metadata">

### Author: ![fenrir](https://discourse.cmake.org/user_avatar/discourse.cmake.org/fenrir/32/734_2.png) [@fenrir](https://discourse.cmake.org/u/fenrir)
#### Post date: [October 26, 2021, 9:48am UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332/6 "2021-10-26T09:48:15Z")

</div>

Probably ExternalProject because FetchContent pulls into the same build tree, so you’ll end up where you started just using different means 😉

---

<div class="post-metadata">

### Author: ![buildSystemPerson](https://discourse.cmake.org/user_avatar/discourse.cmake.org/buildsystemperson/32/2851_2.png) [@buildSystemPerson](https://discourse.cmake.org/u/buildSystemPerson)
#### Post date: [October 26, 2021, 12:04pm UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332/7 "2021-10-26T12:04:17Z")

</div>

> [@Serbenet](#):
>
> In the end, I don’t want to have to worry about how a release build is done and which flags or options should be set. I just want lib1 to be built exactly as if we were in Release mode.
> 
> Is there not a better way to do this?

If you want a specific library to always be release then you could use a pre-built binary approach.

We have dependencies on a third party library so we just link against pre-built binaries because we don’t care about debugging this third party library. At a certain point large projects can’t build everything from source.

So you can start formalizing lib1 into a more formal library deliverable. And even consider using a C/C++ package manger liker Conan (Which works well with CMake).

This is what big game engines end up doing. At a certain point they break up their libraries into shared libraries gfx, physics, etc. Because if you are working on gfx you don’t need a debug physics library.

---

<div class="post-metadata">

### Author: ![Serbenet](https://discourse.cmake.org/user_avatar/discourse.cmake.org/serbenet/32/1904_2.png) [@Serbenet](https://discourse.cmake.org/u/Serbenet)
#### Post date: [October 27, 2021, 7:23am UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332/8 "2021-10-27T07:23:43Z")

</div>

Thanks

lib1 as such is just an internal library, it has no value outside of my project. So making it an external project or packaging/compiling it independently from the rest of the project does not really make sense.

It’s a shame that there is no simple solution to this problem.

---

<div class="post-metadata">

### Author: ![buildSystemPerson](https://discourse.cmake.org/user_avatar/discourse.cmake.org/buildsystemperson/32/2851_2.png) [@buildSystemPerson](https://discourse.cmake.org/u/buildSystemPerson)
#### Post date: [October 27, 2021, 2:49pm UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332/9 "2021-10-27T14:49:06Z")

</div>

To be clear you can solve this problem with CMake. I just don’t recommend it. You’ll have to write a lot of custom CMake to make this work.

---

<div class="post-metadata">

### Author: ![buildSystemPerson](https://discourse.cmake.org/user_avatar/discourse.cmake.org/buildsystemperson/32/2851_2.png) [@buildSystemPerson](https://discourse.cmake.org/u/buildSystemPerson)
#### Post date: [October 27, 2021, 2:49pm UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332/10 "2021-10-27T14:49:26Z")

</div>

Or you maybe look into using a C++ package manager.

---

<div class="post-metadata">

### Author: ![buildSystemPerson](https://discourse.cmake.org/user_avatar/discourse.cmake.org/buildsystemperson/32/2851_2.png) [@buildSystemPerson](https://discourse.cmake.org/u/buildSystemPerson)
#### Post date: [October 27, 2021, 6:01pm UTC](https://discourse.cmake.org/t/cmake-forcing-build-type-for-a-specific-library-fails/4332/11 "2021-10-27T18:01:35Z")

</div>

Also if another build system made this easy I’d say it’s a bad idea overall. For lots of reasons I can get into.

We had issues a while back where our debug builds were too slow. And it made us re-evaluate our codebase and it improved the perf of our debug/release builds. Even our debug builds can still run at 30-60 FPS.
