0

I followed this thread to be able to set different library files for each configuration I have. My current use case is that I use 4 configurations (Debug, Release, MinSizeRel, RelWithDebInfo). I want to have a structure where I have output_folder/Debug, output_folder/Release, etc, and copy all libraries I need into each folder. This way, I have all libraries related to each configuration in the respective output folders.

The problem is that I am having issues with linking my project. What seems to happend is that I have specific libraries to specific configurations. For instance, I might need a library for Debug that I don't need for Release. The problem is that the Release configuration is linked to this Debug library and cannot find the file. Here's an example:

Let's say I need liblokid.lib for Debug, but I don't need it for Release, and that I need libtinyxml2.lib for Release but not for Debug.

add_library(libloki STATIC IMPORTED)
set_target_properties(libloki PROPERTIES IMPORTED_LOCATION_DEBUG ${CMAKE_BINARY_DIR}/bin/Debug/liblokid.lib)
target_link_libraries(${iProjectName} libloki)

add_library(libtinyxml2 STATIC IMPORTED)
set_target_properties(libtinyxml2 PROPERTIES IMPORTED_LOCATION_RELEASE ${CMAKE_BINARY_DIR}/bin/Release/libtinyxml2.lib)
target_link_libraries(${iProjectName} libtinyxml2)

When I open my Visual Studio solution, this is what I see when I select my Debug config when I go to [subproject]->properties->Linker->Input->Additional Dependencies:

..\bin\Debug\liblokid.lib
libtinyxml2.lib-NOTFOUND

And this is when I select the Release configuration:

..\bin\Release\tinyxml2.lib
liblokid.lib-NOTFOUND

Is there a way to have a library linked only during certain configurations? It seems like it is not possible from my results.

JigsawCorp
  • 479
  • 2
  • 6
  • 15
  • Having external dependencies inside your build directory is not a good way to do things. – Guillaume Racicot Jul 29 '19 at 19:18
  • 1
    "Is there a way to have a library linked only during certain configurations?" - What is wrong with `target_link_libraries(${iProjectName} debug libloki)`? The referenced question is exactly about `debug`/`optimized` keywords. Alternative to these keywords is using [generator expressions](https://cmake.org/cmake/help/v3.9/manual/cmake-generator-expressions.7.html). E.g. `$<$:libloki>` refers to the `libloki` only for the Debug configuration. – Tsyvarev Jul 29 '19 at 19:52
  • @Tsyvarev I want even more choices, so I need MinSizeRek, RelWithDebInfo, Release and Debug and possibly have different libraries for each config. According to the documentation for `target_link_libraries`, it states "Higher granularity may be achieved for per-configuration rules by creating and linking to IMPORTED library targets". This is exactly what I am doing, yet it is adding the library to all configs. – JigsawCorp Jul 30 '19 at 11:52
  • @GuillaumeRacicot What would be the good way? My dependencies are Shared libraries, so I need them at runtime. By copying them in the build folder, I have a folder ready for release that I can just copy or move somewhere else and it works, – JigsawCorp Jul 30 '19 at 11:53
  • 1
    It seems you mix different situations: 1. In **every configuration** link to the **different flows** of the *same* library. Imported targets with different `IMPORTED_LOCATION_` are best suited for this case. 2. **Limit** configurations when to link with the library. For that purpose you may use either keywords (`debug`/`optimized`) or *generator expressions* for more precise tuning. Note, that situations 1 and 2 may overlap, and appropriate combination of IMPORTED targets and generator expressions will resolve them. – Tsyvarev Jul 30 '19 at 12:40
  • @Tsyvarev So, let's say I only want to link libloki.so with MinSizeRel, I would do `target_link_libraries(${iProjectName} $<$:libloki>)`? – JigsawCorp Jul 30 '19 at 12:50
  • 1
    Yes, exactly this way. – Tsyvarev Jul 30 '19 at 12:52
  • @Tsyvarev Thank you so much. it worked! You must be the creator of CMake to know all these things, every time I asked a question in the last 3 months you were the one to answer. – JigsawCorp Jul 30 '19 at 13:08
  • @JigsawCorp think of your build directory as something entirely managed by CMake. The good way would be to have a CMake command to copy the binary into the location instead of copying manually. – Guillaume Racicot Jul 30 '19 at 13:30
  • @GuillaumeRacicot I created multiple macros in CMake to attempt to achieve this and am almost done. When I want to add a library in a `CMakeLists.txt`, I have a series of macros that find for what configuration and what project I am doing so, and wll then find the location of said library for each needed configuration, link with the project, and finaly copy all required library files in my binary directory. The only thing that I need to do now is make this functional on Windows, as I need to find a `.lib`'s matching `.dll`. – JigsawCorp Jul 30 '19 at 13:36
  • @Tsyvarev Would it be possible to replace the library name by a path to a library file? For example, could I do `target_link_libraries(${iProjectName} $<$:/home/user/Documents/libloki.so>)` instead? – JigsawCorp Jul 30 '19 at 18:15
  • Yes, inside generator expression you may specify a library path instead of the target. – Tsyvarev Jul 30 '19 at 22:12

0 Answers0