Search code examples
cgitcmakestatic-librariesgit-submodules

Is it possible to create a statically linked library that includes git submodules in the archive file?


I am currently developing a graphics library in C that uses SDL2 along with other parts of their library ecosystem and would like to package the entire library into a single .a file for easy use after someone compiles it locally. I have included SDL2 and the other libraries (SDL-TTF, SDL-Mixer, and SDL-Image) into a folder called external, and they are added as git submodules into the project. I then add them as subdirectories in their respective CMakeLists.txt file (shown below) and link them in the root's CMakeLists.txt file and then statically build the library. However, the static library does not include the SDL dependencies and only includes my own code, so I wanted to ask if it is possible for me to bundle all of the SDL dependencies and my code into a single .a file with cmake.

CMakeLists.txt within the submodule folder called "external"

set( BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE )

# SDL
# https://github.com/libsdl-org/SDL
set( SDL_LIBC ON CACHE BOOL "" FORCE )
set( SDL_TEST OFF CACHE BOOL "" FORCE )
add_subdirectory(SDL)
target_link_libraries( Pixelinator SDL2::SDL2main SDL2::SDL2-static )

# SDL_image
# https://github.com/libsdl-org/SDL_image
set( SDL2IMAGE_SAMPLES OFF CACHE BOOL "" FORCE )
set( SDL2IMAGE_INSTALL OFF CACHE BOOL "" FORCE )
set( SDL2IMAGE_VENDORED ON CACHE BOOL "" FORCE )
set( SDL2IMAGE_DEPS_SHARED OFF CACHE BOOL "" FORCE )
add_subdirectory( sdl-image )
target_link_libraries( Pixelinator SDL2_image::SDL2_image-static)

# SDL_ttf
# https://github.com/libsdl-org/SDL_ttf
# Make sure you run ./download.sh in the directory.
set( SDL2TTF_SAMPLES OFF CACHE BOOL "" FORCE )
set( SDL2TTF_INSTALL OFF CACHE BOOL "" FORCE )
set( SDL2TTF_VENDORED ON CACHE BOOL "" FORCE )
set( SDL2TTF_HARFBUZZ ON CACHE BOOL "" FORCE )
add_subdirectory( sdl-ttf )
target_link_libraries( Pixelinator SDL2_ttf::SDL2_ttf-static )

# SDL_mixer
# https://github.com/libsdl-org/SDL_mixer
# Make sure you run ./download.sh in the directory.
set( SDL2MIXER_SAMPLES OFF CACHE BOOL "" FORCE )
set( SDL2MIXER_INSTALL OFF CACHE BOOL "" FORCE )
set( SDL2MIXER_VENDORED ON CACHE BOOL "" FORCE )
set( SDL2MIXER_DEPS_SHARED OFF CACHE BOOL "" FORCE )
set( SDL2MIXER_FLAC OFF CACHE BOOL "" FORCE )
set( SDL2MIXER_MOD OFF CACHE BOOL "" FORCE )
set( SDL2MIXER_MP3 OFF CACHE BOOL "" FORCE )
set( SDL2MIXER_MIDI OFF CACHE BOOL "" FORCE )
set( SDL2MIXER_OPUS OFF CACHE BOOL "" FORCE )
add_subdirectory( sdl-mixer )
target_link_libraries( Pixelinator SDL2_mixer::SDL2_mixer-static )

CMakeLists.txt within the root of the project for building the static library:

cmake_minimum_required(VERSION 3.21)
cmake_policy(SET CMP0075 NEW)
cmake_policy(SET CMP0091 NEW)
project(Pixelinator VERSION 1.0 DESCRIPTION "A 2D Engine using SDL and C")

set( CMAKE_CXX_STANDARD 11 CACHE STRING "" FORCE )
set( CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "" FORCE )

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

if(CMAKE_BUILD_TYPE EQUAL Release)
    message("Building Release...")
endif()

set(CMAKE_C_STANDARD 11)

set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast")

add_library(Pixelinator STATIC
        ../../Pixelinator/src/engine/audio/sound.c
        ../../Pixelinator/src/engine/config/config.c
        ../../Pixelinator/src/engine/core/core.c
        ../../Pixelinator/src/engine/graphics/bitmap/bitmap.c
        ../../Pixelinator/src/engine/graphics/bitmap/pixel_threading.c
        ../../Pixelinator/src/engine/graphics/sprite/sprite.c
        ../../Pixelinator/src/engine/graphics/draw/shapes.c
        ../../Pixelinator/src/engine/input/input.c
        ../../Pixelinator/src/engine/io/io.c
        ../../Pixelinator/src/engine/render/render.c
        ../../Pixelinator/src/engine/render/render_init.c
        ../../Pixelinator/src/engine/render/render_util.c
        ../../Pixelinator/src/engine/font_cache/SDL_FontCache.c
        ../../Pixelinator/src/engine/text/text.c
        ../../Pixelinator/src/engine/global.c
        ../../Pixelinator/src/engine/time.c

        # SDL (Not sure if needed)
        ../external/SDL
        ../external/sdl-image
        ../external/sdl-mixer
        ../external/sdl-ttf
)

set(APP_EXE PixelinatorDemo)

if( ${CMAKE_SYSTEM_NAME} MATCHES "Android" )
    add_library( ${APP_EXE} SHARED )
else()
    add_executable(${APP_EXE} main.c)
    set_target_properties( ${APP_EXE} PROPERTIES OUTPUT_NAME ${CMAKE_PROJECT_NAME} )
endif()

find_package(Threads REQUIRED)
if(THREADS_HAVE_PTHREAD_ARG)
    target_compile_options(${APP_EXE} PUBLIC "-pthread")
endif()
if(CMAKE_THREAD_LIBS_INIT)
    target_link_libraries(${APP_EXE} "${CMAKE_THREAD_LIBS_INIT}")
endif()

add_subdirectory("external")
add_subdirectory(glad/)
include_directories("include")
#target_link_libraries(Pixelinator SDL2::SDL2main SDL2::SDL2-static SDL2_image::SDL2_image-static SDL2_ttf::SDL2_ttf-static SDL2_mixer::SDL2_mixer-static)

# Library is generated inside of the cmake-build-debug or release folder!
target_link_libraries(${APP_EXE} glad Pixelinator)

Any help anyone can provide will be greatly appreciated!

EDIT: Fixed some spelling mistakes.


Solution

  • As written, for example, here Is it possible to create a statically linked library that includes git submodules in the archive file? you cannot statically link one static library to another.

    May be it would be simpler just add external sources to your library sources?

    execute_process(
        COMMAND bash "-c" "ls external/SDL_image/src/*.c;'" 
        OUTPUT_VARIABLE SDL_SOURCES
    )
    

    and after that

    add_library(Pixelinator STATIC
                # your sources:
                ....
                # external sources:
                ${SDL_SOURCES}
    )