Regola generica dal makefile a CMake

Sto cercando di “tradurre” le linee di makefile vanilla che scorre nella syntax di CMake.

SRCS = $(wildcard *.foo) OBJS = $(SRCS:.foo=.bar) my_rule: $(OBJS) %.bar: %.foo make_bar_from_foo [email protected] $< 

Brutto tentativo di lavoro

 FILE(GLOB SRCS "*.foo") SET(outFiles) FOREACH(SRC ${SRCS}) SET(OUTPUT_FILE_NAME "${SRC}.bar") ADD_CUSTOM_COMMAND( OUTPUT "${OUTPUT_FILE_NAME}" COMMAND make_bar_from_foo ${SRC} ${OUTPUT_FILE_NAME} DEPENDS "${SRC}") SET(outFiles ${outFiles} "${OUTPUT_FILE_NAME}") ENDFOREACH(SRC) ADD_CUSTOM_TARGET(my_rule ALL DEPENDS ${outFiles}) 

Capisco che genererà un comando per file invece di qualcosa di generico. Qualche modo più semplice / pulito per farlo?

In CMake puoi sempre dichiarare la tua lingua del compilatore. Quindi nel tuo caso puoi ad esempio fare:

 cmake_minimum_required(VERSION 2.8) project(MakeBarFromFoo NONE) set( CMAKE_FOO_COMPILE_OBJECT "make_bar_from_foo  " ) file(GLOB SRCS "*.foo") add_library(my_rule OBJECT ${SRCS}) set_source_files_properties(${SRCS} PROPERTIES LANGUAGE FOO) 

Quindi puoi semplicemente lavorare con esso come faresti con altri target di libreria di oggetti . Ma otterrai solo le estensioni .bar se enable_language(FOO) (e questo richiede più lavoro, vedi sotto).

Gli esempi forniti con CMake stesso sono compilatori ASM o RC .


La versione enable_language(FOO)

Ciò richiede altri quattro file che potresti inserire, ad esempio la cartella CMake del tuo progetto:

CMake \ CMakeDetermineFOOCompiler.cmake

 # Find the compiler find_program( CMAKE_FOO_COMPILER NAMES "make_bar_from_foo" HINTS "${CMAKE_SOURCE_DIR}" DOC "FOO compiler" ) mark_as_advanced(CMAKE_FOO_COMPILER) set(CMAKE_FOO_SOURCE_FILE_EXTENSIONS foo;FOO) set(CMAKE_FOO_OUTPUT_EXTENSION .bar) set(CMAKE_FOO_COMPILER_ENV_VAR "FOO") # Configure variables set in this file for fast reload later on configure_file(${CMAKE_CURRENT_LIST_DIR}/CMakeFOOCompiler.cmake.in ${CMAKE_PLATFORM_INFO_DIR}/CMakeFOOCompiler.cmake) 

CMake \ CMakeFOOCompiler.cmake.in

 set(CMAKE_FOO_COMPILER "@[email protected]") set(CMAKE_FOO_COMPILER_LOADED 1) set(CMAKE_FOO_SOURCE_FILE_EXTENSIONS @[email protected]) set(CMAKE_FOO_OUTPUT_EXTENSION @[email protected]) set(CMAKE_FOO_COMPILER_ENV_VAR "@[email protected]") 

CMake \ CMakeFOOInformation.cmake

 # This file sets the basic flags for the FOO compiler if(NOT CMAKE_FOO_COMPILE_OBJECT) set(CMAKE_FOO_COMPILE_OBJECT "  ") endif() set(CMAKE_FOO_INFORMATION_LOADED 1) 

CMake \ CMakeTestFOOCompiler.cmake

 # For now just do nothing in here set(CMAKE_FOO_COMPILER_WORKS 1 CACHE INTERNAL "") 

Quindi il tuo file CMakeLists.txt sembra proprio questo:

CMakeLists.txt

 cmake_minimum_required(VERSION 2.8) project(MakeBarFromFoo NONE) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake") enable_language(FOO) file(GLOB SRCS "*.foo") add_library(my_rule OBJECT ${SRCS}) 

Il tuo tentativo è corretto e difficilmente può essere notevolmente migliorato.

Ecco come funziona CMake: ognuna delle sue “regole” è concreta; non è ansible creare una “regola modello”. La ragione di ciò è l’ indipendenza dalla piattaforma : non tutti i sistemi di costruzione supportano i “modelli” per le regole.

Dall’altra parte, CMake supporta la creazione delle “regole” all’interno di funzioni / macro. In questo modo è ansible ridurre facilmente la digitazione di parti ripetute.

In generale, con CMake non si creano tutti i file object. Basta aggiungere i giusti file .foo nei comandi CMake add_library ( add_library o add_executable ) e CMake lo gestirà per te.

CMake è molto più potente rispetto alla semplice marca. Ma devi accettare che questo potere viene fornito con un cambiamento di come si utilizza lo strumento.