【问题标题】:Getting CMake to build shared library for MSVC [duplicate]让 CMake 为 MSVC 构建共享库 [重复]
【发布时间】:2016-09-04 20:13:58
【问题描述】:

我一直在使用 CMake 在 unix 环境中构建 C 和 C++ 项目。但是,我也想开始在 MSVC 中编译,并且我试图了解 cmake 文档,但我遇到了困难。 当我尝试构建时,我不断收到以下消息。

LINK:致命错误 LNK1104:无法打开文件 'Debug\MyLibrary.lib' [C:\sandbox\projects\cpp\DummyChelloWorld\build\ma inProgram.vcxproj]

你能告诉我我做错了什么吗?

CMakeLists.txt

    cmake_minimum_required(VERSION 3.4)
    project(helloWorld)

    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
    include(GenerateExportHeader)

    ADD_LIBRARY(MyLibrary SHARED myShared.cpp)

    set(SOURCE_FILES main.cpp)

    GENERATE_EXPORT_HEADER( MyLibrary
                 BASE_NAME MyLibrary
                 EXPORT_MACRO_NAME MyLibrary_EXPORT
                 EXPORT_FILE_NAME ${CMAKE_BINARY_DIR}/MyLibrary_Export.h
                 STATIC_DEFINE MyLibrary_BUILT_AS_STATIC
            )

    add_executable(mainProgram ${SOURCE_FILES})
    TARGET_LINK_LIBRARIES(mainProgram MyLibrary)
    TARGET_INCLUDE_DIRECTORIES(mainProgram PUBLIC exports)

main.cpp

#include "myShared.h"

int main() {
  sayHI();
  return 0;
}

myShared.cpp

#include <iostream>
#include "myShared.h"

using namespace std;

void sayHI() {
  cout << "Hello World lib" << endl;
}

myShared.h

    #ifndef HELLOWORLD_HELLO_H
    #define HELLOWORLD_HELLO_H

    void sayHI();

    #endif //HELLOWORLD_HELLO_H

【问题讨论】:

  • TARGET_INCLUDE_DIRECTORIES(mainProgram PUBLIC exports}) - 我认为末尾有一个不需要的花括号。
  • 谢谢,很好,但这是一个复制和粘贴错误。我在我的帖子中更正了它。还是同样的问题。不过,对细节的大眼睛。
  • 文件可能被意外锁定。从干净的构建目录尝试。
  • 我主要使用 GCC/MinGW,所以使用 MSVC 对我来说是新的,所以感谢您向我提出任何愚蠢的问题。我是否需要使用我的所有库对“#include MyLibrary_Export.h”进行硬编码,是否需要将“MyLibrary_EXPORT”硬编码到我的标头中的所有函数以获取共享库以使用 MSVC 中的导出符号进行编译?跨度>
  • @loneraver 如果您使用 CMake 3.4 或更高版本,并且只想导出所有符号,则只需定义 CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS。完整的解决方案,请看下面我的回答。

标签: visual-c++ cmake


【解决方案1】:

把我的评论变成答案

对于 CMake 版本 >= 3.4

只需使用CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS:

cmake_minimum_required(VERSION 3.4)
project(helloWorld)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS 1)

add_library(MyLibrary SHARED myShared.cpp)

set(SOURCE_FILES main.cpp)
add_executable(mainProgram ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(mainProgram MyLibrary)

对于 CMake 版本

您需要将您的函数/符号声明为已导出。所以在你的情况下,你必须修改以下文件:

myShared.h

#ifndef HELLOWORLD_HELLO_H
#define HELLOWORLD_HELLO_H

#include "MyLibrary_Export.h"

void MyLibrary_EXPORT sayHI();

#endif //HELLOWORLD_HELLO_H

CMakeLists.txt

cmake_minimum_required(VERSION 3.4)
project(helloWorld)

set(CMAKE_CXX_STANDARD 11)
include(GenerateExportHeader)

add_library(
    MyLibrary 
    SHARED 
        myShared.cpp
        myShared.h
        MyLibrary_Export.h   
)
GENERATE_EXPORT_HEADER( 
    MyLibrary
    BASE_NAME MyLibrary
    EXPORT_MACRO_NAME MyLibrary_EXPORT
    EXPORT_FILE_NAME MyLibrary_Export.h
    STATIC_DEFINE MyLibrary_BUILT_AS_STATIC
)
target_include_directories(MyLibrary PUBLIC "${CMAKE_CURRENT_BINARY_DIR}")

set(SOURCE_FILES main.cpp)
add_executable(mainProgram ${SOURCE_FILES})
TARGET_LINK_LIBRARIES(mainProgram MyLibrary)

我已经

  1. 在你的函数声明中添加了MyLibrary_EXPORT
  2. CMAKE_CURRENT_BINARY_DIR 添加到共享库包含路径(指向生成的导出定义标头)
  3. 利用了更跨平台的CMAKE_CXX_STANDARD 定义。

替代方案

参考文献

【讨论】:

  • 有效!!!这解决了一切。我不能感谢你。这让我希望学习这些很棒的技巧变得容易得多。
猜你喜欢
  • 2011-01-10
  • 2016-04-30
  • 2017-01-25
  • 2016-12-30
  • 2015-08-18
  • 2016-02-16
  • 1970-01-01
相关资源
最近更新 更多