'C++ Make file - cannot include Thrift library

I am trying to compile my example Thrift (client-server) program. I've got Thrift installed in the path $HOME/thrift/lib, but I cannot resolve why the compiler is giving me errors, that cannot include thrift includes. My make file looks like this:

all: client server

# Generate source files from Thrift IDL
gen-cpp/Example.cpp: Example.thrift
    thrift --gen cpp Example.thrift

# Compile server from main source and generated sources
server: server.cpp gen-cpp/Example.cpp
    g++ --std=c++17 -L$HOME/thrift/lib -Igen-cpp:$HOME/thrift/include/thrift -o server server.cpp gen-cpp/Example.cpp -lthrift

# Compile client from main source and generated sources
client: client.cpp gen-cpp/Example.cpp
    g++ --std=c++17 -L$HOME/thrift/lib -Igen-cpp:$HOME/thrift/include/thrift -o client client.cpp gen-cpp/Example.cpp -lthrift

clean:
    rm -f client
    rm -f server
    rm -rf gen-cpp


.PHONY: all clean

After I run the make command I get results like this:

g++ --std=c++17 -LOME/thrift/lib -Igen-cpp:OME/thrift/include/thrift -o client client.cpp gen-cpp/Example.cpp -lthrift
client.cpp:7:10: fatal error: thrift/protocol/TProtocol.h: No such file or directory
    7 | #include <thrift/protocol/TProtocol.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
In file included from gen-cpp/Example.cpp:7:
gen-cpp/Example.h:10:10: fatal error: thrift/TDispatchProcessor.h: No such file or directory
   10 | #include <thrift/TDispatchProcessor.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make: *** [Makefile:13: client] Error 1

Do you see something I'm missing or I'm doing wrong? Thank you for all your responses.



Solution 1:[1]

If you look at the output that make prints when it prints the command line, it's quite obvious there's something wrong:

g++ --std=c++17 -LOME/thrift/lib -Igen-cpp:OME/thrift/include/thrift ...

What is -LOME/thrift/lib and -Igen-cpp:OME/thrift/include/thrift? Those can't possibly be right: those directories don't exist. So, clearly there's something wrong in your makefile, with the recipe you're using:

g++ --std=c++17 -L$HOME/thrift/lib -Igen-cpp:$HOME/thrift/include/thrift ...

And indeed, there is. The $ is special to make: it introduces make variables. If you want to use $ so it's passed to the shell in your recipes, you have to escape it by doubling it: $$.

If you rewrite your recipe like this:

g++ --std=c++17 -L$$HOME/thrift/lib -Igen-cpp:$$HOME/thrift/include/thrift ...

then you'll see that make will invoke the command with the single unescaped $:

g++ --std=c++17 -L$HOME/thrift/lib -Igen-cpp:$HOME/thrift/include/thrift ...

and it will work. Alternatively, you could use the make variable here, but then you have to enclose it in () or {} (they are the same):

g++ --std=c++17 -L$(HOME)/thrift/lib -Igen-cpp:$(HOME)/thrift/include/thrift ...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MadScientist