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"
它仅作为 STATIC 在 ADD_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)
其他参考资料
- GenerateExportHeader宏
- cmake and GenerateExportHeader
- How do I get CMake to create a dll and its matching lib file?
- MSDN:Walkthrough: Creating and Using a Dynamic Link Library (C++)
使用 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()
一共有三个文件,(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"
它仅作为 STATIC 在 ADD_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)
其他参考资料
- GenerateExportHeader宏
- cmake and GenerateExportHeader
- How do I get CMake to create a dll and its matching lib file?
- MSDN:Walkthrough: Creating and Using a Dynamic Link Library (C++)
使用 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()