[CMake] add_custom_command - help - to specify a rule that can be used to convert all the .pc files to .cxx files

Michael Wild themiwi at gmail.com
Fri May 14 02:05:54 EDT 2010


On 14. May, 2010, at 7:02 , Thangaraj wrote:

> Hi All,
> 
> I am trying to replace the clearmake build system with cmake for one of my
> corporate projects.
> This is a C++ based project and the interaction to database is being done
> using pro*C/C++ for which a meta compiler was provided by oracle.
> We write the database interaction code in a .pc file, which will be compiled
> by pro*C/C++ compiler (an executable named 'proc') to produce the regular
> .cxx files.
> The generated .cxx files can be compiled using the regular cxx compilers.
> 
> I have gone through the details of add_custom_command and found that it can
> be used for the process which i have mentioned above.
> But from the documentation, i see that the source file and target file name
> should be explicitly specified.
> What I am looking for is that, there should be a way by which using a single
> 'add_custom_command' i should be able to specify the rule for all my .pc
> files in a folder.
> In other words, i should be able to say my source files as '*.pc' and my
> target file as 'sorcefile.cxx'.
> Also i would like to have this rule in my master CMakeLists.txt, so that it
> will be available in any sub directory.
> 
> Please let me know whether this is possible in cmake and if so, point me to
> a simple example of doing it.
> Appreciate your help on this.
> 
> Thanks,
> -Thangaraj


No, this is not possible. Initially, when I started with CMake, I also thought this to be a huge drawback. But once you get used to it, you realize it isn't all that big, and it helps you from making mistakes or bad things happening.

I'd recommend wrapping the add_executable and add_library commands in something like this (untested):

#- Create an executable from pro*C/C++ sources
# Use like add_executable().
function(proc_add_executable)
  _proc_preprocess_sources(pargs ${ARGN})
  add_executable(${pargs})
endfunction()

#- Create a library from pro*C/pro*C++ sources
# Use like add_library().
function(proc_add_libraryle)
  _proc_preprocess_sources(pargs ${ARGN})
  add_library(${pargs})
endfunction()

#- Preprocess pro*C/C++ sources
#
#  _PROC_PREPROCESS_SOURCES(<OUTVAR> [<ARG> ...])
#
# Searches the argument list <ARG> ... for files ending in .pc and
# preprocesses them using PROC_EXECUTABLE. <OUTVAR> will contain the
# argument list with all .pc files replaced by the generated .cxx files.
# The variable PROC_FLAGS can be used to pass flags to PROC_EXECUTABLE.
function(_proc_preprocess_sources(OUTVAR)
  set(result)
  foreach(arg ${ARGN})
    # is it a .pc file?
    if(arg MATCHES "\\.pc$")
      # is it an absolute path?
      if(NOT IS_ABSOLUTE "${arg}")
        # make it absolute
        set(arg "${CMAKE_CURRENT_SOURCE_DIR}/${arg}")
      endif()
      # compute output file
      file(RELATIVE_PATH outarg "${CMAKE_CURRENT_SOURCE_DIR}" "${arg}")
      set(outarg "${CMAKE_CURRENT_BINARY_DIR}/${outarg}")
      string(REGEX REPLACE "\\.pc$" ".cxx" outarg "${outarg}")
      # preprocess
      add_custom_command(OUTPUT "${outarg}"
        # ==== TODO: REPLACE BY THE ACTUAL INVOCATION, I DON'T KNOW THE SYNTAX ====
        COMMAND "${PROC_EXECUTABLE}" ${PROC_FLAGS} -o "${outarg}" "${arg}"
        DEPENDS "${arg}"
        IMPLICIT_DEPENDS CXX "${arg}" # ONLY IF C/C++ INCLUDE SYNTAX
        WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
        COMMENT "Creating pro*C/C++ output ${outvar}"
        )
      list(APPEND result "${outarg}")
    else()
      list(APPEND result "${arg}")
    endif()
  endforeach()
  # return modified argument list
  set(${outvar} "${result}" PARENT_SCOPE)
endfunction()



I hope this gets you started...


Michael


More information about the CMake mailing list