在我正在开发的跨平台/操作系统项目中,我努力将特定于平台的代码简化为子目录,并将通用实现放在一个公共目录中。我已经在autotools中实现了原型,但如果可能的话,想要转向cmake实现。我目前遇到的问题是如何支持多个操作系统。我的当前文件系统结构如下:
这使得autotools首先在src/@target_platform@中查找源文件,然后如果没找到,在src/common中获取它。
那么cmake的方法是什么呢?
更新: 为了帮助所有需要帮助的人,这是我目前所做的。我不确定这是最好的解决方案,但它已经足够好用了。
FILE(GLOB common_files“src / common / .c ”) FILE(GLOB platform_files“src / $ {os} / .c ) 然后,执行肮脏的n ^ 2算法以进行覆盖。我不确定如何在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
这个想法是有一个共同的接口和一个“共同”的实现。实现是一个存根或者一个写成posix标准的共同实现,可以适用于大多数平台。那些需要自定义实现的平台可以覆盖共同实现,但这是可选的。
使用autotools,我可以使用VPATH来设置源树层次结构,所以我设置:
VPATH=@srcdir@/src/@target_platform@;@srcdir@/src/common
这使得autotools首先在src/@target_platform@中查找源文件,然后如果没找到,在src/common中获取它。
那么cmake的方法是什么呢?
更新: 为了帮助所有需要帮助的人,这是我目前所做的。我不确定这是最好的解决方案,但它已经足够好用了。
FILE(GLOB common_files“src / common / .c ”) FILE(GLOB platform_files“src / $ {os} / .c ) 然后,执行肮脏的n ^ 2算法以进行覆盖。我不确定如何在cmake“脚本”中做得更好,但文件数很少,因此速度足够快。当然,诊断消息是可选的。
#
# 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})