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
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.

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
How do I tell CMake to link in a static library in the source directory? - Stack Overflow
Bring the best of human thought and AI automation together at your work. Explore Stack Internal ... I have a small project with a Makefile which I'm trying to convert to CMake, mostly just to get experience with CMake. For purposes of this example, the project contains a source file (C++, though I don't think the language is particularly relevant) and a static library ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
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.
🌐
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!
🌐
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 Documentation
In some contexts, fully static builds are appropriate, and in others shared libraries are desirable. ... CMake does not define the BUILD_SHARED_LIBS variable by default, meaning without project or user intervention add_library() will produce STATIC libraries.
🌐
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 ...
Find elsewhere
🌐
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
🌐
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, ...
🌐
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.

🌐
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...
🌐
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.org › cmake › help › latest › command › target_link_libraries.html
target_link_libraries — CMake 4.3.0 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.
🌐
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…
🌐
CMake
cmake.org › cmake › help › latest › prop_tgt › STATIC_LIBRARY_OPTIONS.html
STATIC_LIBRARY_OPTIONS — CMake 4.3.0-rc3 Documentation
See the cmake-buildsystem(7) manual for more on defining buildsystem properties. ... This property must be used in preference to STATIC_LIBRARY_FLAGS property.
🌐
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…