【问题标题】:CMake link shared library on WindowsWindows 上的 CMake 链接共享库
【发布时间】:2016-01-08 20:18:41
【问题描述】:

共有三个文件,(m.cm.h和**main.c*)。

文件 m.h

// m.h
int m();

文件m.c

// m.c
#include <stdio.h>
#include "m.h"

int m(){
    printf("Hello,m!\n");
    return 0;
}

文件 main.c

// main.c
#include "m.h"
int main(){
    return m();
}

虽然我更喜欢共享库 (m.dll),但我制作了 CMakeLists.txt 文件:

    PROJECT("app1")
    ADD_LIBRARY(m SHARED m.c)
    ADD_EXECUTABLE(myexe main.c)
    TARGET_LINK_LIBRARIES(myexe m)

CMake 配置完成并生成完成。打开 app1.sln 并使用 Visual Studio 构建,它崩溃为

LNK1104:Can't open file "Debug\m.lib"

它只能在ADD_LIBRARY() 用作STATIC。为什么它不能在 Windows 上运行?

如果我有另一个共享库 (mylib.dll),我如何在我的 main.c 和 CMakeLists.txt 文件中调用它的函数?

【问题讨论】:

  • It always crashes - 什么崩溃了? CMake 配置步骤(cmake.exe 调用),构建步骤(顺便说一句,您使用什么工具进行构建?Visual Studio?Make?)或运行可执行文件?这次崩溃会出现什么错误消息?
  • CMakeLists.txt 在 Ubuntu-14.04 上运行良好。 libm.so 已生成。
  • @llorch 欢迎使用 StackOverflow。只需查看对代码的修改,您就可以实现它。请参阅下面的答案。

标签: windows build cmake


【解决方案1】:

不同平台上的动态库链接存在差异,也需要一些额外的代码。好消息是,CMake 可以帮助您解决这个问题。我发现Gernot Klingler 的以下博文非常有用:

简而言之,您需要为m.h 中声明的任何内容定义一些“导出前缀”。否则,构建过程将不会为名为 m.lib 的静态链接生成“导入库”(另请参见 CMAKE_IMPORT_LIBRARY_SUFFIX)。

这是您的代码,需要进行修改:

m.h

#include "m_exports.h"

int M_EXPORTS m();

m.c

#include "m.h"
#include <stdio.h>

int m(){
    printf("Hello,m!\n");
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)

include(GenerateExportHeader)

PROJECT("app1")

INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}")
ADD_LIBRARY(m SHARED m.c m.h m_exports.h)
GENERATE_EXPORT_HEADER(m           
    BASE_NAME m
    EXPORT_MACRO_NAME M_EXPORTS
    EXPORT_FILE_NAME m_exports.h
    STATIC_DEFINE SHARED_EXPORTS_BUILT_AS_STATIC)

ADD_EXECUTABLE(myexe main.c)
TARGET_LINK_LIBRARIES(myexe m)

其他参考资料

【讨论】:

  • CMAKE_IMPORT_LIBRARY_SUFFIX 帮助了。谢谢。
  • @Florian 这是否意味着如果我有多个共享库,我必须为每个库创建多个 xxx_exports.h。另外,windows上带有cmake的静态库呢?
【解决方案2】:

使用WINDOWS_EXPORT_ALL_SYMBOLS 可能会有所帮助。有关详细信息,请参阅an introductory article。简而言之,像这样调用 CMake:

cmake -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE -DBUILD_SHARED_LIBS=TRUE

【讨论】:

    【解决方案3】:

    将此添加到CMakeLists.txt

    if(MSVC)
        set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
        set(BUILD_SHARED_LIBS TRUE)
    endif()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-29
      • 1970-01-01
      • 1970-01-01
      • 2021-07-25
      • 2023-03-10
      相关资源
      最近更新 更多