CMake:How To Process Lots Of Input Files: Difference between revisions

From KitwarePublic
Jump to navigationJump to search
(New page: ==Introduction== This tutorial describes how to generate an executable that will process a bunch of input files. Couple of assumptions. The input files can be added, but when they are add...)
 
Line 66: Line 66:
# Create the executable
# Create the executable
ADD_EXECUTABLE(processor processor.c)
ADD_EXECUTABLE(processor processor.c)
GET_TARGET_PROPERTY(processorLocation processor LOCATION)


# Variable to store output files
# Variable to store output files
Line 87: Line 88:
     # Custom command to do the processing
     # Custom command to do the processing
     ADD_CUSTOM_COMMAND(OUTPUT "${outfile}"
     ADD_CUSTOM_COMMAND(OUTPUT "${outfile}"
         COMMAND ${EXECUTABLE_OUTPUT_PATH}/processor
         COMMAND ${processorLocation}
         "${infile}" "${outfile}"
         "${infile}" "${outfile}"
         DEPENDS "${infile}"
         DEPENDS "${infile}" "${processorLocation}"
         COMMENT "do something")
         COMMENT "do something")


Line 96: Line 97:
ENDFOREACH(infileName)
ENDFOREACH(infileName)


# Setup a target to drive the conversion
MESSAGE(STATUS "Output files: ${outFiles}")
ADD_CUSTOM_TARGET(ProcessFiles ALL DEPENDS ${outFiles})</pre>
ADD_CUSTOM_TARGET(ProcessFiles ALL DEPENDS ${outFiles})</pre>



Revision as of 17:16, 18 March 2008

Introduction

This tutorial describes how to generate an executable that will process a bunch of input files. Couple of assumptions. The input files can be added, but when they are added the user has to rerun CMake. Other than that, the list of input files is determined during CMake time.

Simple Processor

Here is a simple processor. All it does, it replaces each character with a two byte hex representation:

#include <stdio.h>

int main(int argc, char* argv[]) {
    const char* inFileName = 0;
    const char* outFileName = 0;
    FILE* inFile = 0;
    FILE* outFile = 0;

    int ch;

    if (argc != 3) {
        fprintf(stderr, "Usage: %s <input> <output>\n", argv[0]);
        return 1;
    }

    inFileName = argv[1];
    outFileName = argv[2];

    inFile = fopen(inFileName, "r");
    outFile = fopen(outFileName, "w");

    if (!inFile) {
        fprintf(stderr, "Cannot open input file: \"%s\"\n", inFileName);
        return 1;
    }
    if (!outFile) {
        fprintf(stderr, "Cannot open input file: \"%s\"\n", outFileName);
        return 1;
    }

    while ((ch = fgetc(inFile)) != EOF) {
        fprintf(outFile, "%02X", ch);
        if (ch == '\n') {
            fprintf(outFile, "\n");
        }
    }

    return 0;
}

Sample Input File

Input file can be just about anything. For example:

SampleFile.in

Hello World

CMake List File To Do The Processing

PROJECT(Tutorial_GenerateFiles)

# Make sure we know where the executable is
SET(EXECUTABLE_OUTPUT_PATH "${Tutorial_GenerateFiles_BINARY_DIR}/bin"
    CACHE INTERNAL "")
SET(LIBRARY_OUTPUT_PATH "${Tutorial_GenerateFiles_BINARY_DIR}/bin"
    CACHE INTERNAL "")

# Create the executable
ADD_EXECUTABLE(processor processor.c)
GET_TARGET_PROPERTY(processorLocation processor LOCATION)

# Variable to store output files
SET(outFiles)

# Find all the input files
FILE(GLOB inFiles RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
    "${CMAKE_CURRENT_SOURCE_DIR}/*.in")

FOREACH(infileName ${inFiles})
    MESSAGE(STATUS "Process file: ${infileName}")

    # Generate output file name
    STRING(REGEX REPLACE ".in\$" "" outfileName "${infileName}")
    SET(outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfileName}")
    MESSAGE(STATUS "Output file: ${outfile}")

    # Generate input file name
    SET(infile "${CMAKE_CURRENT_SOURCE_DIR}/${infileName}")

    # Custom command to do the processing
    ADD_CUSTOM_COMMAND(OUTPUT "${outfile}"
        COMMAND ${processorLocation}
        "${infile}" "${outfile}"
        DEPENDS "${infile}" "${processorLocation}"
        COMMENT "do something")

    # Finally remember the output file for dependencies
    SET(outFiles ${outFiles} "${outfile}")
ENDFOREACH(infileName)

MESSAGE(STATUS "Output files: ${outFiles}")
ADD_CUSTOM_TARGET(ProcessFiles ALL DEPENDS ${outFiles})



CMake: [Welcome | Site Map]