41

for a project I need to create an executable that includes all the libraries that I used (opencv, cgal) in order to execute it on a computer that has not those libraries. Currently, this is my CMakeLists.txt (I use linux).

cmake_minimum_required(VERSION 2.8)
#set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -O2")
project( labeling )
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
add_library(OpenCV STATIC IMPORTED)
add_library(CGAL STATIC IMPORTED COMPONENTS Core)
add_library(GMP STATIC IMPORTED)
find_package(OpenCV REQUIRED)
find_package(CGAL QUIET COMPONENTS Core )
find_library(GMP_LIBRARY gmp /usr/lib)

include(src)
include( ${CGAL_USE_FILE} )
include( CGAL_CreateSingleSourceCGALProgram )


set(EXECUTABLE_OUTPUT_PATH ../bin)
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")

include_directories( src )
include_directories( ${OpenCV_INCLUDE_DIRS} )

file(GLOB_RECURSE nei_SRC "src/*.cpp")
add_executable( nei_segmentation ${nei_SRC})
target_link_libraries( nei_segmentation ${OpenCV_LIBS} ${GMP_LIBRARY})

In such a way only GMP and some other c++ libraries are included in my executable. My question is: How can I create a makefile in order to automatically including all the libraries in a static manner and creating only a "big" executable that contains all the libraries? Can you help me?

Andrea
  • 1,597
  • 3
  • 18
  • 24
  • You should not use `file(GLOB ...)` to collect source files it will not work correctly when you add new files. It's also very unclear what your problem is. The `add_library(IMPORTED)` calls are also not doing anything. – pmr Jul 09 '14 at 08:20
  • I need to create an executable that includes all the libraries (opencv, cgal and all the common c++ libraries) in order to execute the executable in other computer where Opencv or CGAL or other C++ libraries are not installed. – Andrea Jul 09 '14 at 08:36
  • 1
    First you need to make sure that all libraries you depend on are built statically. This is often not the case. After that you need to make sure that your `find_package` calls find those static libraries. – pmr Jul 09 '14 at 09:46
  • Yes, I know this, my problem is: how to include the .a files. – Andrea Jul 09 '14 at 10:46
  • 1
    Andrea, what is your question exactly? In your post, the only question is "Can you help me?". You should edit your post, and at least describe what are the issues with what your have tested so far. – lrineau Jul 10 '14 at 07:45

2 Answers2

68

As global CMake settings, add these lines before add_executable, valid for gcc/clang:

set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXE_LINKER_FLAGS "-static")

On Modern CMake (3.x+ - target_link_libraries doc), you can apply the flag to specific targets, in this way:

target_link_libraries(your_target_name -static)

If you're using MSVC, you have to set the compiler and linker flags:

set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
target_compile_options(your_target_name [PUBLIC|PRIVATE] /MT)
target_link_options(your_target_name [PUBLIC|PRIVATE] /INCREMENTAL:NO /NODEFAULTLIB:MSVCRT)

or alternatively also:

set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")

and if you are using MFC, you need to specify the flag to 1 see here:

set(CMAKE_MFC_FLAG 1) 
madduci
  • 2,635
  • 1
  • 32
  • 51
  • @Royi for MSVC you should use the flags /MT /INCREMENTAL:NO /NODEFAULTLIB:MSVCRT. Xcode uses clang, thant the -static flag is all you need – madduci Sep 16 '19 at 11:36
  • 1
    On Windows: SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.dll.a") – satnhak Jun 05 '20 at 13:25
  • 1
    ```target_link_libraries(your_target_name -static)``` this is awesome! – Hack06 Jul 18 '20 at 14:22
  • A general CMake question here. CMake's design philosophy is that it is portable across GNU Make and MSVC. Why then would we need to use different CMake directives (and presumably platform detection predication in addition to that) in order for it to do its job? – Steven Lu Aug 01 '21 at 02:47
  • @StevenLu because the compilers aren't standardized and every vendor makes its choices – madduci Aug 05 '21 at 07:36
  • 1
    instead of using `target_compile_options(your_target_name [PUBLIC|PRIVATE] /MT)`, it is probably better to use the MSVC_RUNTIME_LIBRARY property – yakoudbz Apr 12 '22 at 14:48
4

Add these lines after add_executable(MyExec "main.c") (for example) :

target_link_libraries(MyExec PUBLIC "-static")

or before: link_libraries("-static")

koppor
  • 19,079
  • 15
  • 119
  • 161
Logicae
  • 49
  • 2