Printing the output straight from makefile to a .txt file - c++

I have a test.cpp file that test my class, then I have a Makefile that I use to run my program AND run my tests (after running the tests, the result should be written into a .txt file as well as into the terminal). This is my test.cpp:
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include "doctest.h"
#include "Weather.h"
using namespace std;
TEST_CASE("Random test") {
Weather testt(10, 1, 0, "sunny");
CHECK(testt.getAirTemperature() == 10);
}
And this is my Makefile
CC = g++
CFLAGS = -c -Wall
TEST_TARGET = test.exe
TEST_OUT = test_out.txt
all: program
program: main.o Weather.o myException.o
$(CC) main.o Weather.o myException.o -o program
main.o: main.cpp
$(CC) $(CFLAGS) main.cpp
Weather.o: Weather.cpp
$(CC) $(CFLAGS) Weather.cpp
myException.o: myException.cpp
$(CC) $(CFLAGS) myException.cpp
build_test: test.o Weather.o myException.o
$(CC) test.o Weather.o myException.o -o $(TEST_TARGET)
run_test: $(TEST_TARGET)
$(TEST_TARGET) >> $(TEST_OUT) && $(TEST_TARGET)
test.o: test.cpp
$(CC) $(CFLAGS) test.cpp
rebuild: clean all
clean:
rm -rf *o program
You can ignore everything in the makefile just look at build_test run_test and test.o Since these are 3 things that I use for this task. In the terminal, when I write make build_test an executable is created successfully without any problem, although when I move on to make run_test I get test.exe >> test_out.txt && test.exe. make: *** [Makefile:24: run_test] Error 1. So it says the issue is in the 24th line which is $(TEST_TARGET) >> $(TEST_OUT) && $(TEST_TARGET). My question is, did I get the idea of how I should print it into a file and a terminal wrong? Or how should I output the results the doctest.h provides me with.

Related

CLion run and makefile showing different results

I have this C++ program in Clion, however, I need to create a makefile for it to be run on text editors and not IDEs, it is for a university, they do not use IDEs.
When I run my program trough the run button on CLion, it works perfectly but when I run it trough the makefile, it displays multiple errors that don't even make sense.
When is the issue occurring from? Please tell me if you need more information or images.
Project structure:
Errors with makefile:
Run without the makefile:
Makefile:
OBJS = main.o HastTable.o Book.o
SOURCE = main.cpp HastTable.cpp Book.cpp
HEADER = HashTable.h Book.h
OUT = book
CC = g++
FLAGS = -g -c -Wall -Wextra
all: $(OBJS)
$(CC) -g $(OBJS) -o $(OUT) $(LFLAGS)
main.o: main.cpp
$(CC) $(FLAGS) main.cpp
HastTable.o: HastTable.cpp
$(CC) $(FLAGS) HastTable.cpp
Book.o: Book.cpp
$(CC) $(FLAGS) Book.cpp
clean:
rm -f $(OBJS) $(OUT)

G++ unresolved identifier, cannot find linker error

