Makefile and errors compiling separate files from a big project - c++

I'm trying to compile a small .cpp file but running into issues since this file utilizes functions found in many other files. Basically, I cloned the ZCash repo and am currently trying to use specific files in that project to do some testing. When I compile the entire ZCash repo that I cloned everything works perfectly, but when I try to compile the files I'm working with some of them get syntax errors.
My Makefile:
CC = g++
CFLAGS = -std=c++11 -Wall -g -c
IDIR = /home/parallels/zcash/src/
INC = -I /home/parallels/zcash/src/ -I
/home/parallels/zcash/depends/x86_64-unknown-linux-gnu/include/
VPATH = /home/parallels/zcash/src/
all: Main.o KeyGen.o prf.o uint256.o sha256.o
$(CC) Main.o KeyGen.o prf.o uint256.o sha256.o -o keygenerator
Main.o: Main.cpp
$(CC) $(CFLAGS) Main.cpp $(INC)
KeyGen.o: KeyGen.cpp
$(CC) $(CFLAGS) KeyGen.cpp $(INC)
prf.o: prf.cpp
$(CC) $(CFLAGS) prf.cpp $(INC)
uint256.o: uint256.cpp
$(CC) $(CFLAGS) uint256.cpp $(INC)
sha256.o: sha256.cpp
$(CC) $(CFLAGS) sha256.cpp $(INC)
clean:
rm -rf *.o keygenerator
The .cpp files being compiled reference these other files:
Main.cpp:
#include "KeyGen.h"
#include "uint252.h"
#include "uint256.h"
#include <string>
KeyGen.cpp
#include "KeyGen.h"
#include "prf.h"
prf.cpp
#include "prf.h"
#include "crypto/sha256.h"
uint256.cpp
#include "uint256.h"
#include "utilstrencodings.h"
#include <stdio.h>
#include <string.h>
sha256.cpp
#include "crypto/sha256.h"
#include "crypto/common.h"
#include <string.h>
#include <stdexcept>
So, after I try to compile these files I get the following error:
g++ -std=c++11 -Wall -g -c Main.cpp -I /home/parallels/zcash/src/ -I /home/parallels/zcash/depends/x86_64-unknown-linux-gnu/include/
g++ -std=c++11 -Wall -g -c KeyGen.cpp -I /home/parallels/zcash/src/ -I /home/parallels/zcash/depends/x86_64-unknown-linux-gnu/include/
g++ -std=c++11 -Wall -g -c prf.cpp -I /home/parallels/zcash/src/ -I /home/parallels/zcash/depends/x86_64-unknown-linux-gnu/include/
g++ -std=c++11 -Wall -g -c uint256.cpp -I /home/parallels/zcash/src/ -I /home/parallels/zcash/depends/x86_64-unknown-linux-gnu/include/
g++ -std=c++11 -Wall -g -c sha256.cpp -I /home/parallels/zcash/src/ -I /home/parallels/zcash/depends/x86_64-unknown-linux-gnu/include/
In file included from /usr/include/x86_64-linux-gnu/bits/byteswap.h:35:0,
from /usr/include/endian.h:60,
from /usr/include/x86_64-linux-gnu/bits/waitstatus.h:64,
from /usr/include/stdlib.h:42,
from /home/parallels/zcash/src/crypto/sha256.h:9,
from sha256.cpp:5:
/home/parallels/zcash/src/compat/endian.h:111:17: error: expected unqualified-id before ‘__extension__’
inline uint16_t htobe16(uint16_t host_16bits)
^
In the offending file /home/parallels/zcash/src/compat/endian.h:111:17, htobe16 is used as follows:
#if HAVE_DECL_HTOBE16 == 0
inline uint16_t htobe16(uint16_t host_16bits) //line #111
{
return bswap_16(host_16bits);
}
#endif // HAVE_DECL_HTOBE16
There also exists a file: /usr/include/endian.h who references htobe16 as follows.
# include <bits/byteswap.h> //line #60
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define htobe16(x) __bswap_16 (x)
# define htole16(x) (x)
# define be16toh(x) __bswap_16 (x)
# define le16toh(x) (x)
Note:
All the .cpp file I am compiling are located in both the ZCash repo that I cloned and the new folder I created (wondering if this might be the issue).
The folder I'm currently working on contains :
KeyGen.cpp
KeyGen.h
Main.cpp
Makefile
prf.cpp
prf.h
serialize.h
sha256.cpp
sha256.h
uint252.h
uint256.cpp
uint256.h
Sorry for the long post, I truly appreciate your time and would really appreciate some help!

