gcc compilation without using system defined header locations - c++

I am attempting to compile a c++ class using gcc. Due to the nature of the build, I need to invoke gcc from a non-standard location and include non-system defined headers, only to add a set from a different location. However, when I do this, I run into an issue where I cannot find some base symbols (suprise suprise). So i am basically running this command to compile my code:
-->(PARENT_DIR)/usr/bin/gcc # invoke compiler
-B$(PARENT_DIR)/usr/lib64/gcc/suselinux-x8664
-B$(PARENT_DIR)/usr/lib64
#C/C++ flags
-fPIC -fvisibility=default -g -c -Wall -m64 -nostdinc
# source files
-I$(SRC_DIR_ONE)/
-I$(SRC_DIR_TWO)
-I../include
# 'Mock' include the system header files
-I$(PARENT_DIR)/usr/include/c++/$(GCC_VERSION)
-I$(PARENT_DIR)/usr/include/c++/$(GCC_VERSION)/backward
-I$(PARENT_DIR)/usr/include/c++/$(GCC_VERSION)/x86_64-suse-linux
-I$(PARENT_DIR)/usr/lib64/x86_64-suse-linux/$(GCC_VERSION)/include
-I$(PARENT_DIR)/usr/lib64/gcc/x86_64-suse-linux/$(GCC_VERSION)/include
-I$(PARENT_DIR)/usr/lib64/gcc/x86_64-suse-linux/$(GCC_VERSION)/include-fixed
-I$(PARENT_DIR)/usr/src/linux/include
-I$(PARENT_DIR)/usr/x86_64-suse-linux/include
-I$(PARENT_DIR)/usr/include/suselinux-x8664
-I$(PARENT_DIR)/usr/suselinux-x8664/include
-I$(PARENT_DIR)/usr/include
-I$(PARENT_DIR)/usr/include/linux
file.cpp
I am getting several errors which indicate that the base headers are not being included: such as:
$(PARENT_DIR)/usr/include/c++/$(GCC_VERSION)/cstddef ::prtdiff_t has not been declared
$(PARENT_DIR)/usr/include/c++/$(GCC_VERSION)/cstddef ::size_t has not bee declared.
Is there something that I am doing wrong when I include the header file directories? Or am I looking in the wrong place?

Perhaps the --sysroot arg would help, see gcc docs.

Related

CMAKE - How to set different compiler options for a single file

I have a CMAKE file with the following compilation flags
set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} \
-fPIC -Wall -pedantic -Wextra -Werror \
-Wno-missing-braces -Wno-unused-variable \
-Wno-ignored-qualifiers -fdiagnostics-color")
I want to omit the -Wextra option for a single header file; /externals/include/foo.hpp (this is a third-party header-only library and gives error: [-Werror=unused-parameter] when compiled).
I have tried set_source_files_properties like this
set_source_files_properties(${EXTERNALS_SOURCE_DIR}/foo.hpp PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS_DEBUG} -Wno-extra")
but couldn't get rid of the compilation error.
Is there a way to do that either in CMAKE or using #pragmas in the header file itself?
Thanks.
SOLUTION
Here is how I got rid of the error:
Create a file foo_wrapper.hpp.
Add _pragma to ignore the trouble maker compilation flag
Use the wrapper header everywhere in the project instead of the actual header.
` // In file foo_wrapper.hpp:
_Pragma("GCC diagnostic push")
_Pragma("GCC diagnostic ignored \"-Wunused-parameter\"")
#include "foo.hpp"
_Pragma("GCC diagnostic pop")
`
On current compilers, it is not possible to do this through build options.
This is because of how the build model works: The compiler will get invoked once for every source file and all the header files included by that source file will invariably use the same build options as the source file itself.
So CMake will not be able to help you here.
Some compilers allow switching off certain warnings through #pragmas. For example, MSVC or gcc. Check your compiler's manual for what they offer in this regard. Unfortunately, this will always be non-portable, so if you have a code base supporting lots of compilers, the #pragmas can get lengthy. I would recommend writing a wrapper header that only includes the third party header giving you trouble and takes care of all the warning disabling. In your project you then always include the wrapper instead of the original third party header.

Why is clang reporting warnings on my header despite the use of -isystem, while gcc reports none?

