在cmake中处理os / platform特定代码

时间:2011-10-24 18:35:10

标签: cmake

在我正在开发的多平台/ os项目中,我正在努力将特定于平台的代码简化为子目录,并使用一个包含常见实现的公共目录。我在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

这个想法是有一个共同的接口和一个“共同的”实现。该实现是一个存根或一个写入posix标准的通用实现,它允许它适用于大多数平台。那些需要自定义实现的平台可能会覆盖普通实现,但它是可选的。

使用autotools,我可以使用VPATH来设置源树层次结构,所以我设置:

VPATH=@srcdir@/src/@target_platform@;@srcdir@/src/common

这使得autotools首先在src / @ target_platform @中查找源文件,然后,如果找不到,则从src / common中获取它。

这样做的方法是什么?

更新: 为了帮助所有那些失去灵魂的人,这就是我暂时做的事情。我不确定这是最好的解决方案,但它运作良好。

FILE(GLOB common_files“src / common / .c ”) FILE(GLOB platform_files“src / $ {os} / .c

然后,执行脏n ^ 2算法以覆盖。不知道如何在cmake“script”中做得更好,但是文件数量很少,所以速度很快。 diag消息当然是可选的。

#
# 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})

1 个答案:

答案 0 :(得分:2)

一种可能的方法是定义变量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})