The inline functions are already declared by several macros with the same name. Similar to this question: error: expected unqualified-id before ‘__extension__’ in Linux (Cent OS)
Could have to do with a unconfigured part of the slice you're building from the whole project as this Github discussion seems to indicate:
https://github.com/bitcoin/bitcoin/issues/5920

Related

makefile include directory

I'm getting a strange error from my makefile when trying to compile multiple c files with an include directory.. I'm new to make so its kind of confusing for me but my directory structure looks like this
root\
main.c
test.c
makefile
inc\
test.h
These are the contents of each file
main.c
#include <test.h>
int main(){
maketest();
return 0;
}
test.c
#include <test.h>
void maketest(){
printf("This is a test");
}
test.h
#include <stdio.h>
void maketest();
and this is my makefile
OBJFILES = test.o main.o
TARGET = main
CXXFLAGS = -I./inc
.PHONY : all
All : $(OBJFILES)
$(CXX) $(CXXFLAGS) $(OBJFILES) -o $(TARGET)
When I run make I get this error
cc -c -o test.o test.c
test.c:1:10: fatal error: 'test.h' file not found
#include <test.h>
^~~~~~~~
1 error generated.
make: *** [test.o] Error 1
But the strange part is when I replace CXX with CC and CXXFLAGS with CFLAGS then it actually compiles
OBJFILES = test.o main.o
TARGET = main
CFLAGS = -I./inc
.PHONY : all
All : $(OBJFILES)
$(CC) $(CFLAGS) $(OBJFILES) -o $(TARGET)
This works and I get this output
cc -I./inc -c -o test.o test.c
cc -I./inc -c -o main.o main.c
cc -I./inc test.o main.o -o main
So I'm confused.. am I doing something wrong in the makefile? Is CFLAGS better than CXXFLAGS and should I be using CC instead of CXX? How come the include directory is found when I use CC and CFLAGS but not CXX And CXXFLAGS?
Thanks for the help it's greatly appreciated!

c++ "fatal error C1083: Cannot open include file: 'curl/curl.h': No such file or directory"

