Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Only run C preprocessor in cmake?

I'm trying to use cmake to simplify distributing my OpenCL program. I have a kernel file which includes several headers and other source files, and I want to have a single self contained executable.

My plan is to have cmake run the C preprocessor on the kernel source, turning the cl file and its includes into a single unit which is easier to work with.

I can use add_custom_command to do it by calling gcc/clang with -E, but then I don't get the flags to include the right directories to find the various header files in the command, and I don't see an easy way to find all current include directories to use in the custom call to the compiler.

Is there a way to run only the C preprocessor on a file with the current cmake environment?

like image 475
arsenm Avatar asked Aug 25 '10 02:08

arsenm


3 Answers

CMake automatically generates make targets for preprocessing files. For each foo.c in your project there's a foo.i make target that will run only the preprocessor (with all the relevant -D and -I flags etc.). Run make help to see all other potentially useful targets that CMake generates in your makefiles.

BTW, I can't see how this "single unit" will be easier to work with for you.

like image 138
Tadeusz A. Kadłubowski Avatar answered Nov 17 '22 00:11

Tadeusz A. Kadłubowski


This worked ok so far:

function(add_c_preprocessor_command)
    # Add custom command to run C preprocessor.
    #
    # Arguments
    #   OUTPUT          output file
    #   SOURCE          input file
    #   TARGET          CMake target to inherit compile definitions, include directories, and compile options
    #   EXTRA_C_FLAGS   extra compiler flags added after all flags inherited from the TARGET

    set(one_value_args TARGET SOURCE OUTPUT)
    set(multi_value_args EXTRA_C_FLAGS)
    cmake_parse_arguments(CPP "" "${one_value_args}" "${multi_value_args}" ${ARGN})

    string(TOUPPER ${CMAKE_BUILD_TYPE} build_type)
    string(REPLACE " " ";" c_flags "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${build_type}}")

    add_custom_command(
        OUTPUT ${CPP_OUTPUT}
        COMMAND ${CMAKE_C_COMPILER}
            "-D$<JOIN:$<TARGET_PROPERTY:${CPP_TARGET},COMPILE_DEFINITIONS>,;-D>"
            "-I$<JOIN:$<TARGET_PROPERTY:${CPP_TARGET},INCLUDE_DIRECTORIES>,;-I>"
            ${c_flags}
            $<TARGET_PROPERTY:${CPP_TARGET},COMPILE_OPTIONS>
            ${CPP_EXTRA_C_FLAGS}
            -E ${CPP_SOURCE} -o ${CPP_OUTPUT}
        COMMAND_EXPAND_LISTS VERBATIM
        IMPLICIT_DEPENDS C ${CPP_SOURCE}
        DEPENDS ${CPP_SOURCE})
endfunction()
like image 3
klimkin Avatar answered Nov 17 '22 02:11

klimkin


This will be a crude hack, but you can abuse add_definition for that, as "This command can be used to add any flags, but it was originally intended to add preprocessor definitions."

Alternatively you could just set the COMPILE_FLAGS property of the target to "-E", which will achieve the same effect but be local to that target.

like image 2
Matthias Bach Avatar answered Nov 17 '22 01:11

Matthias Bach