cmake Visual Studio 嵌套共享库子项目
cmake Visual Studio nested shared library subproject
概览
- 我想使用共享库 XMMathLib 编译项目 CalcMod。
- 两者都应作为项目加载到 Visual Studio 中(即在解决方案资源管理器中,应该有一个 CalcMod 树和一个 XMMathLib 树)。因此,在 CalcMod 中嵌套 XMMathLib(并用
add_subdirectory()
添加它)似乎是合适的解决方案。
- 此外,最终,我们希望将 XMMathLib 导出为(共享)dll 库,因此我们调用
add_library(XMMathLib SHARED […])
。
- 但是,这会在编译结束时触发
cannot open file 'XMMathLib\Debug\XMMathLib.lib'
错误。
确实,文件夹build\XMMathLib\Debug\
包含XMMathLib.dll
、XMMathLib.ilk
和XMMathLib.pdb
,这与我要求为XMMathLib生成共享库一致。但是,为什么 CalcMod 会寻找静态库文件 XMMathLib.lib
?!
详情
项目的组织方式如下:
|- build
|- src
|- CalcMod
| |- src
| |- main.cpp
|- XMMathLib
| |- src
| | |- Demo.cpp
| | |- Demo.h
| |- CMakeLists.txt
|- CMakeLists.txt
这里是每个文件的内容:
src/CMakeLists.txt
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(CalcMod CXX)
set(CMAKE_CXX_STANDARD 14)
add_subdirectory(XMMathLib)
file(GLOB_RECURSE SOURCES_CALCMOD "CalcMod/src/*.cpp")
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES_CALCMOD})
add_executable(
CalcMod
${SOURCES_CALCMOD}
)
target_link_libraries(
CalcMod
XMMathLib
)
target_include_directories(CalcMod PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
src/XMMathLib/CMakeLists.txt
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(XMMathLib CXX)
file(GLOB_RECURSE SOURCES "src/*.cpp")
add_library(XMMathLib SHARED ${SOURCES})
target_link_libraries(
XMMathLib
)
src/CalcMod/src/main.cpp
#include <iostream>
#include "XMMathLib/src/Demo.h"
int main()
{
RunDemo();
}
src/XMMathLib/src/Demo.cpp
#include <iostream>
void RunDemo()
{
std::cout << "hello" << std::endl;
}
src/XMMathLib/src/Demo.h
#pragma once
void __declspec(dllexport) RunDemo();
cmake 参数:
- Visual Studio 2017
- 平台:Win32
- Windows SDK 10.0.19041.0
非常感谢大家帮助我,尤其是 drescherjm!
下面是我最初损坏的代码的固定变体:
|- build
|- src
|- CalcMod
| |- src
| |- main.cpp
|- XMMathLib
| |- src
| | |- Demo.cpp
| | |- Demo.h
| | |- DllExport.h
| |- CMakeLists.txt
|- CMakeLists.txt
这里是每个文件的内容:
src/CMakeLists.txt
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(CalcMod CXX)
set(CMAKE_CXX_STANDARD 14)
add_subdirectory(XMMathLib) # Call XMMathLib's CMakeLists.txt
file(GLOB_RECURSE SOURCES_CALCMOD "CalcMod/src/*.cpp" "CalcMod/src/*.h" "CalcMod/src/*.hpp") # Files to compile. Also all the files that will appear in VS's Solution Explorer (that's why we include the headers here).
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES_CALCMOD}) # So that source files appear in Solution Explorer as a tree reproducing their actual location
add_executable( # Ask VS to generate a CalcMod.exe executable as output
CalcMod
${SOURCES_CALCMOD}
)
target_link_libraries( # Tell VS's linker to link with XMMathLib.dll
CalcMod
PUBLIC XMMathLib
# PRIVATE: CalcMod uses XMMathLib and noone else
# INTERFACE: CalcMod does not use XMMathLib but makes it available to others
# PUBLIC: CalcMod uses XMMathLib *and* makes it available to others.
)
target_include_directories(CalcMod PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # Add include directories (ie gcc's -I option)
# We want to copy XMMathLib.dll at the same location than CalcMod.exe, otherwise it won't run because it won't find it.
# Option #1: Copy the dlls of all the dependent libraries (only XMMathLib in this case) to where CalcMod.exe is
# Pros: Only copy the useful files (ie the *.dll) leaving behind eg the *.ilk and *.exp
# No need to specify explicitly all dependent libraries
# Cons: Does not copy the *.pdb which is required by the debuger (contains the debug symbols)
# Copy eg XMMathLib.dll from `build\XMMathLib\Debug` to `build\Debug
#add_custom_command(TARGET CalcMod POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:CalcMod> $<TARGET_FILE_DIR:CalcMod>
# COMMAND_EXPAND_LISTS
# )
# Option #2: Copy all the output files (*.dll, *.pdb, *.ilk, *.exp) generated by XMMathLib where CalcMod.exe
# Pros: Copies *.pdb which is required by the debbuger (contains the debug symbols)
# Cons: Have to manually list all the dependent libraries explicitly (only one in this case: XMMathLib)
# Also copies *.ilk and *.exp which are used for building/linking but are just bloat after that.
add_custom_command(TARGET CalcMod POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory $<TARGET_FILE_DIR:XMMathLib> $<TARGET_FILE_DIR:CalcMod>
COMMAND_EXPAND_LISTS
)
src/XMMathLib/CMakeLists.txt
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(XMMathLib CXX)
file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.hpp" "src/*.h") # List sources to use in build
add_compile_definitions(XMMATHLIB_EXPORTS) # When defined, export.h will use __declspec(dllexport)
add_library(XMMathLib SHARED ${SOURCES}) # Ask VS to build XMMathLib.dll
target_link_libraries( # Tell VS's linker to link with libraries. Actually unnecessary here (no library linked)
XMMathLib
)
src/CalcMod/src/main.cpp
#include <iostream>
#include "XMMathLib/src/Demo.h"
int main()
{
RunDemo();
}
src/XMMathLib/src/Demo.cpp
#include <iostream>
#include "Demo.h" // We need to include Demo.h, otherwise VS won't see __declspec(dllexport) for RunDemo() and won't export the function
void RunDemo()
{
std::cout << "hello" << std::endl;
}
src/XMMathLib/src/Demo.h
#include "DllExport.h"
void XMMATHLIB_DLLEXPORT RunDemo();
src/XMMathLib/src/DllExport.h
#pragma once
// Tells VS whether to specify the functions and classes marked with XMMATHLIB_DLLEXPORT
// as to be exported in the *.lib that accompanies the *.dll or not.
// If no class or function is marked with __declspec(dllexport), then XMMathLib.lib won't be generated.
#if XMMATHLIB_EXPORTS
#define XMMATHLIB_DLLEXPORT __declspec(dllexport)
#else
#define XMMATHLIB_DLLEXPORT __declspec(dllimport)
#endif
cmake 参数:
- Visual Studio 2017
- 平台:Win32
- Windows SDK 10.0.19041.0
概览
- 我想使用共享库 XMMathLib 编译项目 CalcMod。
- 两者都应作为项目加载到 Visual Studio 中(即在解决方案资源管理器中,应该有一个 CalcMod 树和一个 XMMathLib 树)。因此,在 CalcMod 中嵌套 XMMathLib(并用
add_subdirectory()
添加它)似乎是合适的解决方案。 - 此外,最终,我们希望将 XMMathLib 导出为(共享)dll 库,因此我们调用
add_library(XMMathLib SHARED […])
。 - 但是,这会在编译结束时触发
cannot open file 'XMMathLib\Debug\XMMathLib.lib'
错误。
确实,文件夹build\XMMathLib\Debug\
包含XMMathLib.dll
、XMMathLib.ilk
和XMMathLib.pdb
,这与我要求为XMMathLib生成共享库一致。但是,为什么 CalcMod 会寻找静态库文件XMMathLib.lib
?!
详情
项目的组织方式如下:
|- build
|- src
|- CalcMod
| |- src
| |- main.cpp
|- XMMathLib
| |- src
| | |- Demo.cpp
| | |- Demo.h
| |- CMakeLists.txt
|- CMakeLists.txt
这里是每个文件的内容:
src/CMakeLists.txt
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(CalcMod CXX)
set(CMAKE_CXX_STANDARD 14)
add_subdirectory(XMMathLib)
file(GLOB_RECURSE SOURCES_CALCMOD "CalcMod/src/*.cpp")
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES_CALCMOD})
add_executable(
CalcMod
${SOURCES_CALCMOD}
)
target_link_libraries(
CalcMod
XMMathLib
)
target_include_directories(CalcMod PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
src/XMMathLib/CMakeLists.txt
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(XMMathLib CXX)
file(GLOB_RECURSE SOURCES "src/*.cpp")
add_library(XMMathLib SHARED ${SOURCES})
target_link_libraries(
XMMathLib
)
src/CalcMod/src/main.cpp
#include <iostream>
#include "XMMathLib/src/Demo.h"
int main()
{
RunDemo();
}
src/XMMathLib/src/Demo.cpp
#include <iostream>
void RunDemo()
{
std::cout << "hello" << std::endl;
}
src/XMMathLib/src/Demo.h
#pragma once
void __declspec(dllexport) RunDemo();
cmake 参数:
- Visual Studio 2017
- 平台:Win32
- Windows SDK 10.0.19041.0
非常感谢大家帮助我,尤其是 drescherjm!
下面是我最初损坏的代码的固定变体:
|- build
|- src
|- CalcMod
| |- src
| |- main.cpp
|- XMMathLib
| |- src
| | |- Demo.cpp
| | |- Demo.h
| | |- DllExport.h
| |- CMakeLists.txt
|- CMakeLists.txt
这里是每个文件的内容:
src/CMakeLists.txt
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(CalcMod CXX)
set(CMAKE_CXX_STANDARD 14)
add_subdirectory(XMMathLib) # Call XMMathLib's CMakeLists.txt
file(GLOB_RECURSE SOURCES_CALCMOD "CalcMod/src/*.cpp" "CalcMod/src/*.h" "CalcMod/src/*.hpp") # Files to compile. Also all the files that will appear in VS's Solution Explorer (that's why we include the headers here).
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCES_CALCMOD}) # So that source files appear in Solution Explorer as a tree reproducing their actual location
add_executable( # Ask VS to generate a CalcMod.exe executable as output
CalcMod
${SOURCES_CALCMOD}
)
target_link_libraries( # Tell VS's linker to link with XMMathLib.dll
CalcMod
PUBLIC XMMathLib
# PRIVATE: CalcMod uses XMMathLib and noone else
# INTERFACE: CalcMod does not use XMMathLib but makes it available to others
# PUBLIC: CalcMod uses XMMathLib *and* makes it available to others.
)
target_include_directories(CalcMod PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) # Add include directories (ie gcc's -I option)
# We want to copy XMMathLib.dll at the same location than CalcMod.exe, otherwise it won't run because it won't find it.
# Option #1: Copy the dlls of all the dependent libraries (only XMMathLib in this case) to where CalcMod.exe is
# Pros: Only copy the useful files (ie the *.dll) leaving behind eg the *.ilk and *.exp
# No need to specify explicitly all dependent libraries
# Cons: Does not copy the *.pdb which is required by the debuger (contains the debug symbols)
# Copy eg XMMathLib.dll from `build\XMMathLib\Debug` to `build\Debug
#add_custom_command(TARGET CalcMod POST_BUILD
# COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:CalcMod> $<TARGET_FILE_DIR:CalcMod>
# COMMAND_EXPAND_LISTS
# )
# Option #2: Copy all the output files (*.dll, *.pdb, *.ilk, *.exp) generated by XMMathLib where CalcMod.exe
# Pros: Copies *.pdb which is required by the debbuger (contains the debug symbols)
# Cons: Have to manually list all the dependent libraries explicitly (only one in this case: XMMathLib)
# Also copies *.ilk and *.exp which are used for building/linking but are just bloat after that.
add_custom_command(TARGET CalcMod POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory $<TARGET_FILE_DIR:XMMathLib> $<TARGET_FILE_DIR:CalcMod>
COMMAND_EXPAND_LISTS
)
src/XMMathLib/CMakeLists.txt
cmake_minimum_required(VERSION 3.22 FATAL_ERROR)
project(XMMathLib CXX)
file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.hpp" "src/*.h") # List sources to use in build
add_compile_definitions(XMMATHLIB_EXPORTS) # When defined, export.h will use __declspec(dllexport)
add_library(XMMathLib SHARED ${SOURCES}) # Ask VS to build XMMathLib.dll
target_link_libraries( # Tell VS's linker to link with libraries. Actually unnecessary here (no library linked)
XMMathLib
)
src/CalcMod/src/main.cpp
#include <iostream>
#include "XMMathLib/src/Demo.h"
int main()
{
RunDemo();
}
src/XMMathLib/src/Demo.cpp
#include <iostream>
#include "Demo.h" // We need to include Demo.h, otherwise VS won't see __declspec(dllexport) for RunDemo() and won't export the function
void RunDemo()
{
std::cout << "hello" << std::endl;
}
src/XMMathLib/src/Demo.h
#include "DllExport.h"
void XMMATHLIB_DLLEXPORT RunDemo();
src/XMMathLib/src/DllExport.h
#pragma once
// Tells VS whether to specify the functions and classes marked with XMMATHLIB_DLLEXPORT
// as to be exported in the *.lib that accompanies the *.dll or not.
// If no class or function is marked with __declspec(dllexport), then XMMathLib.lib won't be generated.
#if XMMATHLIB_EXPORTS
#define XMMATHLIB_DLLEXPORT __declspec(dllexport)
#else
#define XMMATHLIB_DLLEXPORT __declspec(dllimport)
#endif
cmake 参数:
- Visual Studio 2017
- 平台:Win32
- Windows SDK 10.0.19041.0