Skip to content
Advertisement

Deplying a C++ application on Linux- linking everything statically to simplify deployment?

I am building a C++ project from Github and want to deploy the code to a remote Linux machine. This is all new to me.

The project has a main.cpp, which includes the various headers/sources like a library.

The CMake outputs an executable (to represent main.cpp) AND a separate static library. The project also uses OpenSSL, which I have linked statically.

  1. I presume the OpenSSL functions are included within the static library? So when I deploy, I don’t need to copy-over or install any OpenSSL on the remote machine?

  2. Is it possible to modify the CMake so the application and the library are merged in to one file?

I am trying to make deployment as simple as copying over a single file, if this is possible.

Any additional advice/references are most-welcome.

UPDATE the CMake script:

cmake_minimum_required(VERSION 3.20)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake;${CMAKE_MODULE_PATH}")

project(helloworld C CXX)

set (CMAKE_CXX_STANDARD 20)
set (CMAKE_BUILD_TYPE Release)

set (BUILD_MAIN TRUE)
set (BUILD_SHARED_LIBS FALSE)
set (OPENSSL_USE_STATIC_LIBS TRUE)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

set( HELLOWORLD_HEADERS    helloworld/File1.h       helloworld/File2.h    )
set( HELLOWORLD_SOURCES    helloworld/File1.cpp     helloworld/File2.cpp  )

# Static library
add_library( helloworld  ${HELLOWORLD_SOURCES}    ${HELLOWORLD_HEADERS}   )

# Rapidjson
include_directories(/tmp/rapidjson/include/)


# OpenSSL
if (NOT OPENSSL_FOUND)
  find_package(OpenSSL REQUIRED)
endif()

add_definitions(${OPENSSL_DEFINITIONS})

target_include_directories(helloworld PUBLIC $<BUILD_INTERFACE:${OPENSSL_INCLUDE_DIR}>)
target_link_libraries(helloworld PRIVATE ${OPENSSL_LIBRARIES})

set( HELLOWORLD_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})

include(GNUInstallDirs)

target_include_directories(helloworld PUBLIC
  $<BUILD_INTERFACE:${HELLOWORLD_INCLUDE_DIRS}/>
  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/helloworld>
)

set_target_properties(helloworld PROPERTIES PUBLIC_HEADER "${HELLOWORLD_HEADERS}")

add_library(helloworld::helloworld ALIAS helloworld)

option(HELLOWORLD_INSTALL "Install HelloWorld" TRUE)

if (HELLOWORLD_INSTALL)
  install(TARGETS helloworld
          EXPORT helloworld
          ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
          PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/helloworld/
  )

  configure_file("${CMAKE_CURRENT_LIST_DIR}/helloworld-config.cmake.in" "${CMAKE_BINARY_DIR}/helloworld-config.cmake" @ONLY)
  install(FILES "${CMAKE_BINARY_DIR}/helloworld-config.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/helloworld")
  
  install(EXPORT helloworld
          FILE helloworld-targets.cmake
          NAMESPACE helloworld::
          DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/helloworld
  )
endif()


if (BUILD_MAIN) 
  add_executable(main main.cpp)
  target_link_libraries(main helloworld) 
endif()

Advertisement

Answer

ITNOA

I it is very helpful to make URL of your GitHub’s project, but I write some public notes about that

In generally in CMake for static linking your library to your executable, you can write simple like below (from official CMake example)

add_library(archive archive.cpp zip.cpp lzma.cpp)
add_executable(zipapp zipapp.cpp)
target_link_libraries(zipapp archive)

In above example your executable file is just work without needing .a library file and you can simple copy single file.

if you want to make all of thing static, you make sure all dependencies make static link to your project, like CMake: how to produce binaries “as static as possible”

if you want to prevent library creation, Probably in your CMake file, you can find add_library command, and add_executable command. you can remove add_library command and add all sources to add_executable command.

for example add_executable(a.out main.cpp lib.cpp)

2 People found this is helpful
Advertisement