Get CMake not to be silent about sources it doesn't understand?

Let's say you have a very simple CMakeLists.txt

add_executable(silent T.cpp A.asm)

      

CMake will happily generate a C ++ target to build silent

, with T.cpp

in it, but will silently discard any reference to A.asm

because it doesn't know what to do with the suffix.

Is there a way to get CMake to loudly complain about this source file it doesn't understand (to help port the Makefile for CMake).

+3


source to share


2 answers


Ignoring unknown file extensions - unfortunately for your case - by design.

If I look at the code cmGeneratorTarget::ComputeKindedSources()

, all unknowns end up being classified as SourceKindExtra

(for adding as such to the generated IDE files).

So, I tested a bit and came up with the following script that evaluates your executable target source files for valid file extensions, overwriting add_executable()

myself:



cmake_minimum_required(VERSION 3.3)

project(silent CXX)

file(WRITE T.cpp "int main() { return 0; }")
file(WRITE T.h "")
file(WRITE A.asm "")

function(add_executable _target)
    _add_executable(${_target} ${ARGN})

    get_property(_langs GLOBAL PROPERTY ENABLED_LANGUAGES)
    foreach(_lang IN LISTS _langs)
        list(APPEND _ignore "${CMAKE_${_lang}_IGNORE_EXTENSIONS}")
    endforeach()

    get_target_property(_srcs ${_target} SOURCES)
    foreach(_src IN LISTS _srcs)
        get_source_file_property(_lang "${_src}" LANGUAGE)
        get_filename_component(_ext "${_src}" EXT)
        string(SUBSTRING "${_ext}" 1 -1 _ext) # remove leading dot
        if (NOT _lang AND NOT _ext IN_LIST _ignore)
            message(FATAL_ERROR "Target ${_target}: Unknown source file type '${_src}'")
        endif()
    endforeach()
endfunction()

add_executable(silent T.cpp T.h A.asm)

      

Since you wanted to complain quite loudly about CMake, I declared it FATAL_ERROR

in this implementation example.

+3


source


CMake doesn't just leave unknown files in add_executable()

.

If along with

add_executable(silent T.cpp A.asm)

      

you have

add_custom_command(OUTPUT A.asm COMMAND <...>
    DEPENDS <dependees>)

      



then whenever <dependees>

changed, CMake will rerun the command to build the A.asm

executable before compiling.

Note that auto-scanning of headers does not provide such functionality: if your executable includes foo.h

, then the executable will only be restored when it is modifiedfoo.h

... Any custom command creating this header will be ignored.


However, you can change the behavior add_executable

by overriding it. See @ Florian's answer for example about such an override.

+1


source







All Articles