[CMake] How can I create a C executable and C++ library from the same source

J Decker d3ck0r at gmail.com
Wed Jan 17 13:29:49 EST 2018


No.
CMake tracks each source file name exactly once.  If you set properties on
it, it will be treated that way always.  Have to make  a copy of the source
to cpp...

copies to cmake_binary_dir/<source name>
plusplus_file_dup is the resulting list
( https://github.com/d3x0r/SACK/blob/master/CMakeLists.txt#L655 )

(really this is just for headers... src/csrc.h should be
${binary}/src/csrc.h in target too because #include "crsc.h"

FOREACH(SOURCE ${PLUSPLUS_FILES_TO_COPY})
   if( ${SOURCE} MATCHES "${SOURCES_ROOT}(.*)$" )
       set( BASENAME ${CMAKE_MATCH_1} )
       set( plusplus_file_dup ${plusplus_file_dup}
${CMAKE_BINARY_DIR}/${BASENAME} )
       add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/${BASENAME}
                           DEPENDS ${SOURCE}
                           COMMAND ${CMAKE_COMMAND} -E copy_if_different
${SOURCE} ${CMAKE_BINARY_DIR}/${BASENAME}
                           #COMMAND ${CMAKE_COMMAND} -E touch
${CMAKE_BINARY_DIR}/${BASENAME}
                           )
   else()
   endif()
ENDFOREACH(SOURCE)


---------------------
( https://github.com/d3x0r/SACK/blob/master/CMakeLists.txt#L672 )
THis make s abetter copy routine; it tests to see the type of header(file)
and possible substitutions...  still kinda some debugging coments (#)  in
there... this adds it as a rule, so it only generates the target source if
the source is referenced.  therefore also onlly when those C files change
do new copies get made.

macro( COPY_CPLUSPLUS FILE_LIST )
FOREACH(SOURCE ${ARGN} )
   if( ${SOURCE} MATCHES "${SACK_BASE}/(.*)\\.c$" )
      set( FILEOK 1 )
      set( BASENAME ${CMAKE_MATCH_1} )
      set( FILEEXT .cpp )
   elseif( ${SOURCE} MATCHES "${SACK_BASE}/(.*)\\.h$" )
      set( FILEOK 1 )
      set( BASENAME ${CMAKE_MATCH_1} )
      set( FILEEXT .h )
   elseif( ${SOURCE} MATCHES "(.*)\\.c$" )
      set( FILEOK 1 )
      set( BASENAME ${CMAKE_MATCH_1} )
      set( FILEEXT .cpp )
   elseif( ${SOURCE} MATCHES "(.*)\\.h$" )
      set( FILEOK 1 )
      set( BASENAME ${CMAKE_MATCH_1} )
      set( FILEEXT .h )
   else()
      set( FILEOK 0 )
      set( BASENAME "" )
   endif()

   if( FILEOK )
       get_source_file_property(SOURCE_FOLDER ${SOURCE} FOLDER)

       if( ${SOURCE} MATCHES "^${PROJECT_SOURCE_DIR}.*" )
          if( NOT ${SOURCE_FOLDER} MATCHES "NOTFOUND" )
            #message( "err folder : ${SOURCE_FOLDER} " )
            SOURCE_GROUP( ${SOURCE_FOLDER} FILES ${SOURCE} )
            SOURCE_GROUP( ${SOURCE_FOLDER} FILES
${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT} )
          endif()
          add_custom_command( OUTPUT
${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT}
                              DEPENDS ${SOURCE}
                              COMMAND ${CMAKE_COMMAND} -E copy_if_different
${SOURCE} ${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT}
                              #COMMAND ${CMAKE_COMMAND} -E touch
${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT}
                              )
          #EXECUTE_PROCESS(COMMAND cmake -E copy_if_different ${SOURCE}
${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT} )

       else( ${SOURCE} MATCHES "^${PROJECT_SOURCE_DIR}.*" )
         if( NOT ${SOURCE_FOLDER} MATCHES "NOTFOUND" )
           #message( "err folder : ${SOURCE_FOLDER} " )
           SOURCE_GROUP( ${SOURCE_FOLDER} FILES
${PROJECT_SOURCE_DIR}/${SOURCE} )
           SOURCE_GROUP( ${SOURCE_FOLDER} FILES
${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT} )
         endif()
         add_custom_command( OUTPUT
${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT}
                             DEPENDS ${PROJECT_SOURCE_DIR}/${SOURCE}
                             COMMAND ${CMAKE_COMMAND} -E copy_if_different
${PROJECT_SOURCE_DIR}/${SOURCE} ${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT}
                             #COMMAND ${CMAKE_COMMAND} -E touch
${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT}
                             )
         #EXECUTE_PROCESS(COMMAND cmake -E copy_if_different
${PROJECT_SOURCE_DIR}/${SOURCE} ${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT} )
         #message( "LIB2_SOURCE2 : ${BASENAME}  ${SOURCE}" )
       endif()
     set( ${FILE_LIST} ${${FILE_LIST}}
${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT} )
     #set( cplusplus_sources ${cplusplus_sources}
${CMAKE_BINARY_DIR}/${BASENAME}${FILEEXT} )
   else()
      #message( "NOT THING ${SOURCE}" )
   endif()