I'm not sure if this is an error in my makefile, header, or source, but it looks like all the relevant pieces of code should link up nicely so I can use functions from one C++ file inside another, but I'm running into a brick wall. Here's a simplified version of what I'm working with:
common.h:
//common.h
#ifndef COMMON_H
#define COMMON_H
int foo();
#endif
common.cc:
//common.cc
#include "common.h"
int main(){
int z = foo();
return 0;
}//main
int foo(){
int x = 5;
int y = 7;
return x + y;
}//foo
test.cc:
//test.cc
#include "common.h"
int main(){
return foo();
}
And the makefile (sorry, it's a bit more complex, to better reflect how my overall project is operating):
TARGETS = common test
FLAGS = -lpthread
DEPS = common.h
all: $(TARGETS)
common: common.cc $(DEPS)
g++ $^ $(FLAGS) -g -o $#
test: test.cc $(DEPS)
g++ $(FLAGS) $^ -g -o $#
clean::
rm -fv $(TARGETS) *~
The compiler seems happy compiling common.cc, but runs into an unresolved identifier error on test.cc:
g++ -lpthread test.cc common.h -g -o test
/tmp/ccMwBGAj.o: In function `main':
/home/...../test.cc:6: undefined reference to `foo()'
Am I missing something here?
Thanks!
First, notice that when you try to build test, the only files you use are test.cc and common.h. The code in test.cc calls the function foo(), but that function is not defined in either of those files; it is defined in common.cc, which was not invited. And if you try to fix that by adding common.cc or common.o to the recipe, you'll run into more trouble, because common.cc contains a definition of main(), and so does test.cc, and there can be only one.
If you want to use foo() with other versions of main(), you should not put a main() in common.cc.
Now for the makefile recipe:
test: test.cc $(DEPS)
g++ $(FLAGS) $^ -g -o $#
This expands to:
test: test.cc common.h
g++ -lpthread test.cc common.h -g -o test
Which is incorrect, as #NeilButterworth has pointed out. You could do this:
test: test.cc common.cc
g++ test.cc common.cc -lpthread -g -o test
which can be written as:
test: test.cc common.cc
g++ $^ $(FLAGS) -g -o $#
But that can fail to rebuild when common.h is changed, and when it does rebuild it can recompile a source that hasn't changed. A better approach is:
common.o: common.cc $(DEPS)
g++ -c $< -g -o $#
test.o: test.cc $(DEPS)
g++ -c $< -g -o $#
common: common.o
g++ $^ $(FLAGS) -o $#
test: test.o common.o
g++ $^ $(FLAGS) -o $#
And further improvement is possible, once you have this much working.

C++ makefile while seperate the declaration and implementation

I wrote a small simple SQL interpreter in C++, in my main.cpp
the code is something like
#include "lexer.h"
#include "parser.h"
#include "interpreter.h"
using namespace std;
int main(int argc, char* argv[]) {
//my code
}
In lexer.h,parser.h, interpretor.h, each contain the declaration and implementation of a class with the same name of the header file.My question is how should I write my makefile so that I can separate the declaration and implementation, for example, declaration in lexer.h, implementation in lexer.cpp ?
The simplest way to do it is like below
interpreter: main.cc lexer.cc parser.cc interpreter.cc
g++ -o interpreter main.cc lexer.cc parser.cc interpreter.cc -I
but sometimes is useful to use different targets. This is because if you modify a single file in your project, you don't have to recompile everything, only what you modified.So you can do like below
Using dependencies
all: interpreter
interpreter: main.o lexer.o parser.o interpreter.o
g++ main.o lexer.o parser.o interpreter.o -o interpreter
main.o: main.cc
g++ -c main.cc
lexer.o: lexer.cc
g++ -c lexer.cc
parser.o: parser.cc
g++ -c parser.cc
interpreter.o: interpreter.cc
g++ -c interpreter.cc
clean:
rm -rf *o hello
Using variables and comments
We can also use variables when writing Makefiles
# Implementing a new sql lexer the variable CC will be
# the compiler to use.
CC=g++
# these flags will be passed to the compiler.
CFLAGS=-c -Wall
all: interpreter
interpreter: main.o lexer.o parser.o interpreter.o
$(CC) main.o lexer.o parser.o interpreter.o -o interpreter
main.o: main.cc
$(CC) $(CFLAGS) main.cc
lexer.o: lexer.cc
$(CC) $(CFLAGS) lexer.cc
parser.o: parser.cc
$(CC) $(CFLAGS) parser.cc
interpreter.o: interpreter.cc
$(CC) $(CFLAGS) interpreter.cc
clean:
rm -rf *o hello

MakeFile : Header in different Directory - Error

I am trying to avoid relative paths in header declaration of C++ files. So, I had used the makefile by following an online example. But I am getting error. Please check the code and help me to resolve this
COMPILER = g++
IDIR = ./include
CXXFLAGS += -I$(IDIR)
CFLAGS += -I$(IDIR)
EXEC = hello
OBJECTS = main.o factorial.o hello.o
all: $(EXEC)
(---- I had also used CFLAGS instead of CXXFLAGS below but the same result###)
$(EXEC): $(OBJECTS)
$(COMPILER) $(CXXFLAGS) $(OBJECTS) -o $(EXEC)
main.o: main.cpp ./include/functions.h
$(COMPILER) $(CXXFLAGS) -c main.cpp
factorial.o: main.cpp ./include/functions.h
$(COMPILER) $(CXXFLAGS) -c factorial.cpp
hello.o: main.cpp ./include/functions.h
$(COMPILER) $(CXXFLAGS) -c hello.cpp
Error:
make: * No rule to make target 'include / functions.h "
required by "main.o" to create. Closing.
Directory Structure is
- main.cpp
- factorial.cpp
- hello.cpp
- MakeFile.mk
- +include (dir)
----->functions.h
main.cpp contains ----include "functions.h"---- in the header declaration
You are not using h files as a source files.
there should only be:
main.o: main.cpp
$(COMPILER) $(CXXFLAGS) -c main.cpp
edited:
I copy your folder content and write simple application where hello.cpp have a simple void function, factorial.cpp have simple int-returning function ane main.cpp have int main() and uses this functions, include.h hafe declarations of these two dummy functions.
Now. My makefile looks:
COMPILER = g++
IDIR = ./include
CXXFLAGS += -I$(IDIR)
EXEC = hello
OBJECTS = main.o factorial.o hello.o
all: $(EXEC)
$(EXEC): $(OBJECTS)
$(COMPILER) $(CXXFLAGS) $(OBJECTS) -o $(EXEC)
main.o: main.cpp factorial.o hello.o
$(COMPILER) -c $(CXXFLAGS) $^ -o $#
factorial.o: factorial.cpp
$(COMPILER) -c $(CXXFLAGS) $^ -o $#
hello.o: hello.cpp
$(COMPILER) -c $(CXXFLAGS) $^ -o $#
download for my sample
That should help You!
This is a pure make error message. The error is not related to the content of any .cpp or .h file. The error actually can come only from the content of the Makefile, and of the presence or absence of the files named in it.
As per this error message, make states that it cannot find the file include/functions.h. Double check it actually is here, with correct name and matching case.
For debugging purpose you can add the following lines to your Makefile:
./include/functions.h:
touch $#
It will instruct make to create an empty include/functions.h file if it's missing.

Creating static library in a makefile, using linux g++ compiler

I have simple files:
hello.h , hello.cpp
I have created a makefile in order to generate a static library (libhello.a)
but I'm getting error message , what am I doing wrong?
My code is:
CC = g++
CFLAGS = -Wall -g
utilObjs = hello.o
libhello.a: $(utilObjs)
ar rc $# $(utilObjs)
ranlib $#
hello: hello.o libhello.a
$(CC) $(CFLAGS) hello.o -L ./ -lutil -o $#
hello.o: hello.cpp hello.h
$(CC) $(CFLAGS) -c $>
clean:
rm -rf *.o libhello.a hello
all: hello
.PHONY: all clean
The error message :
g++: fatal error: no input files
compilation terminated
I don't think $> means anything special, change it to $< , which expands to the first prerequisite of the rule. (hello.cpp in this case)