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

Robert Maynard robert.maynard at kitware.com
Wed Jan 17 14:39:23 EST 2018


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 <d3ck0r at gmail.com> 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
> ( 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
>>
>>
>
> --
>
> 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/f9009300/attachment.html>


More information about the CMake mailing list