The add_library line should be all you need. See this example code I just wrote to test out creating one and then using it (on Ubuntu 16.04):

Structure.h:

int sum( int a, int b );

Structure.c:

int sum( int a, int b ) { 
    return a + b;
}

Main.c:

#include <stdio.h>
#include "Structure.h"

int main() {
    int a = 5;
    int b = 8;
    int c = sum( a, b );

    printf( "sum of %d and %d is %d\n", a, b, c );

    return 0;
}

CMakeLists.txt:

# CMake instructions to make the static lib

ADD_LIBRARY( MyStaticLib STATIC
             Structure.c )


# CMake instructions to test using the static lib

SET( APP_EXE StaticTest )

ADD_EXECUTABLE( ${APP_EXE}
                Main.c ) 

TARGET_LINK_LIBRARIES( ${APP_EXE}
                       MyStaticLib )

And then here is the output from running it:

nick@dusseldorf:~/code/cmake/static_lib$ ls
CMakeLists.txt  Main.c  Structure.c  Structure.h

nick@dusseldorf:~/code/cmake/static_lib$ cmake .
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/nick/code/cmake/static_lib

nick@dusseldorf:~/code/cmake/static_lib$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  CMakeLists.txt  Main.c  Makefile  Structure.c  Structure.h

nick@dusseldorf:~/code/cmake/static_lib$ make
Scanning dependencies of target MyStaticLib
[ 25%] Building C object CMakeFiles/MyStaticLib.dir/Structure.c.o
[ 50%] Linking C static library libMyStaticLib.a
[ 50%] Built target MyStaticLib
Scanning dependencies of target StaticTest
[ 75%] Building C object CMakeFiles/StaticTest.dir/Main.c.o
[100%] Linking C executable StaticTest
[100%] Built target StaticTest

nick@dusseldorf:~/code/cmake/static_lib$ ls
CMakeCache.txt  cmake_install.cmake  libMyStaticLib.a  Makefile    Structure.c
CMakeFiles      CMakeLists.txt       Main.c            StaticTest  Structure.h

nick@dusseldorf:~/code/cmake/static_lib$ ./StaticTest 
sum of 5 and 8 is 13
Answer from ndeubert on Stack Overflow
🌐
CMake
cmake.org › cmake › help › latest › command › add_library.html
add_library — CMake 4.3.0-rc3 Documentation
A Module Library: a plugin that may not be linked by other targets, but may be dynamically loaded at runtime using dlopen-like functionality. If no <type> is given the default is STATIC or SHARED based on the value of the BUILD_SHARED_LIBS variable.
Discussions

