【发布时间】:2011-06-18 06:35:26
【问题描述】:
标题大多涵盖了它,模块和共享库有什么区别?我刚刚在 CMake 的 add_library 命令中发现了这种区别,他们说:
SHARED 库是动态链接的,并在运行时加载。 MODULE 库是不链接到其他目标但可以在运行时使用类似 dlopen 的功能动态加载的插件。
但是我可以使用 dlopen() 加载共享对象,不是吗?
【问题讨论】:
标签: module linker shared-libraries cmake
标题大多涵盖了它,模块和共享库有什么区别?我刚刚在 CMake 的 add_library 命令中发现了这种区别,他们说:
SHARED 库是动态链接的,并在运行时加载。 MODULE 库是不链接到其他目标但可以在运行时使用类似 dlopen 的功能动态加载的插件。
但是我可以使用 dlopen() 加载共享对象,不是吗?
【问题讨论】:
标签: module linker shared-libraries cmake
不同之处在于您可以使用链接器链接到 SHARED 库,但不能使用链接器链接到 MODULE。在一些平台上。
所以...要完全跨平台并在 CMake 工作的任何地方工作,你永远不应该这样做:
# This is a big NO-NO:
add_library(mylib MODULE ${srcs})
target_link_libraries(myexe mylib)
公平地说,在 Windows 上,它们都只是 dll,因此这段代码可能确实有效。但是当你把它带到一个无法链接到 MODULE 的平台上时,你会遇到一个错误。
底线:如果您需要链接到库,请使用 SHARED。如果您保证库将仅动态加载,那么使用 MODULE 是安全的。 (也许更可取的是帮助检测是否有人确实尝试链接到它...)
【讨论】:
我认为区别在于共享库是由开发人员在编译时指定的,并且必须存在才能让应用程序运行,即使它们的方法是在运行时加载的。一个模块,即插件,在运行时添加了额外的支持,但不是必需的。是的,您可以 dlopen() 共享库,但在这种情况下,它不会被指定为程序和函数的必需部分,而是作为模块。
【讨论】:
另一个区别是..._OUTPUT_DIRECTORY 和..._OUTPUT_NAME 的处理方式:
模块库始终被视为库目标。对于非 DLL 平台,共享库被视为库目标。对于 DLL 平台,共享库的 DLL 部分被视为运行时目标,相应的导入库被视为存档目标。包括 Cygwin 在内的所有基于 Windows 的系统都是 DLL 平台。
例如,这意味着如果您在 Windows 上编译 SHARED 库,LIBRARY_OUTPUT_DIRECTORY 将被忽略,因为它正在查看 ARCHIVE_OUTPUT_DIRECTORY 和 RUNTIME_OUTPUT_DIRECTORY。
【讨论】: