Windows 上的 CMake link 共享库

CMake link shared library on Windows

一共有三个文件,(m.c,m.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"

它仅作为 STATICADD_LIBRARY() 上工作。为什么它在 Windows 上不起作用?

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

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

简而言之,您需要为 m.h 中声明的内容定义一些 "export prefix"。否则,构建过程将不会为名为 m.lib 的静态链接生成 "import library"(另请参阅 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)

其他参考资料

使用 WINDOWS_EXPORT_ALL_SYMBOLS might help. See an introductory article 了解详情。简而言之,像这样调用 CMake:

cmake -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE -DBUILD_SHARED_LIBS=TRUE

将此添加到 CMakeLists.txt

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