I've been learning c++ and encountered the following question:
I have a directory structure like:
- current directory
- Makefile
- include
- header.h
- src
- main.cpp
my header.h :
#include <iostream>
using namespace std;
void print_hello();
my main.cpp:
#include "header.h"
int main(int argc, char const *argv[])
{
print_hello();
return 0;
}
void print_hello()
{
cout<<"hello world"<<endl;
}
my Makefile:
CC = g++
OBJ = main.o
HEADER = include/header.h
CFLAGS = -c -Wall
hello: $(OBJ)
$(CC) $(OBJ) -o $#
main.o: src/main.cpp $(HEADER)
$(CC) $(CFLAGS) $< -o $#
clean:
rm -rf *o hello
And the output of make is:
g++ -c -Wall src/main.cpp -o main.o
src/main.cpp:1:20: fatal error: header.h: No such file or directory
compilation terminated.
Makefile:10: recipe for target 'main.o' failed
make: *** [main.o] Error 1
What mistakes I have made in here. It's frustrating. Really appreciate any advice!
You told the Makefile that include/header.h must be present, and you told the C++ source file that it needs header.h … but you did not tell the compiler where such headers live (i.e. in the "include" directory).
Do this:
CFLAGS = -c -Wall -Iinclude
You can either add a -I option to the command line to tell the compiler to look there for header files. If you have header files in include/ directory, then this command should work for you.
gcc -Iinclude/
Since, you are using makefile, you can include this option in CFLAGS macro in your makefile.
CFLAGS = -Iinclude/ -c -Wall
OR
You can include header files using #include "../include/header.h".
Perhaps change your include line:
#include "include/header.h"
Assuming that's where your header exists - I'm making that assumption from your makefile
Related
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!
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
I am trying to use Google Test framework: https://github.com/google/googletest/tree/master/googletest .
I have 4 files:
factorial.cpp:
#include "factorial.h"
int factorial(int n) { [some code here] }
facotrial.h:
int factorial(int n);
test_factorial.cpp
#include "gtest/gtest.h"
#include "factorial.h"
[some tests here]
gtest_main.cpp:
#include <stdio.h>
#include "gtest/gtest.h"
GTEST_API_ int main(int argc, char **argv) {
printf("Running main() from gtest_main.cc\n");
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Also I have a makefile which contains (among other things):
INCLUDES = -I/home/my_username/Documents/gtest/googletest/googletest/include
[...]
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
After writing make in terminal I get:
test_factorial.cpp:1:25: fatal error: gtest/gtest.h: No such file or directory
compilation terminated.
makefile:27: recipe for target 'test_factorial.o' failed
What is the issue?
In the README file on googletest they say:
g++ -isystem ${GTEST_DIR}/include -pthread path/to/your_test.cc libgtest.a \
-o your_test
So here it's -isystem instead of -I but I had problems with -isystem as well.
You've added your includes to the link command, but not to the compile command. This rule:
$(MAIN): $(OBJS)
$(CC) $(CFLAGS) $(INCLUDES) -o $(MAIN) $(OBJS) $(LFLAGS) $(LIBS)
tells how to link the main program from the object files. This rule isn't used to compile the object files: assuming that your [...] doesn't elide a compile rule, you're using the built-in compiler rule which doesn't know anything about the INCLUDES variable.
If you would have shown us the compile command make printed when you got that error for test_factorial.cpp it would have been clear that the flag was missing.
If you don't make up your own variable to hold these flags and instead use the CPPFLAGS variable which is the standard variable for C preprocessor flags like -I, it will just work.
CPPFLAGS = -I/home/my_username/Documents/gtest/googletest/googletest/include
it may just work.
In my project files I just want to be able to say:
main.cpp:
#include <foo.h>
#include <bar.h>
When these headers files reside in separate
-Project
-include
-foo
foo.h
-bar
bar.h
-src
main.cpp
I've setup my make file to attempt to achieve this but I still get fatal error: foo.h: No such file or directory so I haven't been able to set it up correctly.
Makefile:
LIBS = ./include/foo ./include/bar
all:
g++ -o bin/myapp src/main.cpp $(LIBS) -std=c++11
Is LIBS correct? How can I achieve relative/agnostic include paths?
INCLUDES = -I./include/foo -I./include/bar
all:
g++ -o bin/myapp src/main.cpp $(INCLUDES) -std=c++11
This is a really specific compilation problem involving C++, SWIG and Lua.
I have a really simple base code :
[AClass.hpp]
class AClass {
public:
AClass();
};
[AClass.cpp]
#include "AClass.hpp"
AClass::AClass() {}
[main.cpp]
#include "AClass.hpp"
int main() {
AClass my_a;
}
At this point, there is no matter with compilation.
I first compile the class in libengine.dll and then use the shared library to build the executable.
Let's introduce a SWIG module, and add it to the dll :
[AClass.i]
%module M_AClass
%{
#include "AClass.hpp"
%}
%include "AClass.hpp"
Henceforth, when linking everything in an executable, I got the following error :
g++ -c main.cpp
g++ -c AClass.cpp
swig.exe -c++ -lua AClass.i
g++ -Iinclude -c AClass_wrap.cxx
g++ AClass.o AClass_wrap.o -shared -o libengine.dll -Wl,--out-implib,libengine.dll.a -L. -llua5.1
Creating library file: libengine.dll.a
g++ main.o libengine.dll.a -o main.exe
main.o:main.cpp:(.text+0x16): undefined reference to `AClass::AClass()'
collect2: ld returned 1 exit status
Would anyone have a clue ? I tried looking into the dll with nm but I can't figure how adding another .o to the shared library can "hide" a method (this isn't specific to constructors).
To reproduce the context, here are the necessary files to put in a directory to build the test :
include/ # Contains "lauxlib.h", "lua.h" & "luaconf.h"
liblua5.1.dll
AClass.hpp
AClass.cpp
AClass.i
main.cpp
Makefile
And finally, here is the Makefile content :
ifneq (,$(findstring Linux,$(shell uname -o)))
EXEC := main
LIB := libengine.so
LIB_FLAGS := -o $(LIB)
else
EXEC := main.exe
LIB := libengine.dll.a
LIB_FLAGS := -o libengine.dll -Wl,--out-implib,$(LIB)
#NO DIFFERENCE using ".dll.a" as in CMake (option: -Wl,--out-implib,) or only ".dll"
ifdef SystemRoot
# Pure Windows, no Cygwin
RM := del /Q
endif
endif
LANG_LIB := -L. -llua5.1
LANG_INC := include
LANG_SWIG := -lua
all: clean $(EXEC)
clean:
$(RM) main *.exe *_wrap.cxx *.o libengine.*
$(EXEC): main.o $(LIB)
g++ $^ -o $#
main.o: main.cpp
g++ -c $<
#NO PB without dependency to AClass_wrap.o
$(LIB): AClass.o AClass_wrap.o
g++ $^ -shared $(LANG_LIB) $(LIB_FLAGS)
AClass.o: AClass.cpp
g++ -fPIC -c $<
AClass_wrap.o: AClass_wrap.cxx
g++ -fPIC -I$(LANG_INC) -c $<
AClass_wrap.cxx: AClass.i
swig -c++ $(LANG_SWIG) $<
This was tested under Windows Seven, with MingGW g++ v4.5.2, SWIG 2.0.2 and Lua5.1.
EDIT: The problem also appear when SWIG-exporting to tcl. However, there is absolutely no problem compiling under Linux. I compared the generated AClass_wrap.cxx, they are similar.
g++ under mingw might require __declspec(dllimport/export)