ENDFOREACH(SOURCE)
endmacro( COPY_CPLUSPLUS )



On Wed, Jan 17, 2018 at 10:05 AM, Jimi Damon <jdamon at accesio.com> wrote:

> Hi,
>
> I want to use Gtest for some unit tests on a number of the C functions
> that comprise my C executable.  However, Gtest ( And gMock ) are C++
> testing frameworks.
>
> What I would like to have is a project for my exe and then a separate
> project for my C++ library and be able to change the source properties to
> use the language CXX just before compiling.
>
> The problem I'm having is that CMake uses the CXX compiler for the C files.
>
>
> Here's what I would like to have
>
> project(cexe)
> set(SOURCES foo.c bar.c )
> add_executable( cexe  ${SOURCES} )
>
> project(cpplib)
> set_source_files_properties(${SOURCES} PROPERTIES LANGUAGE CXX )
> add_library( cpplib SHARED ${SOURCES} )
>
>
>
> Is there a way to do this ?
>
> Can target_compile_options set the compile type for a given target ?
>
>
> In the past I've had to copy the .C files to some renamed .CPP equivalent
> and then compile off of that.
>
> I'm hoping that enough new functionality has been added to Cmake to allow
> separation between compiles.
>
>
> Thanks,
>
>
>
>
> --
>
> Jimi Damon
> ACCES I/O Products, Inc.
> <http://accesio.com/go.cgi?p=/contact/contact.html>
> Linux Engineer
> JDamon at accesio.com
> (858) 550-7320 x3015
> [image: ACCES I/O Logo]
> 10623 Roselle Street San Diego CA 92121-1506 <http://accesio.com/>
>
>
> WARNING - This e-mail or its attachments may contain controlled technical
> data or controlled technology within the definition of the International
> Traffic in Arms Regulations (ITAR) or Export Administration Regulations
> (EAR), and are subject to the export control laws of the U.S. Government.
> Transfer of this data or technology by any means to a foreign person,
> whether in the United States or abroad, without an export license or other
> approval from the U.S. Government, is prohibited. The information contained
> in this document is CONFIDENTIAL and property of ACCES I/O Products, Inc.
> Any unauthorized review, use, disclosure or distribution is prohibited
> without express written consent of ACCES I/O Products, Inc. If you are not
> the intended recipient, please contact the sender and destroy all copies of
> the original message and enclosed attachments.
> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more
> information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
>
> Visit other Kitware open-source projects at http://www.kitware.com/
> opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> https://cmake.org/mailman/listinfo/cmake
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180117/3ed2f870/attachment-0001.html>


More information about the CMake mailing list