Slightly related to this question but not the same.
Using clang 7.0.1 on Arch Linux. I like clean code, so I want to enable all warnings and treat them as errors.
The problem is that I have some autogenerated files in my build that are not free of warnings, e.g.:
generated/foo.h
inline void foo(int unused) { // warning: unused parameter 'unused'
}
generated/foo.cc
#include "foo.h"
// There is actual code here, but it doesn't matter.
Since these files are generated by a third-party tool, I cannot easily modify them, so I use -isystem to suppress all warnings from the generated directory.
I also have a main file that depends on the generated ones:
main.cc
#include "foo.h"
int main() {
foo(42);
}
With gcc, I can compile this just fine, even with all warnings enabled.
$ g++ -Wall -Wextra -pedantic -Werror -isystem generated -omain main.cc generated/foo.cc
With clang, however, it fails to compile generated/foo.cc:
$ clang++ -Wall -Wextra -pedantic -Werror -isystem generated -omain main.cc generated/foo.cc
In file included from generated/foo.cc:1:
generated/foo.h:1:21: error: unused parameter 'unused'
[-Werror,-Wunused-parameter]
inline void foo(int unused) {
^
1 error generated.
Adding --system-header-prefix does not help:
$ clang++ -Wall -Wextra -pedantic -Werror -isystem generated --system-header-prefix=generated/ -omain main.cc generated/foo.cc
In file included from generated/foo.cc:1:
generated/foo.h:1:21: error: unused parameter 'unused'
[-Werror,-Wunused-parameter]
inline void foo(int unused) {
^
1 error generated.
What does help is to replace #include "foo.h" by #include <foo.h> in the generated ("DO NOT MODIFY") code. This is hardly a proper fix, but it provides a clue: I suspect that clang is somehow finding foo.h in the current directory . instead of scanning the include path, and of course . is not marked as a system include directory.
This is actually almost documented:
A #include directive which finds a file relative to the current directory is treated as including a system header if the including file is treated as a system header.
However, it doesn't say what happens if the including file is not a header at all.
Workarounds that I can think of, none of which are great:
Postprocess the generated files before compiling them. E.g. by adding #pragma clang system_header. Ugly, and tricky to do in a very portable way.
Fiddle with the build system, CMake, to not enable warnings when compiling the generated .cc files. But this probably means I'll have to add a separate target for them, which means either duplicating lots of flags and configuration, or a DRY but more complex CMakeLists.txt.
I'd rather just set the right flags, like with gcc. Is this possible?
I underestimated CMake; this works without adding a lot of clutter:
set_source_files_properties(generated/foo.cc PROPERTIES COMPILE_FLAGS -w)

Decrease clang compile time with precompiled headers

I am working on a database project that compiles queries (expressed in some higher level language) into c++ code. This code is compiled and executed by the database. That part works perfectly fine.
Right now, I am trying to reduce the compile time for the C++ query code. I was wondering whether I can use precompiled headers to gain performance here.
The query is translated into a file called Query.cpp which includes library/src/Database.hpp. The Database.hpp file includes further files like StandardTypes.hpp and so on. Can I precompile all those header files to speed up the compilation of Query.cpp? If yes, how can I do that? I could not find any good example for precompiled headers so far, only some really basic stuff.
I use the following command to compile Query.cpp:
clang++ -fPIC -std=c++11 Query.cpp -I./library/src/ -shared -o libquery.so;
to create pre-compiled header include all the headers you don't change into Query.h and use:
clang -cc1 Query.h -emit-pch -o Query.h.pch
to use the pre-compiled header type:
clang -cc1 -include-pch Query.h.pch Query.cpp -shared -o libquery.so;
Query.cpp needs to include Query.h

compile <json/json.h> in eclipse using c++

I'm trying to include and compile
#include <json/json.h>
However even though I've installed it and included it on the project settings it wouldn't find the path.
here's what I've so far done:
path to libjson:
/usr/include/jsoncpp-src-0.5.0
options in eclipse gcc c++ compiler:
-Ijson_linux-gcc-4.5.2_libmt -O0 -g3 -Wall -c -fmessage-length=0 -ljson_linux-gcc-4.5.2_libmt
libraries in gcc c++ linker:
-L/usr/include/jsoncpp-src-0.5.0/include/
Anything else I forgot to do to make it work?
try adding -I/usr/include/jsoncpp-src-0.5.0 to compiler options
-L indicates where to find shared libraries (e.g. .so)
-I is the search path for the header files.
If the problem occurs during compilation (json.h not found), then you have indicated the wrong -I
If it occurs during linking (symbol not found), then you have indicated a wrong -L, a wrong -l, or forgot to run ldconfig

equivalent gcc flags for g++ call

I'm playing around with a toolchain that seems to wrap gcc (qcc), but also uses g++ for a few things. This caused a bit of confusion when I couldn't link libs I built with g++ using g(q)cc even though it was for the same architecture (due to missing lib errors). After a bit more research, I found that g++ is basically gcc with a few default flags and a slightly different interpretation mechanism for file extensions (there may be other differences I've glanced over). I'd like to know exactly which flags can be passed to gcc to amount to the equivalent g++ call. For instance:
g++ -g -c hello.cpp // I know at the very least that this links in stl
gcc -g -c -??? // I want the exact same result as I got with g++... what flags do I use?
The way the tool chain is set up makes it sort of difficult to simply replace the gcc calls with g++. It'd be much easier to know which flags I need to pass.
The differences between using gcc vs. g++ to compile C++ code is that (a) g++ compiles files with the .c, .h, and .i extensions as C++ instead of C, and that (b) it automatically links with the C++ standard library (-lstdc++). See the man page.
So assuming that you're not compiling .c, .h., or .i files as C++, all you need to do to make gcc act like g++ is add the -lstdc++ command line option to your linker flags. If you are compiling those other files as C++, you can add -x c++, but I'd advise you instead to rename them to use .cc or .ii files (.h can stay that way, if you're using precompiled headers).