6

I'm designing a collection of libraries that can be linked in my other C++ projects. In order to make the collection easy to use I want to either be able to link to individual libraries, or link to one master library that contains all of the others. How can I specify this in a CMakeLists.txt file?

For example:

add_library(library1 SHARED
    file1.cpp
    file2.cpp
)

add_library(library2 SHARED
    file3.cpp
    file4.cpp
)

# Define a master library that contains both of the others
add_library(master_library SHARED
    library1
    library2
)

Is there a proper way to get this functionality with CMake?


EDIT:

This question is not a duplicate of: CMake: Is it possible to build an executable from only static libraries and no source?

This has to do with shared libraries only and has nothing to do with static libraries or executables.

tjwrona1992
  • 8,614
  • 8
  • 35
  • 98
  • 1
    Why have two different libraries if you just going to "merge" them into a single "master" library? Unless you have other targets that depend on either of the other libraries, then just create the *single* library `master_library` from the source of the others, and don't have the other libraries at all. – Some programmer dude Jul 25 '17 at 13:58
  • That's the exact reason I want to have separate libraries. Some programs will only depend on the smaller libraries while larger programs that need all of the features can just link to a master library instead of having to link to all of the smaller ones – tjwrona1992 Jul 25 '17 at 14:00
  • Having this merged "master" library will just use extra space on disk that is not needed. When both libraries are needed then use both. It will also make it clearer for others. – Some programmer dude Jul 25 '17 at 14:02
  • On a much larger scale there may be many more small libraries so it would be a lot of extra work to separately link to all of them – tjwrona1992 Jul 25 '17 at 14:03
  • 1
    Possible duplicate of [CMake: Is it possible to build an executable from only static libraries and no source?](https://stackoverflow.com/questions/34234446/cmake-is-it-possible-to-build-an-executable-from-only-static-libraries-and-no-s) – Florian Jul 25 '17 at 14:46
  • @Florian this question is about shared libraries, and has nothing to do with static libraries or executables. – tjwrona1992 Jul 25 '17 at 14:52

3 Answers3

12

This solution seemed to work.

add_library(library1 SHARED
    file1.cpp
    file2.cpp
)

add_library(library2 SHARED
    file3.cpp
    file4.cpp
)

# dummy file is required to avoid a cmake error, but this
# "dummy" file serves no other purpose and is empty.
add_library(master_library SHARED
    dummy.cpp
)

# Link the master library with the other libraries
target_link_libraries(master_library
    library1
    library2
)

After doing this, I was able to compile and link code using ONLY the master library.

tjwrona1992
  • 8,614
  • 8
  • 35
  • 98
  • That's not really the same and anyone could have suggested that since the dependencies are still there. You cannot distribute anything that uses "master_library" without library1 and library2 - at least not on some platforms like Windows. – utopia Jul 25 '17 at 16:45
  • @utopia All of the libraries are all part of the same cmake project, so anywhere it is deployed `library1`, `library2` and `master_library` will all be there. This allows you to only link to `master_library` and its basically a shortcut for linking to the other 2. That's pretty much what I was looking for. – tjwrona1992 Jul 25 '17 at 17:01
2

If all you want is a convenient target for use by others and don't care about whether you have one or multiple libraries, cmake can do that with an interface library:

add_library(library1 SHARED
    file1.cpp
    file2.cpp
)

add_library(library2 SHARED
    file3.cpp
    file4.cpp
)

add_library(master_library INTERFACE)

# Link the master library with the other libraries
target_link_libraries(master_library INTERFACE
    library1
    library2
)

Then in another location if you have

target_link_libraries(my_executable PRIVATE
    master_library
)

my_executable will link against library1 and library2

Caleb Huitt - cjhuitt
  • 14,785
  • 3
  • 42
  • 49
  • I'm fairly certain this doesn't work with our SUPER old version of CMake that my company uses (we use v2.8.12) but this is exactly what I was looking for. I will change this to my accepted answer since this is what most people coming here will be looking for. – tjwrona1992 Apr 26 '23 at 20:27
  • @tjwrona1992 Here's hoping you can get to a somewhat modern version of CMake... my company currently uses 3.16 and I still run into things in newer versions I want to use – Caleb Huitt - cjhuitt Apr 27 '23 at 13:54
-1

Just make a function in your project:

function(link_all_libs TARGET)
    target_link_libraries(TARGET library1 library2)
endfunction(link_all_libs)

Now you can simply:

link_all_libs(myapp)
John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • 1
    This would still have to be in the `CMakeLists.txt` file for the project that is linking the master library so its basically the same as just separately linking them. I basically want the project linking to the master library to only have to know about the master library and none of the others. – tjwrona1992 Jul 25 '17 at 14:07