integrate cppcheck into build system - makefile

I want to integrate cppcheck into my project in order to automatically produce fail on build if something is wrong. This could be part of CI job of course, but currently we have some technical issues doing that. The easiest way would be to integrate cppcheck into Makefile. Also it could use header directories configured for the project.
Is it possible and how to do that?
CC=gcc
CFLAGS=-I.
DEPS =
OBJ = main.o
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
hellomake: $(OBJ)
gcc -o $# $^ $(CFLAGS)
I want to perform static analysis on main.c:
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}

The easiest way is to make your default target depend both on the binary and on cppcheck's output:
SOURCES = main.cpp
CPPCHECK = cppcheck
CHECKFLAGS = -q --error-exitcode=1
default: cppcheck.out.xml hellomake
.PHONY: default clean
cppcheck.out.xml: $(SOURCES)
$(CPPCHECK) $(CHECKFLAGS) $^ -xml >$#
hellomake: $(OBJ)
$(LINK.c) -o $# $^

Related

Makefile target gets called twice

I have the following Makefile:
VERSION = 0.1.1
CC = g++
CFLAGS = -Wall -g -DVERSION=\"$(VERSION)\"
LDFLAGS = -lm
DEPFILE = .dep
SOURCES := ${wildcard *.cpp}
HEADERS := ${wildcard *.h}
OBJECTS := ${SOURCES:.cpp=.o}
BINARY = main.exe
.PHONY: all dep clean
all: $(BINARY)
$(BINARY): $(DEPFILE) $(OBJECTS)
$(CC) $(CFLAGS) -o $(BINARY) $(OBJECTS) $(LDFLAGS)
%.o: %.cpp
$(CC) $(CFLAGS) -c $<
dep: $(DEPFILE)
$(DEPFILE): $(SOURCES) $(HEADERS)
$(CC) -MM $(SOURCES) > $(DEPFILE)
-include $(DEPFILE)
clean:
rm -vf $(BINARY) $(OBJECTS) $(DEPFILE)
When I run make dep I get
g++ -MM Monomial.cpp main.cpp Variable.cpp > .dep
make: Nothing to be done for 'dep'.
It seems as if dep is called twice. Why is that?
I am using GNU Make 4.2.1 under Cygwin.
Also it would be great if you could give me some best practises for this Makefile if you spot some bad design patterns (other than the double call of dep).
Your makefile contains an include directive:
-include $(DEPFILE)
So when Make starts, before it even considers the target(s) you've asked it to build, it tries to rebuild the file that is to be included in the makefile. Once it's done rebuilding .dep, it gets to work on the file you asked for... which is .dep.
You probably don't have to explicitly make dep, ever.
And you can simplify a couple of your rules in light of this fact, and the useful nature of automatic variables:
$(BINARY): $(OBJECTS)
$(CC) $(CFLAGS) -o $# $^ $(LDFLAGS)
$(DEPFILE): $(SOURCES) $(HEADERS)
$(CC) -MM $(SOURCES) > $#

How to write a makefile for llvm IR

If I have 3 files, function.h, function.c and my_program.c which calls a method in function.h all in the same directory, what would be the best way to write a makefile so that I end up with a my_program.bc that would actually run when I type in lli my_program.bc? (I need to run a user defined pass that would insert stuff into the functions - should I run the pass on function.bc and test.bc, or should I link before running the pass?)
I've tried llvm-link function.bc my_program.bc with no luck. I feel I'm either missing something simple or going about the whole thing wrong.
Current terrible none-working makefile:
.PHONY: all clean
CC = clang
CFLAGS = -std=gnu99 -D_POSIX_C_SOURCE=200809L -g -Wall
IRFLAGS = -O3 -emit-llvm
TARGET = test
DEPS = functions.h
all: $(TARGET)
bc: test2
%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
%.bc: %.c $(DEPS)
$(CC) $(IRFLAGS) -c -o $# $<
test2: test.bc functions.bc
llvm-link -o test2.bc $< functions.bc
test: test.o functions.o
$(CC) $(CFLAGS) -o $# $^
clean:
$(RM) $(TARGET) *.o *.bc
Why not just write a normal Makefile to produce the desired executable,
then use wllvm?
Shameless plug for wllvm:
https://github.com/SRI-CSL/whole-program-llvm
I do not use lli, so I would be interested to hear about how it resolved
any reliance on stdlibc that your program may have.

