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

Michael Hertling mhertling at online.de
Fri May 14 03:19:39 EDT 2010


On 05/14/2010 08:05 AM, Michael Wild wrote:
> 
> 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()

If you need to mix proc-generated C++ source files with manually written
ones in order to generate an executable or a library you should not wrap
ADD_EXECUTABLE() and ADD_LIBRARY() in functions like that. Moreover, you
probably want to preserve the possibility to specify some options like
SHARED, STATIC or EXCLUDE_FROM_ALL. Thus, I would recommend to use the
conversion function directly; cf. QT4_WRAP_CPP():

set(PCSRCS x.pc y.pc z.pc)
_proc_preprocess_sources(CXXSRCS ${PCSRCS}
add_executable(exe a.cxx b.cxx c.cxx ${CXXSRCS})

Nevertheless, a function like MW's _proc_preprocess_sources()
is, IMO, definitely the right approach for the OP's concern.

> #- 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()

Regards,

Michael


More information about the CMake mailing list