[CMake] Using m4 as a additional preprocessor for C/C++

Michael Wild themiwi at gmail.com
Sat Jun 6 10:58:58 EDT 2009


On 5. Jun, 2009, at 22:27, Prasad H. L. wrote:

> Consolidating all the things, the working CMakeLists.txt is as  
> follows -
>
> ------------------------------------
> project(cmake_test)
> cmake_minimum_required(VERSION 2.6)
>
> macro(m4tocxx outfilename)
> add_custom_command(
> 	OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${outfilename}.cpp
> 	COMMAND m4 -P -s ${CMAKE_CURRENT_SOURCE_DIR}/${outfilename}.m4 >
> ${CMAKE_CURRENT_BINARY_DIR}/${outfilename}.cpp
> 	DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${outfilename}.m4
> )
> set_source_files_properties(${outfilename}.cpp PROPERTIES GENERATED  
> true)
> endmacro(m4tocxx)
>
>
> add_executable(testcmake testcmake.cpp)
>
> m4tocxx(testcmake)
> -------------------------------------------------------------
>
> where m4tocxx is the macro to convert from m4 to cpp.
> Objective of the above CMakeLists.txt :- The source file
> is testcmake.m4 which is to be preprocessed to testcmake.cpp and
> linked to form the executable testcmake.
>
> Thanks to Denis and Robert again for all their suggestions.
>
> If anybody knows a way by which this macro could be made
> to get called for all m4 files automatically in the dependence order,
> please let me know. Again, as pointed out by Tyler, not by  
> FILE(GLOB...)...


Hi

I'd modify the macro as follows:

cmake_minimum_required(VERSION 2.6)
project( test CXX )

# we need the M4 macro processor
find_program( M4_EXECUTABLE m4 DOC "The M4 macro processor" )
if( NOT M4_EXECUTABLE )
   message( SEND_ERROR "Failed to find the M4 macro processor." )
endif( NOT M4_EXECUTABLE )

# - Pass a list of files through the M4 macro processor
#
# ADD_M4_SOURCES( OUTVAR source1 ... sourceN )
#
#  OUTVAR  A list containing all the output file names, suitable
#          to be passed to add_executable or add_library.
#
# If the source files have a .m4 suffix it is stripped from the output
# file name. The output files are placed in the same relative location
# to CMAKE_CURRENT_BINARY_DIR as they are to CMAKE_CURRENT_SOURCE_DIR.
#
# Example:
#  add_m4_sources( SRCS src/test1.cxx.m4 src/test2.cxx.m4 )
#  add_executable( test ${SRCS} )
function( ADD_M4_SOURCES OUTVAR )
   set( outfiles )
   foreach( f ${ARGN} )
     # first we might need to make the input file absolute
     get_filename_component( f "${f}" ABSOLUTE )
     #if( NOT IS_ABSOLUTE "${f}" )
     #  set( f "${CMAKE_CURRENT_SOURCE_DIR}/${f}" )
     #endif( NOT IS_ABSOLUTE "${f}" )
     # get the relative path of the file to the current source dir
     file( RELATIVE_PATH rf "${CMAKE_CURRENT_SOURCE_DIR}" "${f}" )
     # strip the .m4 off the end if present and prepend the current  
binary dir
     string( REGEX REPLACE "\\.m4$" ""  of "$ 
{CMAKE_CURRENT_BINARY_DIR}/${rf}" )
     # append the output file to the list of outputs
     list( APPEND outfiles "${of}" )
     # create the output directory if it doesn't exist
     get_filename_component( d "${of}" PATH )
     if( NOT IS_DIRECTORY "${d}" )
       file( MAKE_DIRECTORY "${d}" )
     endif( NOT IS_DIRECTORY "${d}" )
     # now add the custom command to generate the output file
     add_custom_command( OUTPUT "${of}"
       COMMAND ${M4_EXECUTABLE} ARGS -P -s "${f}" > "${of}"
       DEPENDS "${f}"
       )
   endforeach( f )
   # set the output list in the calling scope
   set( ${OUTVAR} ${outfiles} PARENT_SCOPE )
endfunction( ADD_M4_SOURCES )

add_m4_sources( SRCS src/test1.cxx.m4 src/test2.cxx.m4 )
add_executable( test ${SRCS} )

# EOF

Of course, you could turn this into a proper FindM4.cmake module...

HTH

Michael

>
>
>
> Regards,
> Prasad
>
> 2009/6/5 Prasad H. L. <hlprasu at gmail.com>:
>> Can I define a new source type, like .m4 and add rules for it? That
>> would be ideal, I feel, for my case.
>>
>> 2009/6/5 Tyler Roscoe <tyler at cryptio.net>:
>>> On Fri, Jun 05, 2009 at 10:10:07PM +0530, Prasad H. L. wrote:
>>>> 2009/6/5 Denis Scherbakov <denis_scherbakov at yahoo.com>:
>>>>>
>>>>>> Is it possible to set the preprocessing to all .m4 files
>>>>>> avoiding a
>>>>>> manual specification of list of files to processed?
>>>>>
>>>>> If your list of files changes all the time, you can use  
>>>>> FILE(GLOB...)
>>>>> to find all *.m4 files to automate process.
>>>>
>>>> I try this out.
>>>
>>> FYI this approach is not recommended since CMake then has no way  
>>> to know
>>> if you added a new file and thus cannot regenerate your build  
>>> system for
>>> you automatically.
>>>
>>> tyler
>>>
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake



More information about the CMake mailing list