Multiple make targets in the same CMake project

In my project I have a makefile that looks like this:
CXX = clang++
CFLAGS = -std=c++11
COMMON_SOURCES = file1.cpp file2.cpp
TARGET_SOURCES = main.cpp
TEST_SOURCES = run_tests.cpp test_file1.cpp test_file2.cpp
COMMON_OBJECTS = $(COMMON_SOURCES:.c=.o)
TARGET_OBJECTS = $(TARGET_SOURCES:.c=.o)
TEST_OBJECTS = $(TEST_SOURCES:.c=.o)
EXECUTABLE = build/application
TEST_EXECUTABLE = build/tests
.PHONY: all target tests
all: target tests
target: $(EXECUTABLE)
tests: $(TEST_EXECUTABLE)
clean:
rm build/tests & rm build/application &
$(EXECUTABLE): $(COMMON_OBJECTS) $(TARGET_OBJECTS)
$(CXX) $(CFLAGS) $(LDFLAGS) $^ -o $#
$(TEST_EXECUTABLE): $(COMMON_OBJECTS) $(TEST_OBJECTS)
$(CXX) $(CFLAGS) $(LDFLAGS) $^ -o $#
.c.o:
$(CXX) $(CFLAGS) $< -o $#
This lets me run make tests or make target and it will build the appropriate executable.
How do I set up a CMakeLists file to get the same convenient build system?
Except for using clang++, I think if you put the following in a CMakeLists.txt file and then run your cmake configure step in a build directory (i.e., mkdir build; cd build; cmake ..), you should have what you are asking for.
project(myproject)
# I am not sure how you get cmake to use clang++ over g++
# CXX = clang++
add_definitions(-std=c++11)
set(COMMON_SOURCES file1.cpp file2.cpp)
set(TARGET_SOURCES main.cpp)
set(TEST_SOURCES run_tests.cpp test_file1.cpp test_file2.cpp)
add_executable(application ${COMMON_SOURCES} ${TARGET_SOURCES})
add_executable(tests ${COMMON_SOURCES} ${TEST_SOURCES})
Every add_custom_target() (and some other commands, like add_executable) actually adds target in the make sence.
add_custom_target(tests) # Note: without 'ALL'
add_executable(test_executable ...) # Note: without 'ALL'
add_dependencies(tests test_executable)
So, test_executable will be build on make tests, but not in case of simple make.

Simple Makefile not taking include path

following is my makefile. but It is not taking include path during build.
SHELL = /bin/sh
CC = g++
FLAGS =
CFLAGS = -fPIC
TARGET = my_bridge.so
INC=-I/my_custom_path/include/ -I/my_custom_path/include/linux
SOURCES = $(shell echo *.cpp)
HEADERS = $(shell echo *.h)
OBJECTS = $(SOURCES:.cpp=.o)
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) $(FLAGS) $(INC) $(CFLAGS) -o $(TARGET) $(OBJECTS)
When I build i get following line
g++ -c -o my_bridge.o my_bridge.cpp
Your $(TARGET): $(OBJECTS) rule tells make how to generate my_bridge.so out of my_bridge.o, but you haven't given a rule that explains how to make my_bridge.o in the first place. make relies thus on its implicit rules for that, which gives you the command that you see. You can either define your own rule to compile .cpp files, e.g.
%.o: %.cpp
$(CC) $(FLAGS) $(INC) $(CFLAGS) -o $# $<
or put your include directive in $(CXXFLAGS), which is used by make's default rule (see https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html#Catalogue-of-Rules)

Compiling for Multiple Targets

I want to compile my program both to linux and windows using g++ and mingw respectively. The only difference between the compilations is the compiler to use and output file name.
A single make command should produce both output files. What is the best way to achieve this with as little duplications in the makefile as possible?
How about this:
linux-name: CC:=g++
windows-name: CC:=mingw
linux-name windows-name:
$(CC) whatever -o $#
EDIT:
What I wrote above is only the new part of the makefile; I assumed that the rest of the makefile was implied. To be more explicit:
all: linux-name windows-name
linux-name: CC:=g++
windows-name: CC:=mingw
linux-name windows-name: foo.o bar.o baz.o SomethingElse
$(CC) $(CCFLAGS) whatever $^ -o $#
%.o: %.cc
$(CC) $(CFLAGS) -I$(INC_DIR) whatever -c $< -o $#
SomethingElse:
build somehow

Resources