I want to set up GLFW3 to work with C++ in a program called 4coder. I have a folder named libraries that holds all the stuff I need, I just don't know how to get C++ to include them using #include <GLFW/glfw3.h>. I literally started using C++ today and have no idea where to start.
You will need to add arguments when compiling the source code to specify the location of your headers and libraries. Exactly how this is done will depend on which compiler you are using but for example if you're using g++:
path-to-working directory>g++ name-of-file.cpp -Ipath-to-header-files -Lpath-to-library-files -lglfw3 -o name-of-executable
The key points here are the -I flag (which tells the compiler where to look for header files) and the -L flag (which tells the compiler where to look for libraries). -lglfw3 will then cause the compiler to look in the directory specified with the -L flag for the glfw3 library.
If you're using a different compiler, the syntax may be different but the general principle will apply - you just have to find the equivalent commands to -I and -L.
I have no idea what I am doing. I decided to use Vim as my only editor, I'm trying to set up autocompletion and syntax checking.
So I need to configure a .ccls file in the root of my project (and I don't want to generate a compile_commands.json file so please don't tell me about it). But there is no detailed documentation whatsoever on .ccls because all it does is use compiler flags, which of course I don't know; I have started not too long ago in C++ and I don't know any CMake, I was used to just run my code from the IDE!
I know that the default code to put in my .ccls is the path to my includes, which I do put (which are 5 paths that I get using clang++ -E -x c++ - -v < /dev/null) and I'm on mac btw. I put these, I get autocompletion, but my source breaks with errors telling things like iostream and every other header does not exist in /usr/local/include even though I provided 4 other paths (it really doesn't exit in /usr/local/include I don't know where iostream and those others are) and that I can't cout << "Hello, World!" << endl for example because ostream and char[] are incompatible and things like that. BTW even if I use compile_commands.json I still get errors it only fixes my header paths.
Can someone just explain how to use .ccls? No links, just plain explanation. Or at least a default configuration to get me going.
P.S Do I also need to provide paths to my project's header files?
This is my .ccls:
clang++
%cxx -std=c++17
%cxx -stdlib=libc++
%hxx --include=Global.h
%cxx -I/usr/local/include
%cxx -I/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1
%cxx -I/Library/Developer/CommandLineTools/usr/lib/clang/12.0.0/include
%cxx -I/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include
%cxx -I/Library/Developer/CommandLineTools/usr/include
I may be wrong, but I would keep it simple and simply put these lines in the .ccls file
clang
-std=c++17
-stdlib=libc++
-isystem/usr/local/include
-isystem/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1
-isystem/Library/Developer/CommandLineTools/usr/lib/clang/12.0.0/include
-isystem/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include
-isystem/Library/Developer/CommandLineTools/usr/include
If it works with this at first, then you could prefix all these lines with %cxx %c -- well, -std=c++17, -stdlib=libc++ and ..../include/c++/v1 are just for C++ though.
BTW, I'm not sure if the first line shall be clang or clang++.
Note: I've used -isystem because of the following:
You can use -I to override a system header file, substituting your own version, since these directories are searched before the standard system header file directories. However, you should not use this option to add directories that contain vendor-supplied system header files; use -isystem for that. -- https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html
What I am asking might sound illogical but it is very important for me.
Lets assume we have such file and folders
project_rat/
project_cat/
project_rabbit/
Makefile
The user might add any project folder here. The Makefile has the following config variable:
model_name:= project_rat
The user might change this model_namevariable to any of the folders.
and the makefile compiles the appropriate project folder.
g++ -std=c++11 $(model_name)/main.cpp
Now my problem is that I want to add a debug/release variable into the Makefile and based on that I turn on the appropriate optimizer. I want this variable be determined from my project. It must depend on each individual project. One project might need -O2 and the other -O3.
Can I influence Makefile from any C++ code?
Assuming that you're using GNU make (a safe bet, given your usage of gcc), add this to your Makefile:
include $(model_name)/Makefile.opts
Now, create a file Makefile.opts in each project directory, that sets the Makefile options for that project.
This works just like the C/C++ #include preprocessor directive.
If you do not want to require a Makefile.opts in each project directory, use sinclude instead of include.
I just started to learn C/C++, but I'm a bit confused. I often see the #include preprocessor directive, with a header file argument:
#include <stdio.h>
#include <iostream.h>
#include "windows.h"
#include <math.h>
But sometimes the .h is missing:
#include <iostream>
I already know, that the header file contains the signatures of the functions only, and some preprocessor commands. But when and how does the compiler include the math functions, if I include math.h?
If I create a library, then where to put the .c/.cpp/.h files, and how to include them?
When you install the compiler, the standard header and library files are also installed into well-known locations. For example, on a Linux or Unix system, the standard headers are typically installed under /usr/include or /usr/local/include and the standard libraries are typically installed under /usr/lib or /usr/local/lib.
When you #include the header file, the compiler will look for it in different places depending on whether you use the angle brackets (#include <stdio.h>) or quotes (#include "myfile.h"). For example, if you include a header file in angle brackets, gcc will search for that header in the following directories:
/usr/local/include
libdir/gcc/target/version/include
/usr/target/include
/usr/include
If you include a header file with quotes, gcc will first search the current working directory, then additional directories as specified by command-line options, and finally the standard include paths above.
Most compilers allow you to specify additional include paths as arguments to compile command, such as
gcc -o executable-name -I /additional/include/path source-files
But sometimes the .h is missing:
#include <iostream>
This is the C++ convention1; C++ standard headers do not have the .h extension, I guess to make it look more object-oriented than it really is (that is, you can pretend you're importing the class directly, rather than including the text of the file that describes the class).
I already know, that the header file contains the signatures of the functions only, and some preprocessor commands. But when and how does the compiler include the math functions, if I include math.h?
The implementations of the math functions are typically kept in a separate library (code that's already been compiled and archived into a single binary file); depending on the compiler, the math library may or may not be automatically linked into the executable. For example, gcc does not automatically link in any math library functions, even if you include the math.h header file. You have to explicitly include the math library as part of the build command:
gcc -o executable-name command-line-options source-files -lm
With gcc, the convention is that -lname links in a library named libname.a2. The standard math library file is named libm.a, so -lm tells gcc to link in the machine code that's contained within libm.a.
Like the standard headers, the compiler will search for the standard libraries in well-known locations. You can specify additional search paths for libraries that aren't part of the standard installation, like so:
gcc -o executable-name command-line-options source-files -L /additional/library/path -ladditional-library
If I create a library, then where to put the .c/.cpp/.h files, and how to include them?
You can put the files pretty much anywhere you want; you'll specify where they are as part of the build command. So, say you're creating a new library named mylib. You create a new directory under your home directory:
mkdir ~/mylib
cd ~/mylib
Then you create and edit your source files and headers:
cd ~/mylib
vi mylib.h
vi mylib.c
To build mylib as a static library, do the following:
cd ~/mylib
gcc -c mylib.c
ar libmylib.a mylib.o
So when you're done, the directory ~/mylib contains the following:
libmylib.a
mylib.c
mylib.h
mylib.o
To use the functions collected in mylib in a program, you'd specify the header and library include paths as part of the compile command:
gcc -o executable-name command-line-options source-files -I ~/mylib -L ~/mylib -lmylib
So, if you include "mylib.h" in another program, this will tell the compiler to search for that header in ~/mylib, and it will tell the linker that the libmylib.a library will be found under ~/mylib.
In a real-world situation you'd handle all of the builds with makefiles instead of building everything by hand. You'd also probably set it up so that as part of the build process, all the headers that anyone else would need to use your library would be copied to a separate include subdirectory, and the library would be written to a separate lib subdirectory, so you could distribute your library without exposing your source code. In that case, the build command above would look more like:
gcc -o executable-name command-line-options source-files -I ~/mylib/include -L ~/mylib/lib -lmylib
1. This hasn't always been the case; the earliest implementations of C++ used iostream.h, vector.h, etc. I'm not sure exactly when that convention changed, but it's been a while.
2. Actually, I'm not sure anymore if this is a gcc convention or a *nix convention; the two have been joined at the hip for so long it's hard to remember sometimes.
Actually, the compiler doesn't know anything about other source files, it only knows about the current translation unit. It's the job of the linker to take all translation units and link them together with the libraries to create the executable program, and it's the linker that will resolve all definitions and that notice missing function definitions.
Traditionally, working with C or C++ is a four step process:
Edit files
Compile source files into object files
Link object files and libraries to generate the executable program
Run the program.
The preprocessor is usually built into the compiler, so preprocessing and compiling is only a single step.
As for the "missing" .h, none of the C++-only standard library header files have that extension.
Standard Template Library headers, such as < algorithm > include source code for the template functions, which get instantiated at compile time, based on the template type(s) involved in source code calls to template functions.
A library is a collection of object files in a single library file. The linker normally only includes the object files needed to satisfy the references to functions or data to build the program, not the entire library file. The exception to this is a dynamic link library, since all of that library will be loaded (if not already loaded) at program load time.
The compiler has default locations for headers using < > and using " ". The headers using " ", can include relative or absolute paths. The relative path may vary depending on the tool set.
Re
” How a compiler knows from a header file, that a source file exists somewhere?
Generally, how a compiler locates header files, or if they are files, depends on the compiler.
But usually one or more of the following mechanisms are used:
The compiler knows its own program location, and can look for include directories for standard headers, relative to that location. g++ does this.
The compiler can be configured with paths to include directories in one or more environment variables. E.g. g++ uses CPATH (among others), and Visual C++ uses INCLUDE (and possibly more).
The compiler can accept include directory paths as command line options. Typically this is -I or with Visual C++, alternatively /I.
The compiler can be configured via a configuration file in a well known location. For example, g++ uses a specs file.
The compiler can accept one or more configuration files as command line options. E.g. Visual C++ accepts so called "response files", and g++ accepts specs files, although with slightly different semantics than the general configuration specs file.
Possibly there are more mechanisms in use, but the above are the most common ones.
Re
” But when and how does the compiler include the math functions, if I include math.h?
It doesn't.
The whole of the standard library is linked in regardless of what headers you include. Depending on the quality of the implementation the unused parts of the standard library are then discarded.
When you use a 3rd party library you will generally have to explicitly link with that library, in addition to including one or more of its headers. The Visual C++ compiler supports #pragma directives that can be placed in headers and serve to automatically direct the linker. But this is not standardized, and e.g. g++ does not support that automagic mechanism.
Re
” If I create a library, then where to put the .c/.cpp/.h files, and how to include them?
Essentially you have free reins, you can do it any way you want. Which is problematic because users of a C++ library have to deal with different conventions and tools for each library, to the extent of using a different OS to "configure" things. However, nowadays it's popular to employ CMake for libraries with separate compilation, which helps to reduce the DIY problems.
A nice alternative is to create a header only library, with all the code in headers. Large parts of Boost are header only. The advantage is that it's very easy to use, no configuration or toolset adaption or whatever, but with currently popular 1950's build technology it can cause longer build times.
I am trying to use OpenBabel and am experiencing great difficulty with setting up a global search path for include files. I have successfully linked to the libraries with $LD_LIBRARY_PATH, but when compiling with the GNU C++ compiler, it cannot find the include files. Is there a global include environment variable on Linux, and if so, what is it?
You could give the include path to GCC using the option -I:
g++ -I/path/to/the/include/dir blabla
Please note that also the library dir may be bassed via -L option -L/path/to/lib/dir. LD_LIBRARY_PATH is usually considered a dirty hack.
You can have multiple -I (and -L) options:
g++ -I/dir/include1 -I/dir/include2
If you check the manpage for cpp (the C Preprocessor), it state that it will treat the following environment variables like the -I option mentioned above:
CPATH
C_INCLUDE_PATH
CPLUS_INCLUDE_PATH
Now, I believe that current g++ and gcc use an inbuilt cpp, but I would expect that it would function like the stand alone cpp, and respect these environment variables.