Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generic rule from makefile to CMake

Tags:

makefile

cmake

I am trying to "translate" the flowing vanilla makefile lines into CMake syntax.

SRCS = $(wildcard *.foo)
OBJS = $(SRCS:.foo=.bar)

my_rule: $(OBJS)

%.bar: %.foo
    make_bar_from_foo  $@  $<

Working ugly attempt

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

I understand that it's going to generate one command per file instead of something generic. Any simplest/cleanest way to do it?

like image 297
trax Avatar asked Jul 10 '16 15:07

trax


People also ask

How do I call CMake Makefile?

# To run our code, we will use these steps: # - mkdir build && cd build # - cmake .. # - make # # With those steps, we will follow the best practice to compile into a subdir # and the second line will request to CMake to generate a new OS-dependent # Makefile. Finally, run the native Make command.

Is CMake better than Makefile?

So, what is the real difference? CMake is much more high-level. It's tailored to compile C++, for which you write much less build code, but can be also used for general purpose build. make has some built-in C/C++ rules as well, but they are useless at best.

Does CMake make makefiles?

CMake generates a Unix makefile by default when run from the command line in a Unix-like environment. Of course, you can generate makefiles explicitly using the -G option. When generating a makefile, you should also define the CMAKE_BUILD_TYPE variable.

What is CMakeLists txt?

CMakeLists. txt file contains a set of directives and instructions describing the project's source files and targets (executable, library, or both). When you create a new project, CLion generates CMakeLists. txt file automatically and places it in the project root directory.


1 Answers

In CMake you can always declare your own compiler language. So in your case you can e.g. do:

cmake_minimum_required(VERSION 2.8)

project(MakeBarFromFoo NONE)

set(
   CMAKE_FOO_COMPILE_OBJECT 
       "make_bar_from_foo <SOURCE> <OBJECT>"
)

file(GLOB SRCS "*.foo")
add_library(my_rule OBJECT ${SRCS})
set_source_files_properties(${SRCS} PROPERTIES LANGUAGE FOO)

Then you can simply work with it as you would with other object library targets. But you will only get things like the .bar extension if you enable_language(FOO) (and that requires more work, see below).

Examples delivered with CMake itself are ASM or RC compilers.


The enable_language(FOO) Version

This needs four more files you could put in e.g. your project's CMake folder:

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 "@CMAKE_FOO_COMPILER@")
set(CMAKE_FOO_COMPILER_LOADED 1)
set(CMAKE_FOO_SOURCE_FILE_EXTENSIONS @CMAKE_FOO_SOURCE_FILE_EXTENSIONS@)
set(CMAKE_FOO_OUTPUT_EXTENSION @CMAKE_FOO_OUTPUT_EXTENSION@)
set(CMAKE_FOO_COMPILER_ENV_VAR "@CMAKE_FOO_COMPILER_ENV_VAR@")

CMake\CMakeFOOInformation.cmake

# This file sets the basic flags for the FOO compiler
if(NOT CMAKE_FOO_COMPILE_OBJECT)
    set(CMAKE_FOO_COMPILE_OBJECT "<CMAKE_FOO_COMPILER> <SOURCE> <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 "")

Then your CMakeLists.txt file just looks like this:

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})
like image 112
Florian Avatar answered Oct 17 '22 09:10

Florian