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

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Jimi Damon
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,




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
Reply | Threaded
Open this post in threaded view
|

Re: How can I create a C executable and C++ library from the same source

Matthew Keeler
Whether what you want exactly is possible I dont know. If you are just wanting your C++ test library to be able to test your C source then I would still let them compile as C and just extern “C” { #include <your header> }. When it gets linked all together it should be fine. This is how I usually do testing of my C code with cpputest which is also a C++ library.

-- 
Matt Keeler


On January 17, 2018 at 13:05:36, Jimi Damon ([hidden email]) 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,




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

--

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
Reply | Threaded
Open this post in threaded view
|

Re: How can I create a C executable and C++ library from the same source

J Decker
In reply to this post by Jimi Damon
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 

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


---------------------
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 <[hidden email]> 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,




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



--

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
Reply | Threaded
Open this post in threaded view
|

Re: How can I create a C executable and C++ library from the same source

Robert Maynard
As stated CMake tracks source files globally so they can only have a single language.

Project that I work on have migrated over to using file(GENERATE) to produce the files as it only
requires a couple lines of CMake code.

get_filename_component(c_fname "${c_source_file}" NAME_WE)
get_filename_component(c_fullpath "${c_source_file}" ABSOLUTE)
file(GENERATE
      OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${c_fname}.cpp
      CONTENT "#include \"${c_fullpath}\"")

What ever approach you take I recommend not using an approach that copies the contents of the
source file itself. Those will generally than require CMake to re-run every time you modify the file. Instead
use an include statement so CMake won't re-run.

On Wed, Jan 17, 2018 at 1:29 PM, J Decker <[hidden email]> wrote:
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 

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


---------------------
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 <[hidden email]> 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,




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



--

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



--

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