I want to use the https://github.com/tensaix2j/binacpp (a Binance c++ library) and I'm getting the same error again and again. I changed the MakeFile in the library to the correct paths but yeah... Here is my MakeFile:
libcurl_dir=../lib/libcurl-7.56.0
libcurl_include=${libcurl_dir}/include
libcurl_lib=${libcurl_dir}/lib
jsoncpp_dir=../lib/jsoncpp-1.8.3
jsoncpp_include=${jsoncpp_dir}/include
jsoncpp_src=${jsoncpp_dir}/src
libwebsockets_dir=../lib/libwebsockets-2.4.0
libwebsockets_include=${libwebsockets_dir}/include
libwebsockets_lib=${libwebsockets_dir}/lib
libbinacpp_dir=../lib/libbinacpp
libbinacpp_include=${libbinacpp_dir}/include
libbinacpp_lib=${libbinacpp_dir}/lib
build_dir=../lib/libbinacpp/lib
objects=$(build_dir)/jsoncpp.o $(build_dir)/binacpp_utils.o
$(build_dir)/binacpp_logger.o $(build_dir)/binacpp.o $(build_dir)/binacpp_websocket.o
build_include=../lib/libbinacpp/include
$(build_dir)/libbinacpp.so: $(objects)
g++ -I$(libcurl_include) -I$(jsoncpp_include) I$(libwebsockets_include) \
-L$(libcurl_lib) \
-L$(libwebsockets_lib) \
$(objects) \
-shared \
-lcurl -lcrypto -lwebsockets -fPIC -o $#
# Make a new copy of the header too
cp *.h $(build_include)
$(build_dir)/binacpp.o: binacpp.cpp binacpp.h
g++ -I$(libcurl_include) -I$(jsoncpp_include) -c binacpp.cpp -fPIC -o $(build_dir)/binacpp.o
$(build_dir)/binacpp_websocket.o: binacpp_websocket.cpp binacpp_websocket.h
g++ -I$(libwebsockets_include) -I$(jsoncpp_include) -c binacpp_websocket.cpp -fPIC -o $(build_dir)/binacpp_websocket.o
$(build_dir)/binacpp_logger.o: binacpp_logger.cpp binacpp_logger.h
g++ -c binacpp_logger.cpp -fPIC -o $(build_dir)/binacpp_logger.o
$(build_dir)/binacpp_utils.o: binacpp_utils.cpp binacpp_utils.h
g++ -c binacpp_utils.cpp -fPIC -o $(build_dir)/binacpp_utils.o
$(build_dir)/jsoncpp.o: $(jsoncpp_src)/jsoncpp.cpp
g++ -I$(jsoncpp_include) -c $(jsoncpp_src)/jsoncpp.cpp -fPIC -o $(build_dir)/jsoncpp.o
clean:
rm $(build_dir)/*.o
rm $(build_dir)/*.so
If I'm inserting the paths like:
#include "../../libcurl-7.56.0/include/curl/curl.h"
instead of:
#include <curl/curl.h>
then it works but I cant change it for all includes.
Here's the Tree:
binacpp
-example
-lib
--jsoncpp-1.8.3
--libbinacpp
---include
----binacpp.h (File with include issue)
----binacpp_logger.h
----binacpp_websocket.h
----binacpp_utils.h
---lib
--libcurl-7.56.0
--(here's some other not important stuff)
-src
--MakeFile
--(here's some other not important stuff)

Precompiled headers not used by GCC when building with a makefile

I'm trying to use precompiled headers with GCC to speed up the compilation process. If I launch the compilation directly from the command line the precompiled headers are used, but if I try to organize the compilation using a makefile they are not.
More specifically, I try to compile with GCC 8.1.0 a file main.cpp using a precompiled header lib.hpp.gch for the file lib.hpp included as first token in main.cpp.
lib.hpp is precompiled with
$ g++ -O2 -H -Wall -std=c++17 -c lib.hpp
main.cpp is then compiled with
$ g++ -O2 -H -Wall -std=c++17 -c main.cpp -o main.o
! lib.hpp.gch
...
and I can see from the "!" that the precompiled lib.hpp.gch is actually used.
If I write a makefile for this
CXX = g++
CXXFLAGS = -O2 -H -Wall -std=c++17
main.o: \
main.cpp \
main.hpp \
lib.hpp
$(CXX) $(CXXFLAGS) \
-c main.cpp \
-o main.o
and then use make, I would expect the same usage of the precompiled header
but instead it fails, as can be seen from the "x":
$ make
g++ -O2 -H -Wall -std=c++17 \
-c main.cpp \
-o main.o
x lib.hpp.gch
...
This is very strange, because the command issued by make seems exactly the same as the one that I used manually before.
I've also made measurement of timings and can confirm that the compilation via make is definitely slower than the manual one, confirming that the precompiled header is not used.
What's wrong in the makefile?
You're not including the PCH anywhere in your make command. Try this:
CXX = g++
CXXFLAGS = -O2 -H -Wall -std=c++17
OBJ = main.o #more objects here eventually I would think!
PCH_SRC = lib.hpp
PCH_HEADERS = headersthataregoinginyourpch.hpp andanother.hpp
PCH_OUT = lib.hpp.gch
main: $(OBJ)
$(CXX) $(CXXFLAGS) -o $# $^
# Compiles your PCH
$(PCH_OUT): $(PCH_SRC) $(PCH_HEADERS)
$(CXX) $(CXXFLAGS) -o $# $<
# the -include flag instructs the compiler to act as if lib.hpp
# were the first header in every source file
%.o: %.cpp $(PCH_OUT)
$(CXX) $(CXXFLAGS) -include $(PCH_SRC) -c -o $# $<
First the PCH gets compiled. Then all cpp commands get compiled with -include lib.hpp this guarantees that lib.hpp.gch will always be searched first before lib.hpp

expected type-specifier before 'classname'

I have been looking this up for a while and there are a bunch of solutions but I don't think they are quite what my problem is,
at the moment I have a folder with some classes for a 'UI' for my client, I have compiled and tested these classes separate to my main project and they all work great, and my current makefile for my project without this new package works fine, but when I add my new package to my project and update my makefile and include the new UI files in my main I get a problem saying that previous classes in my project that I have already tested no longer work, for a better Idea of what I mean here
Terminal:
make -f makeLedger2.mk
gcc -o sqlite3 SQLite/sqlite3.c SQLite/shell.c -lm -lrt -lpthread -ldl
g++ -c rsa/Number.cpp
g++ -c rsa/BigInt.cpp -lm -lrt -lpthread -ldl
g++ -c rsa/Rsa.cpp -lm -lrt -lpthread -ldl
g++ -c database/Entry.cpp
g++ -c rsa/Key.cpp
g++ -c database/PersonalDataBase.cpp -lm -lrt -lpthread -ldl
gcc -o sqlite.o -c SQLite/sqlite3.c -lm -lrt -lpthread -ldl
g++ -c ClientUI/UIOutput.cpp
g++ -c ClientUI/UserCommand.cpp
g++ -c ClientUI/KeyboardController.cpp
g++ -c Network/P2P/Network.cpp -lm -lrt -lpthread -ldl
g++ -c main.cpp -lm -lrt -lpthread -ldl
main.cpp: In function ‘int main()’:
main.cpp:23:11: error: ‘overlay’ was not declared in this scope
main.cpp:23:25: error: expected type-specifier before ‘Network’
main.cpp:23:25: error: expected ‘;’ before ‘Network’
make: *** [main.o] Error 1
The biggest problem here is this is untouched from before I updated my makefile, (i.e. my Network class does not run into this error before I include, or all my code would compile without the addition of this new package 'ClientUI')
my makefile:
CXX = g++
CC = gcc
LIB = -lm -lrt -lpthread -ldl
BIN = SQLite ledger database Network/P2P Control ClientUI
****Added : UIOutput.o UserCommand.o KeyboardController.o***
OBJECTS = Number.o BigInt.o Rsa.o LedgerEntry.o Entry.o Key.o PersonalDataBase.o sqlite.o UIOutput.o UserCommand.o KeyboardController.o Network.o main.o
VPATH = SQLite rsa database Network/P2P Control ClientUI
all : $(BIN)
sqlite3: sqlite3.c shell.c
$(CC) -o $# $^ $(LIB)
ledger: $(OBJECTS)
$(CXX) -o $# $^ $(LIB)
Number.o: rsa/Number.cpp rsa/Number.h
$(CXX) -c rsa/Number.cpp
BigInt.o: rsa/BigInt.cpp rsa/BigInt.h rsa/Number.h
$(CXX) -c rsa/BigInt.cpp$(LIB)
Rsa.o: rsa/Rsa.cpp rsa/Rsa.h rsa/BigInt.h rsa/Number.h
$(CXX) -c rsa/Rsa.cpp $(LIB)
Key.o: rsa/Key.cpp rsa/Key.h rsa/Number.h
$(CXX) -c rsa/Key.cpp
Entry.o: database/Entry.cpp database/Entry.h rsa/Number.h
$(CXX) -c database/Entry.cpp
PersonalDataBase.o: database/PersonalDataBase.cpp database/PersonalDataBase.h SQLite/sqlite3.h database/Entry.h rsa/Key.h
$(CXX) -c database/PersonalDataBase.cpp $(LIB)
*****NEW PACKAGE******
UIOutput.o: ClientUI/UIOutput.h ClientUI/UIOutput.cpp
$(CXX) -c ClientUI/UIOutput.cpp
UserCommand.o: ClientUI/UserCommand.cpp ClientUI/UserCommand.h
$(CXX) -c ClientUI/UserCommand.cpp
KeyboardController.o: ClientUI/KeyboardController.cpp
$(CXX) -c ClientUI/KeyboardController.cpp
*****NEW PACKAGE End******
Network.o: Network/P2P/Network.cpp
$(CXX) -c Network/P2P/Network.cpp $(LIB)
***Include KeyboardController below***
main.o: main.cpp database/PersonalDataBase.h Network/P2P/Network.h ClientUI/KeyboardController.h
$(CXX) -c main.cpp $(LIB)
sqlite.o: sqlite3.c
$(CC) -o $# -c $^ $(LIB)
clean:
rm -f $(BIN)
rm -f $(OBJECTS)
.PHONEY: all, clean
for New Dependencies,
Message includes UIOutput
UserCommand Extends Message (includes)
KeyboardController includes UserCommand
this makefile for jsut these files works (and a test main.cpp for them)
out: UIOutput.o UserCommand.o KeyboardController.o main.o
g++ -o out UIOutput.o UserCommand.o KeyboardController.o main.o
UIOutput.o: UIOutput.h UIOutput.cpp
g++ -c UIOutput.cpp
UserCommand.o: UserCommand.cpp UserCommand.h Message.h UIOutput.h
g++ -c UserCommand.cpp
KeyboardController.o: KeyboardController.cpp KeyboardController.h UserCommand.h Message.h UIOutput.h
g++ -c KeyboardController.cpp
main.o: KeyboardController.h main.cpp
g++ -c main.cpp
main.cpp
#include "Network/P2P/Network.h"
#include "rsa/BigInt.h"
#include "rsa/Number.h"
#include "rsa/Rsa.h"
#include "database/PersonalDataBase.h"
//****Litterally All I do is include it here and I get an issue
//if I commented it out I would be fine and all the .o files would be built, including my new ones, and this can compile
#include "ClientUI/KeyboardController.h"
#include <iostream>
#include <sys/time.h>
#include <stdlib.h>
#include <limits>
using namespace std;
using namespace BigIntOperators;
using namespace RSA;
int main()
{
Network *overlay = new Network("Alice", "LOLO1");
....
.....
I'm doing nothing different to how I import my other packages, and I have compiled all the newly added files and tested them without problem seperatley, furthermore the packages ClientUI shares no dependancies with any other file, except in my main function... what's happening here?

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