Static library dependencies
So, let’s say I have separate libraries A, B & C in separate project folders. C is a static library but it’s CMake is unimportant for this example. B’s CMakeLists.txt looks something like this: add_library(B STATIC b.c… More on discourse.cmake.org
🌐 discourse.cmake.org
0
0
September 24, 2023
CMake: why is there no easy way to build a static library that contains linked static libraries?
this is exactly what static linking is supposed to do, the 3rd party .a libs will be bundled within the library or executable that statically links them More on reddit.com
🌐 r/cpp_questions
19
17
October 13, 2022
How can I include dependencies in a static library using CMake
What I want to achieve is to only need to link against my library and not its dependencies Do you mean you want to bundle SDL and GLEW into your static library? Or that when you do target_link_library(… MyLibrary) it should transitively try to link to SDL and GLEW? Could you share your whole CMake file? More on reddit.com
🌐 r/cpp_questions
12
6
October 25, 2024
static and dynamic libraries, single compile
I am very new to cmake. I am not new to build systems. I have maintained signficant ones. I have a very custom build system. Very declarative, and embeds a little custom scripting language as an escape hatch. Nice but design, but that I would rather stop maintaining. More on discourse.cmake.org
🌐 discourse.cmake.org
0
0
February 28, 2021
Top answer
1 of 4
74

The add_library line should be all you need. See this example code I just wrote to test out creating one and then using it (on Ubuntu 16.04):

Structure.h:

int sum( int a, int b );

Structure.c:

int sum( int a, int b ) { 
    return a + b;
}

Main.c:

#include <stdio.h>
#include "Structure.h"

int main() {
    int a = 5;
    int b = 8;
    int c = sum( a, b );

    printf( "sum of %d and %d is %d\n", a, b, c );

    return 0;
}

CMakeLists.txt:

# CMake instructions to make the static lib

ADD_LIBRARY( MyStaticLib STATIC
             Structure.c )


# CMake instructions to test using the static lib

SET( APP_EXE StaticTest )

ADD_EXECUTABLE( ${APP_EXE}
                Main.c ) 

TARGET_LINK_LIBRARIES( ${APP_EXE}
                       MyStaticLib )

And then here is the output from running it:

nick@dusseldorf:~/code/cmake/static_lib$ ls
CMakeLists.txt  Main.c  Structure.c  Structure.h

nick@dusseldorf:~/code/cmake/static_lib$ cmake .
-- The C compiler identification is GNU 5.4.0
-- The CXX compiler identification is GNU 5.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/nick/code/cmake/static_lib

nick@dusseldorf:~/code/cmake/static_lib$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  CMakeLists.txt  Main.c  Makefile  Structure.c  Structure.h

nick@dusseldorf:~/code/cmake/static_lib$ make
Scanning dependencies of target MyStaticLib
[ 25%] Building C object CMakeFiles/MyStaticLib.dir/Structure.c.o
[ 50%] Linking C static library libMyStaticLib.a
[ 50%] Built target MyStaticLib
Scanning dependencies of target StaticTest
[ 75%] Building C object CMakeFiles/StaticTest.dir/Main.c.o
[100%] Linking C executable StaticTest
[100%] Built target StaticTest

nick@dusseldorf:~/code/cmake/static_lib$ ls
CMakeCache.txt  cmake_install.cmake  libMyStaticLib.a  Makefile    Structure.c
CMakeFiles      CMakeLists.txt       Main.c            StaticTest  Structure.h

nick@dusseldorf:~/code/cmake/static_lib$ ./StaticTest 
sum of 5 and 8 is 13
2 of 4
6

I had same issue. What I missed is the location where build files are created.

CLion makes libraries or exectables under cmake-build-* directory. IfBuild, Execution, Deployment > CMake > Configuration is Debug, the lib file (.a) is created under cmake-build-debug.

🌐
GitHub
github.com › m3y54m › library-with-cmake
GitHub - m3y54m/library-with-cmake: Creating a shared or static library using cmake · GitHub
If you use libhello.a static library, main executable embeds Hello() function in itself and does not need the libhello.a file anymore. But if you use libhello.so shared library, you will get an error message after execution of ./main. Because the main executable needs the libhello.so file to call Hello() function. To solve this problem for shared libraries there are many solutions which two of them is mentioned here: [BEST SOLUTION] Open terminal in the directory where libhello.so exists and execute this command to tell the Linux that where the libhello.so is located.
Author   m3y54m
🌐
CMake
cmake.org › cmake › help › v3.23 › guide › tutorial › Selecting Static or Shared Libraries.html
Step 9: Selecting Static or Shared Libraries — CMake 3.23.5 Documentation
This documents an old version of CMake. Click here to see the latest release. In this section we will show how the BUILD_SHARED_LIBS variable can be used to control the default behavior of add_library(), and allow control over how libraries without an explicit type (STATIC, SHARED, MODULE or ...
🌐
CMake Discourse
discourse.cmake.org › code
Static library dependencies - Code - CMake Discourse
September 24, 2023 - So, let’s say I have separate libraries A, B & C in separate project folders. C is a static library but it’s CMake is unimportant for this example. B’s CMakeLists.txt looks something like this: add_library(B STATIC b.cpp) target_link_libraries(B PRIVATE C) And A’s CMakeLists.txt looks something like this: add_library(A STATIC a.cpp) target_link_libraries(A PRIVATE B) Now, I know the dependency to C is passed along to A thru B – that makes sense!
🌐
GitHub
github.com › ttroy50 › cmake-examples › blob › master › 01-basic › C-static-library › README.adoc
cmake-examples/01-basic/C-static-library/README.adoc at master · ttroy50/cmake-examples
This will be used to create a static library with the name libhello_library.a with the sources in the add_library call. ... As mentioned in the previous example, we pass the source files directly to the add_library call, as recommended for modern CMake.
Author   ttroy50
Find elsewhere
🌐
CMake
cmake.org › cmake › help › latest › guide › tutorial › In-Depth CMake Library Concepts.html
Step 5: In-Depth CMake Library Concepts — CMake 4.3.0-rc3 Documentation
add_library(MyLib-static STATIC) add_library(MyLib-shared SHARED) # Depends on BUILD_SHARED_LIBS add_library(MyLib) This is desirable behavior, as it allows packagers to determine what kind of library will be produced, and ensure dependents link to that version of the library without needing to modify their source code.
🌐
CMake
cmake.cmake.narkive.com › Bm8RKIrl › using-to-build-a-static-library
[CMake] Using cmake to build a static library
If CMake generates the build ... because CMake knows all the dependencies from the target_link_libraries commands, and it can produce the linker line containing all the right lib references. If all you are doing is building static libraries and then feeding them to some other build system, you also have to feed it all the libraries you depend on too, because that information is simply NOT encoded into static libraries. The best way, as always, ...
🌐
CGold
cgold.readthedocs.io › en › latest › tutorials › libraries › static-shared.html
3.11.3. Static + shared — CGold 0.1 documentation
That’s not our case of course since we are trying to build both variants, hence library designed to be used as static or shared. Libraries should be installed to separate directories. So there will be two builds and two root directories. Out of source will kindly help us: > cd library-examples [library-examples]> rm -rf _builds _install [library-examples]> cmake -Hright-way -B_builds/shared -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX="`pwd`/_install/configuration-A" [library-examples]> cmake --build _builds/shared --target install Scanning dependencies of target foo [ 50%] Building CXX object CMakeFiles/foo.dir/foo.cpp.o [100%] Linking CXX shared library libfoo.so [100%] Built target foo Install the project...
🌐
Reddit
reddit.com › r/cpp_questions › cmake: why is there no easy way to build a static library that contains linked static libraries?
r/cpp_questions on Reddit: CMake: why is there no easy way to build a static library that contains linked static libraries?
October 13, 2022 -

AFAIK, CMake does not offer any (convenient) way to combine several static libraries into one (static or shared) library and doing so in a portable (generator, platform) way seems to be non-trivial. To me, this is kind of surprising, since it seems like a very common thing one might want to do. Of course, there are solutions ready for C&P on StackOverflow (e.g., [1]), but I'm kind of wondering: since this is such a hassle, does CMake even want me to do that or is there something wrong (non-idiomatic) with my setup?

My use case is as follows: I've got a project whose primary target is a single library libproject.{a, so}. The project does not depend on any large, well-known libraries; but it does use some smaller libraries to get a few things done. A user of my library should not have to worry about them; in fact, he shouldn't even (have to) know that I'm using those libraries to implement a few things. I might stop using them next month, or use even more libraries by then, and a user should not have to change his build instructions to also link against libsomewhatbettersamplinglibrary123.a because of that.

Since these libraries are all CMake projects and are on Github, I add them as Git submodules to my project, include them in my CMakeLists.txt and link them against my project using

target_link_libraries(project PRIVATE SomeDependencyA SomeDependencyB)

(The dependencies are defined using add_library(...) in their own CMakeLists.txt)

However, now my project compiles to a set of libraries, and a user of libproject.{a, so} also has to link against all those other libraries, which is exactly what I do not want.

Is this something that I'm not supposed to do? Not something that I'm supposed to want? Am I wrong in expecting that CMake should offer a convient way to "export" my project as a single library file that contains all of its (statically linked) dependencies? Or is there some other reason why this is such a hassle to achieve with CMake?

[1] https://stackoverflow.com/questions/11429055/cmake-how-create-a-single-shared-library-from-all-static-libraries-of-subprojec

🌐
Reddit
reddit.com › r/cpp_questions › how can i include dependencies in a static library using cmake
r/cpp_questions on Reddit: How can I include dependencies in a static library using CMake
October 25, 2024 -

I'm working on a library to help me in creating new projects faster. The library is built on top of a few dependencies, like SDL2 and GLEW.

What I want to achieve is to only need to link againts my library and not its dependencies when creating new projects. I could do this when instead of using CMake, I edited the Librarian section of the VS project myself, but when I use CMake to generate the project files, the "Additional Dependencies" and "Additional Library Directories" sections of the project properties remain empty.

Some additional info:
- I'm using vcpkg to manage dependencies
- to link the libraries I use: target_link_libraries(${PROJECT_NAME} PUBLIC SDL2::SDL2 SDL2::SDL2main GLEW::GLEW)
- when I create an executable with add_executable and not a library with add_library everything works as expected.

I've just began learning about CMake a few days ago, so feel free to correct me if I'm doing something wrong.

🌐
CMake
cmake.cmake.narkive.com › fwryim0M › best-way-to-combine-generated-static-libraries-into-a-single-static-library
[CMake] Best way to combine generated static libraries into a single static library
CMakeLists.txt is not compilable, so no extra compilation step, no need for dummy empty source file and add_library is happy. It did not work in my case because of problems related to how our .so are used/generated. (problems at runtime with duplicated symbols in protobufs) 3- a variation around 1 instead of defining OBJECT libs, define a variable holding all the sources for lib1, another for lib2, ... then just do add_library(mysharedlib STATIC ${SOURCES_FOR_lib1} ${SOURCES_FOR_lib2}) It works a little bit like 1) but does not have any of its problems (target_link, add_dependencies, generators, ...) It has new problems of its own though : if your libs live in different subfolders, the variables might not be visible from your add_library(mysharedlib...) call.
🌐
CMake
cmake.cmake.narkive.com › TNONT3iP › use-a-static-library
[Cmake] use a static library
Permalink Hi, If you want to create static library: ADD_LIBRARY(foo STATIC source.c source1.c...) If you want to link static library to your project: TARGET_LINK_LIBRARIES(bar foo) or TARGET_LINK_LIBRARIES(bar /path/to/foo/libfoo.a) Andy
🌐
CMake Discourse
discourse.cmake.org › code
static and dynamic libraries, single compile - Code - CMake Discourse
February 28, 2021 - I am very new to cmake. I am not new to build systems. I have maintained signficant ones. I have a very custom build system. Very declarative, and embeds a little custom scripting language as an escape hatch. Nice b…
🌐
Alexreinking
alexreinking.com › blog › building-a-dual-shared-and-static-library-with-cmake.html
Building a Dual Shared and Static Library with CMake
March 6, 2021 - The core issue is that a CMake library target models the build and usage requirements for a single library configuration. When you import SomeLib::SomeLib from a package, the library type is already determined by the time you link another target to it. On the build side, this means that a single library target corresponds to a single physical library on the system. Static and shared libraries are typically produced from the same set of sources, too, so new CMake users sometimes expect that a single call to add_library will provide whatever mix of types they want.
🌐
CMake Discourse
discourse.cmake.org › code
How to statically link external library by target_link_libraries()? - Code - CMake Discourse
August 18, 2020 - I am trying to achieve the equivalent of following command by CMake. gcc -static -O0 -g main.c /usr/lib/x86_64-linux-gnu/libpthread.a My cmake script successfully built executable file, but gave segmentation fault at r…
🌐
CMake
cmake.org › cmake › help › latest › command › target_link_libraries.html
target_link_libraries — CMake 4.3.0-rc3 Documentation
compiles static3.c with -DOBJ3 and creates libstatic3.a using only its own object file. use_static3.c is compiled without -DOBJ3 because the usage requirement is not transitive through the private dependency of static3. However, the link dependencies of static3 are propagated, including the iface_obj3 reference to $<TARGET_OBJECTS:obj3>. The use_static3 executable is created with object files from use_static3.c and obj3.c, and linked to library libstatic3.a.
🌐
NVIDIA Developer Forums
forums.developer.nvidia.com › accelerated computing › cuda › cuda programming and performance
CMake link to Static library - CUDA Programming and Performance - NVIDIA Developer Forums
February 22, 2024 - I have a static library that contains some helper __device__ functions that will be consumed by several other projects. I have looked online and so far the best I discern is that to do this you need to set both CUDA_SEPARABLE_COMPILATION and CUDA_RESOLVE_DEVICE_SYMBOLS to ON to enable device linking.