在我正在处理的多平台/操作系统项目中,我正在努力将特定于平台的代码简化为子目录,其中一个公共目录包含一个公共实现。我在 autotools 中有一个原型实现,但如果可能的话,我想转向 cmake 实现。我目前的症结是如何支持多个操作系统。我当前的文件系统结构如下所示:
/* A common header file for all platforms that presents an interface */
include/my_socket_utils.h
include/my_time_utils.h
/* Platform specific source files */
src/common/my_socket_utils.cpp
src/linux/my_socket_utils.cpp
src/vxworks/my_socket_utils.cpp
src/qnx/my_socket_utils.cpp
src/common/my_time_utils.cpp
src/vxworks/my_time_utils.cpp
Run Code Online (Sandbox Code Playgroud)
这个想法是有一个通用接口和一个“通用”实现。该实现要么是一个存根,要么是一个写到 posix 标准的通用实现,允许它在大多数平台上工作。那些需要自定义实现的平台可能会覆盖通用实现,但它是可选的。
使用 autotools,我可以使用 VPATH 设置源树层次结构来实现这一点,所以我设置:
VPATH=@srcdir@/src/@target_platform@;@srcdir@/src/common
Run Code Online (Sandbox Code Playgroud)
这使得自动工具首先在 src/@target_platform@ 中查找源文件,然后,如果没有找到,则从 src/common 中获取它。
执行此操作的 cmake 方法是什么?
更新:为了帮助所有需要帮助的迷失灵魂,这就是我暂时所做的事情。我不确定这是最好的解决方案,但它运行良好。
文件(GLOB common_files“src/common/ .c ”)文件(GLOB platform_files“src/${os}/. c)
然后,执行dirty n^2 算法来覆盖。不知道如何在 cmake "script" 中做得更好,但文件数量很少,所以速度很快。诊断消息当然是可选的。
#
# For each common file, check to see if a platform file exists to override it.
#
foreach(fqfn ${common_files})
set(platform_override FALSE)
get_filename_component(filename ${fqfn} NAME)
#
# If filename exists in platform, override it with the platform,
# otherwise fall back to the common implementation. Oh for a real
# language.
#
foreach(platform_fqfn ${platform_files})
get_filename_component(platform_filename ${platform_fqfn} NAME)
message("pf=${platform_filename} cf=${filename}")
if(filename STREQUAL platform_filename)
message("filename == platform_filename")
list(APPEND proj_files ${platform_fqfn})
set(platform_override TRUE)
endif(filename STREQUAL platform_filename)
endforeach(platform_fqfn ${platform_files})
if(NOT ${platform_override})
list(APPEND proj_files ${fqfn})
message("Appended ${fqfn}")
endif(NOT ${platform_override})
endforeach(fqfn ${common_files})
message("proj_files=${proj_files}")
add_executable (cc_dfi_main ${proj_files})
Run Code Online (Sandbox Code Playgroud)
一种可能的方法是定义变量TARGET_BUILD_PLATFORM并将其设置为您想要构建的确切平台(linux/qnx/vxworks)。
set(PROJECT_NAME some_name_for_project)
project(${PROJECT_NAME} CXX)
file(GLOB COMMON_SRC ${PROJECT_SOURCE_DIR}/common/*.cpp)
file(GLOB PLATFORM_SRC ${PROJECT_SOURCE_DIR}/${TARGET_BUILD_PLATFORM}/*.cpp)
set(SRC_FILES ${COMMON_SRC} ${PLATFORM_SRC})
add_executable(${PROJECT_NAME} ${SRC_FILES})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3524 次 |
| 最近记录: |