【问题标题】:Compiling a static executable with CMake使用 CMake 编译静态可执行文件
【发布时间】:2014-08-30 03:57:09
【问题描述】:

对于一个项目,我需要创建一个包含我使用的所有库(opencv、cgal)的可执行文件,以便在没有这些库的计算机上执行它。目前,这是我的 CMakeLists.txt(我使用 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})

以这种方式,只有 GMP 和其他一些 c++ 库包含在我的可执行文件中。我的问题是:如何创建一个生成文件以便以静态方式自动包含所有库并仅创建一个包含所有库的“大”可执行文件?你能帮帮我吗?

【问题讨论】:

  • 您不应该使用file(GLOB ...) 来收集源文件,当您添加新文件时它将无法正常工作。你的问题是什么也很不清楚。 add_library(IMPORTED) 调用也没有做任何事情。
  • 我需要创建一个包含所有库(opencv、cgal 和所有常见 c++ 库)的可执行文件,以便在未安装 Opencv 或 CGAL 或其他 C++ 库的其他计算机上执行可执行文件.
  • 首先您需要确保您所依赖的所有库都是静态构建的。通常情况并非如此。之后,您需要确保您的 find_package 调用找到那些静态库。
  • 是的,我知道,我的问题是:如何包含 .a 文件。
  • 安德烈亚,你的问题到底是什么?在您的帖子中,唯一的问题是“您能帮帮我吗?”。您应该编辑您的帖子,并至少描述您迄今为止测试的内容有哪些问题。

标签: c++ opencv compilation cmake cgal


【解决方案1】:

作为全局 CMake 设置,在 add_executable 之前添加这些行,对 gcc/clang 有效:

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

Modern CMake (3.x+ - target_link_libraries doc) 上,您可以通过以下方式将标志应用于特定目标:

target_link_libraries(your_target_name -static)

如果您使用 MSVC,则必须设置编译器和链接器标志:

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)

如果您使用的是 MFC,则需要将标志指定为 1 see here

 set(CMAKE_MFC_FLAG 1) 

【讨论】:

  • @Royi 对于 MSVC,您应该使用标志 /MT /INCREMENTAL:NO /NODEFAULTLIB:MSVCRT。 Xcode 使用 clang,你只需要 -static 标志
  • 在 Windows 上:SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.dll.a")
  • target_link_libraries(your_target_name -static) 这太棒了!
  • 这里是一个一般的 CMake 问题。 CMake 的设计理念是它可以跨 GNU Make 和 MSVC 移植。那么为什么我们需要使用不同的 CMake 指令(除此之外可能还有平台检测预测)才能完成它的工作?
  • @StevenLu 因为编译器没有标准化,每个供应商都有自己的选择
【解决方案2】:

add_executable(MyExec "main.c")之后添加这些行(例如):

target_link_libraries(MyExec PUBLIC "-static")

或之前:link_libraries("-static")

【讨论】:

    猜你喜欢
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 2011-03-18
    • 1970-01-01
    相关资源
    最近更新 更多