Save and reprint warnings for successfully compiled files in subsequent builds?

When you re-create a project, when there are warnings but no errors in the translator, the main source file is usually not recompiled.

This can make it difficult to deal with errors and warnings to try and build the project without warnings. Typically, you should continue to iterate through the build until all errors are taken care of, then do a full cleanup and build to make sure there are no warnings (and also so that a previously run build is not a "fluke" caused by the remainder of the build artifacts).

Is there any way, with CMake (or some other utility like a Bash script), to parse the build output for warnings, save them to a text file somewhere, and then re-render them on subsequent builds?

For bonus points, since I color my compiler output, is it possible to save warnings with color management symbols and re-render with the same coloring?

(If it matters, at the moment I only compile C ++ and I usually use GCC for this. My build generator of choice is Ninja and I have a few Bash scripts I wrote, wrap all my calls to CMake and Ninja.)

+3


source to share


1 answer


I am not an expert bash

, so the following code can certainly be improved, but here is a working example with CMake

/ bash

/ gcc

/ ninja

that should give the basic idea I had:

  • Detecting if the compiler puts warnings / errors in stderr

  • Save it to <object file name>.warnings

  • Delete object file with warning before starting next build
  • The compiler itself issues a warning again (if not fixed yet)

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(CaptureWarnings CXX)

add_compile_options(-fdiagnostics-color=always -Wconversion)
configure_file(capture_warnings.sh.in ${CMAKE_BINARY_DIR}/capture_warnings.sh @ONLY)

file(WRITE foo.cc "int main() {\nreturn 0.5;\n}")
file(WRITE bar.cc "")

set_directory_properties(PROPERTIES 
    RULE_LAUNCH_COMPILE "bash ${CMAKE_BINARY_DIR}/capture_warnings.sh")

add_executable(MyExe foo.cc bar.cc)

      

capture_warnings.sh.in

#!/bin/bash

# shell script invoked with the following arguments
# $(CXX) $(CXX_DEFINES) $(CXX_FLAGS) -MMD -MT OBJ_FILE -MF DEP_FILE -o OBJ_FILE -c SRC_FILE

# extract parameters
OBJECT_FILE="${@: -3:1}"

# invoke compiler
set -o pipefail
$@ 2> ${OBJECT_FILE}.warnings
ERROR=${PIPESTATUS}

OUT=$(<${OBJECT_FILE}.warnings)

if ! [[ -z "$OUT" ]]; then
    # reprint the warning/error
    >&2 echo "${OUT}"
    echo "rm -f ${PWD}/${OBJECT_FILE}" >> @CMAKE_BINARY_DIR@/remove_obj_with_warnings.sh
else
    rm -f ${OBJECT_FILE}.warnings
fi

exit ${ERROR}

      



build.sh

#!/bin/bash

if ! [ -d build ]; then
    mkdir build
    cmake -H. -Bbuild -G "Ninja"
fi

if [ -f build/remove_obj_with_warnings.sh ]; then 
    sh ./build/remove_obj_with_warnings.sh
    rm build/remove_obj_with_warnings.sh
fi

cmake --build build

      

I thought that collecting files to be deleted in remove_obj_with_warnings.sh

would be faster than grepping for files .warnings

. The downside would be that it could contain files that were already deleted or not yet created (covered by the provision rm -f

).

This is especially true if you make the call remove_obj_with_warnings.sh

optional.

Links used:

+3


source







All Articles