В многоплатформенном / OS-проекте, над которым я работаю, я стремлюсь упростить код, специфичный для платформы, до подкаталогов с общим каталогом, содержащим общую реализацию. У меня есть прототип реализации в автоинструментах, но я хочу перейти к реализации 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, что позволяет работать на большинстве платформ. Те платформы, которые требуют пользовательской реализации, МОГУТ переопределять общую, но это не обязательно.
С помощью автоинструментов я могу добиться этого, используя VPATH для установки иерархии дерева исходных текстов, поэтому я установил:
VPATH=@srcdir@/src/@target_platform@;@srcdir@/src/common
Это заставляет автоинструменты сначала искать исходный файл в src / @ target_platform @, а затем, если он не был найден, получить его из src / common.
Как это сделать cmake?
Обновление:
Чтобы помочь всем тем потерянным нуждающимся душам, это то, чем я в данный момент занимаюсь. Я не уверен, что это лучшее решение, но оно работает достаточно хорошо.
FILE (GLOB common_files "src / common / .c ")
ФАЙЛ (GLOB platform_files "src / $ {os} / .c )
Затем выполните грязный алгоритм n ^ 2 для переопределения. Не знаю, как сделать что-то лучше в "скрипте" cmake, но количество файлов мало, так что это довольно быстро. Сообщения 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})