导入对象¶
在 3.9 版本加入.
imported object library 的磁盘上对象文件的绝对路径的分号分隔列表 <CMake Language Lists>。
忽略非导入目标。
如果设置了特定于配置的属性 IMPORTED_OBJECTS_<CONFIG>,项目可能会跳过 IMPORTED_OBJECTS,除非在以下部分中提到的情况。
Xcode 生成器注意事项¶
在 3.20 版本加入.
对于 Apple 平台,一个项目可能会针对多个架构构建。这是由 CMAKE_OSX_ARCHITECTURES 变量控制的。除了 Xcode 生成器之外,CMake 为每个源文件调用一次编译器并传递多个 -arch 标志,导致一个单一的目标文件,这将是一个通用的二进制文件。当在单独的 CMake 构建的 IMPORTED_OBJECTS 中列出时,此类目标文件可以很好地工作,即使对于 Xcode 生成器也是如此。但是使用 Xcode 生成器生成这样的目标文件更加困难,因为它为每个源文件的每个体系结构调用一次编译器。与其他生成器不同,它不生成通用目标文件二进制文件。
Xcode 生成器的另一个复杂之处在于,当针对设备平台(iOS、tvOS 或 watchOS)时, Xcode 生成器能够使用设备或模拟器 SDK,而无需 CMake重新运行。可以在构建时选择 SDK。但是由于设备和模拟器 SDK 都可以支持某些架构(例如 Xcode 12 或更高版本的“arm64”),因此并非所有组合都可以用一个通用二进制文件表示。在这种情况下唯一的解决方案是拥有多个目标文件。
IMPORTED_OBJECTS 不支持生成器表达式,因此它列出的每个文件都需要对每个架构和 SDK 有效。如果包含不是通用二进制文件的目标文件,则每个目标文件的路径和/或文件名必须以某种方式封装不同的体系结构和 SDK。使用 Xcode 生成器,形式为 $(...) 的 Xcode 变量可用于表示这些方面,Xcode 将在构建时替换适当的值。 CMake 不解释这些变量并将它们原封不动地嵌入到 Xcode 项目文件中。 $(CURRENT_ARCH) 可用于表示架构,而 $(EFFECTIVE_PLATFORM_NAME) 可用于区分 SDK。
下面显示了一个示例,说明如何使用这两个变量来引用其位置取决于 SDK 和体系结构的目标文件:
add_library(someObjs OBJECT IMPORTED)
set_property(TARGET someObjs PROPERTY IMPORTED_OBJECTS
# Quotes are required because of the ()
"/path/to/somewhere/objects$(EFFECTIVE_PLATFORM_NAME)/$(CURRENT_ARCH)/func.o"
)
# Example paths:
# /path/to/somewhere/objects-iphoneos/arm64/func.o
# /path/to/somewhere/objects-iphonesimulator/x86_64/func.o
在某些情况下,您可能还希望拥有特定于配置的目标文件。 $(CONFIGURATION) Xcode 变量通常用于此,并且可以与上面提到的其他变量结合使用:
add_library(someObjs OBJECT IMPORTED)
set_property(TARGET someObjs PROPERTY IMPORTED_OBJECTS
"/path/to/somewhere/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/$(CURRENT_ARCH)/func.o"
)
# Example paths:
# /path/to/somewhere/Release-iphoneos/arm64/func.o
# /path/to/somewhere/Debug-iphonesimulator/x86_64/func.o
当使用任何 Xcode 变量时,CMake 无法在配置时完全评估路径。这样做的一个后果是无法使用特定于配置的 IMPORTED_OBJECTS_<CONFIG> 属性,因为 CMake 无法确定目标文件是否存在于特定的 <CONFIG> 位置。 IMPORTED_OBJECTS 属性必须用于这些情况,路径的配置特定方面应由 $(CONFIGURATION) Xcode 变量处理。