TDM-GCC c++ compiler (Setting up) - c++

I'm now using TDM-GCC 64 bit compiler and have originally built all my libraries (dependencies for other libraries) and projects using this compiler to create 64 bit binaries (which is what I want).
Recently I have run into some build issues where I was building a Fast Light Tool Kit (gui toolkit) project which included math.h. This is where I ran into my first build issue and made me realize that I've probably set up my build environment incorrectly. Everything was built using MSYS.
My root directory is C:\mingw so when I configured each project I used the commands:
./configure --prefix=c:\mingw and the appropriate c:\mingw include and lib directories were created (c:\mingw\include & c:\mingw\lib).
FLTK contains a math.h file which directs the compiler to search for the appropriate math.h c++ file in the relevant include directory but the issue is it is telling me it can't find it (math.h: no such file or director etc). I'm using Windows 7 64 bit.
I think this is because the way I have set up my build environment, I have maybe not accounted for the fact that TDM-GCC can compile both 32 and 64 bit binaries so this somehow has affected the compilers interpretation of where my c++ math.h file is.
I looked on this explanation of how to go about building libraries using Mingw64 on this link: enter link description here but I think TDM-GCC has taken care of a few of the problems this article is designed to resolve.
How do I set up my build environment correctly for the TDM-GCC 64 bit compiler so all my directories are found?
I noticed there are a number of include directories:
C:\mingw\x86_64-w64-mingw32\include
C:\mingw\lib\gcc\x86_64-w64-mingw32\5.1.0\include
PLUS my own directory created when I build my projects
C:\mingw\include
What am I doing wrong here? Should I have used one of the first two directories as my include directory? I think this where I have baused things up.

Related

How do I setup a Codeblocks project on Windows 10 to compile and link a static SFML project?

My advance appologies for being hopeless at Windows development. I am by no means a Windows developer and my understanding of how to write, compile and link C++ code on a Windows system is limited to say the least.
I am having difficulty trying to compile and link a SFML project on a Windows 10 system with the CodeBlocks IDE.
I am trying to link this project with static linking, not dynamic linking. Again I have virtually no idea how the two different methods work in detail, I just know that if I ship a static linked binary to another Windows 10 user it is much more likely to "just work" on their system.
List of things I did:
Downloaded the latest version of CodeBlocks with MINGW integration.
Installed, default options
Downloaded the latest version of SFML (32bit MINGW version)
Extracted the zip file (SFML) to my home directory
Created a new codeblocks project (console application) and followed the instructions to set the compiler and linker options
https://www.sfml-dev.org/tutorials/2.5/start-cb.php
It works fine for dynamic linking, but requires me to copy the .dll files to the same dir as the produced executable file (produced from compilation of my C++ code).
I tried to change to static linking, changing the names of the linker libs with the -s or -s-d suffix, and adding the define SMFL_STATIC option to global (release and debug) options. I also added the opengl32, freetype, winmm and gdi32 link libs, before their respective sfml link libs.
When trying to compile I get the following linker errors
cannot find -lfreetype
cannot find -lsfml-graphics-s-d
cannot find -lsfml-window-s-d
cannot find -lsfml-system-s-d
in Release mode, similar errors are produced.
What am I doing wrong?
My hunch would be that you either have the wrong compiler (see below) or you haven't defined the library directory as mentioned in the linked tutorial.
There are four common things to consider when using SFML (and essentially any other C++ library) on Windows.
Compiler versions have to fully match
Make sure to not mix x86 and x64
Settings need to be specified for the correct configuration
When linking libraries statically, you also need to link the dependencies
Compiler versions have to fully match
Since C++ doesn't have a standardized ABI, the generated libraries will never be reusable between compilers. Yes, sometimes "it works", but it can break at any point and there's no guarantee.
We strongly recommend to either use the compilers linked on the SFML Download page or build SFML from source with your current compiler.
If you got the latest stable Code::Blocks version with MinGW as stated, you should also be able to get a snapshot build of SFML, which should be using the same compiler.
Note: One exception to this rule is Visual Studio, where VS 2017 binaries are compatible with VS 2019 (and maybe VS 2022?).
Make sure to not mix x86 and x64
When you download a 32-bits (x86) version of SFML, you also need a 32-bits version of your compiler. When you download a 64-bits (x64) version of SFML, you also need a 64-bits version of your compiler.
Make sure you double check your compiler configuration that you've selected the correct bit-ness.
Note: For Visual Studio you need to select the correct compiler architecture in the IDE, usually positioned right next to the run button.
Settings need to be specified for the correct configuration
Project configurations are usually spread across the matrix built from the types:
Debug / Release / All
x86 / x64 (for VS)
Make sure when you add the settings for library paths and include paths that it's not just set for debug or release and ends up missing in either or the other configuration.
Also make sure you're not setting up debug libraries (with the -d suffix) in release mode or release libraries (without any suffix) in debug mode.
When linking libraries statically, you also need to link the dependencies
The SFML static libraries don't contain any symbols of any of its dependencies, that means, in your final application you have to link static SFML and all its dependencies.
As a short summary you can think of static libraries like an archive of object files. These object files will directly be linking into your application, like you link your own source file object files. As such, the SFML static libraries only contain object files of SFML itself and not of other libraries as well.
Troubleshooting
If nothing seems to help, then you should enable verbose compiler & linker output, that we you see exactly which commands are invoked and one can quickly spot the missing statements.

Build Environment C++ using Mingw?

I haven't programmed for a while and am trying to set up my build environment on a new laptop. I've just forgotten how and think that I did allot of things wrong last time!
What I'm trying to do is have that common Include Directory and common Lib directory so when I build projects or other dependencies, etc... my compiler is able to find all the include and lib files it needs. I'm not formally trained so some obvious things to you guys are learning points for me.
I'm going to use a Mingw compiler and MSYS. Off memory I put the Include directory and the lib directory in the Mingw directory but I could be wrong there.
I'm just trying to set up an effective and simple build environment on Windows 7.
Where should all my directories go? Thanks
If you aren't already, MSYS2 is generally preferred over MSYS. I'm going to answer this assuming MSYS2. I use the 64 bit version, so that is what I'll show, but it should be simple enough to change.
I will also assume you put the msys64 directory in the base directory, if not replace C:/msys64/ with C:/wherever/you/put/it/msys64/.
When using the msys shell, /c/msys64/usr/ is the same as C:/msys64/usr/ which is the same as /usr/ since it tries to blend Linux file organization with windows, and it can sometimes be slightly unintuitive. When you install msys libraries, usually the include files are in C:/msys64/usr/include/ and the libraries are in C:/msys64/usr/lib/. The exception to this is when you have a 64-bit version and a 32-bit version of a program, in which case the headers are in C:/msys64/mingw64/include/ and the libs in C:/msys64/mingw64/lib/ for 64-bit (mingw32 for 32 bit).
In order to build using these, you will need to add the appropriate include paths and library paths. So, to make all 64-bit programs available, you would add the following flags
-IC:/msys64/usr/include -IC:/msys64/mingw64/include -LC:/msys64/usr/lib -LC:/msys64/mingw64/lib
When you compile your own programs from source, you put them wherever you'd like. It is best not to put them in the same directory as the package manager to avoid collisions. Running make install sometimes won't run as seamlessly on msys as it would on linux. In these cases, creating a folder such as C:/msys64/custom/include/ is a safer alternative. See https://unix.stackexchange.com/questions/30/where-should-i-put-software-i-compile-myself for some more insight on this.

I cannot find the folder C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\gl on my laptop. How do I add it?

Also does that mean opengl is not installed by default because I did check all the boxes when I installed visual studio community 2015. I couldn't find any clear answer anywhere. I'm supposed to add glut and glew header files to the aforementioned folder where gl.h and glu.h should already be there. But I couldnt find the folder include\gl itself.
Also does that mean opengl is not installed by default because I did check all the boxes when I installed visual studio community 2015. I couldn't find any clear answer anywhere.
You have to distinguish between:
a fully featured OpenGL driver being installed (which unfortunately doesn't happen by default on Windows)
the OpenGL development support files being available for your compiler environment.
As far as the compiler environment is concerned, since OpenGL-1.1 has been part of the Windows ABI contract since Windows-NT-4 all compilers that target the Windows-32 API must ship with the required support files.
To check if your compiler installation is complete try to compile and execute the following little program:
#include <windows.h>
#include <GL/gl.h>
#include <stdio.h>
#pragma comment(lib, "opengl32.lib")
int main(int argc, char *argv[])
{
if( &glGetError ) {
fprintf(stderr, "OpenGL glGetError symbol available\n");
}
}
It does not actually call an OpenGL function, but compiling it requires to link against opengl32.lib and testing for the symbol glGetError being non-NULL makes sure the linker will pull in a reference.
I'm supposed to add glut and glew header files to the aforementioned folder
Don't! Never put anything manually into installation directories of the compiler toolchain. Always configure an auxiliary directory structure for header and library files, that you add to your projects' compiler include and linker search paths.
Install GLEW there. If you got the instructions to install GLEW into the compiler toolchain directory, disregard any other advice coming from the same source, as whoever is the source is apparently clueless about proper DevOps.
Update due to question in comment
In software development using 3rd party libraries is commonplace. You normally want to collect those libraries at a common location. Such libraries usually consist of header files, binaries and on some operating systems additional linker stubs. The binaries are built for a specific operating system and the linker stubs are made for specific compilers.
The following would be such a directory structure, inspired by the way *nix OSs organize their stuff
/local/include/ gets all the headers
/local/i686-windows/bin 32 bit Windows extra tooling executables
/local/i686-pc-linux-gnu/bin 32 bit Linux extra tooling executables
/local/i686-windows/lib 32 bit Windows DLLs
/local/i686-windows/libmsvc 32 bit Visual C++ linker stubs and static libraries
/local/i686-windows/libmingw 32 bit GNU MinGW linker stubs and static libs
/local/i686-pc-linux-gnu/lib 32 bit Linux SOs and static libraries
/local/x86_64-windows/bin 64 bit Windows extra tooling executables
/local/x86_64-pc-linux-gnu/bin 64 bit Linux extra tooling executables
/local/x86_64-windows/lib 64 bit Windows DLLs
/local/x86_64-windows/libmsvc 32 bit Visual C++ linker stubs and static libraries
/local/x86_64-windows/libmingw 32 bit GNU MinGW linker stubs and static libs
/local/x86_64-linux-gnu/lib 64 bit Linux SOs and static libraries
Ok, so the above list may be a little bit excessive for a simple development environment. But say you're targeting 64 bit Windows, using the Visual C++ compiler, then you'd create a directory structure
/local/include/
/local/x86_64-windows/bin
/local/x86_64-windows/lib
/local/x86_64-windows/libmsvc
You'd add GL/glut.h and GL/glew.h (and the other header files) beneath /local/include, e.g.
/local/include/GL/glxew.h
/local/include/GL/glew.h
/local/include/GL/glut.h
/local/include/GL/wglew.h
The .lib files you put into /local/x86_64-windows/libmsvc and the DLLs into /local/x86_64-windows/lib. Then in your project build settings you can simply add /local/x86_64-windows/libmsvc as a linker search path. For the DLLs you should add /local/x86_64-windows/lib to your systems environment PATH variable, so that they are found when executing the programs you built. For deployment of those programs copy the required DLLs beside the EXE file.

How can I add libraries to a project in a system independent way?

I'm developing an application using Qt and OpenGL, and found it necessary to download the GLM library. It's a header-only library, so I don't need to link to anything. I want this application to build on any system that has the correct libraries installed. My problem is that I don't know where to put GLM so that the system can find it without adding a specific path to the project's .pro file. The .pro file is part of my git repository, which is how the source is distributed to other systems like Linux, etc. So I don't want this file to specify the exact location of GLM because other systems could have it in other places.
I'm currently developing on Windows, compiling in Qt Creator using Visual C++ 2010. I read from MSDN that #include <file> searches using the INCLUDE environment variable, so I tried to add the path to glm.hpp to INCLUDE, but QtCreator's build environment for this project seems to overwrite INCLUDE. So I appended the path to GLM to the new INCLUDE from within QtCreator's Projects tab, but my code still can't find glm.hpp.
In general, how can I add an external library to my system such that my compiler will be able to find it without specifying the exact location in a project file that's distributed to other systems?
What you need is a build system with the power to search the system for the libraries you request, and be able to do so on any platform. One such build system is cmake, and it is the most widely used build system. In essence, cmake allows you to write a build script in which you can specify all the things you normally specify when creating a project in Qt Creator or Visual Studio, like the list of source files, grouped by targets to compile (libraries, executables, etc.), the relative paths to the headers, and libraries to include for linking and for include-paths, amongst many more things. For libraries that are installed on the system, there is a function, called find_package() (part of cmake script commands), that will find out if the library is installed and where to find its lib files and headers (storing those paths as cache strings that you can specify on the targets and such). It usually works great, as long as the libraries are not installed in weird places. The way it works is that when you run cmake, it will generate a build script/configuration for almost any platform you specify, and then you use that to compile your code. It can generate makefiles (Unix-like or windows), CodeBlocks project files, Visual Studio project files, etc.. And many IDEs also have native support for cmake projects.
I wish I could recommend an alternative, just to sound less biased for cmake, but I haven't heard of any that truly compare to it, especially for the purpose of locating external dependencies and working with different platforms. I would guess Boost.Build is decent too.

Installing Boost libraries with MinGW and CodeBlocks

I'm having my first fling with the Boost libraries, and I've picked a pretty girl named Regex.
I've installed the libraries (which build automatically?) on my machine, but I'm getting the above error (cannot find -lboost_regex). I'm using Code::Blocks with MinGW, and a C++0X compiler flag.
I have
Pointed the "search directories" to the installation directory
Added the -lboost_regex flag to the linker
but no luck. Can someone help me get this working?
Update
Got things running now. I've added some further notes in an answer below, for newcomers to this problem.
(Also, changed the title of the question since it turned out to be a broader issue than when I started out.)
Here's some links and tips that can help a newcomer, from my first build experience. I built the libraries directly from the zip file. I built on MinGW and I used CodeBlocks for the IDE.
Download Boost zip, unzip somewhere (I'll call that place $boostdir)
Pretty large when unzipped, > 300MB
Add MinGW bin to PATH var
When Boost builds, it will need access to MinGW executables
Build b2.exe and bjam.exe
The documentation for Windows blithely assumes MSVC compiler is available.
If it is, you can apparently use the bootstrap.bat like the docs say.
If it's not (like mine), you'll have to build the exe files yourself, in steps 4 and 5.
In CMD, navigate to $boostdir/tools/build/v2/engine
Run build.bat mingw (will build b2.exe and bjam.exe)
Some aging basic documentation on that
Now you've got b2 and bjam custom-built according to your system spec. Navigate back up to $boostdir and get ready to start building the libraries.
Boost will make a new bin.v2 directory in the current directory.
All the libs will go in bin.v2.
This is an "intermediate" directory, for some reason
Nothing to do in this step, just some extra info :)
Run b2 toolset=gcc --build-type=complete
This takes a long time, in the neighborhood of 1 - 2 hours.
You'll know if it's working. If you think something's wrong, it's not working.
The build can use various flags
Now you're all built. Time to set up CodeBlocks.
Point your compiler to the header files
Right click your project -> Build Options -> Search Directories tab -> Compiler tab -> add $boostdir address
Boost has built a DLL for the library you want according to your current system spec. Look in the stage\lib\ directory of $boostdir
This DLL will be used later in the linker, so don't close its explorer window yet
Mine was in C:\Program Files\Boost_1_52\stage\lib\libboost_regex-mgw44-1_52.dll
I think the documentation had a smart way to do this but I haven't tried it yet
The "intermediate" directory from step #6 can be deleted now that the build is finished
Point your linker to the directory of that DLL
Right click your project -> Build Options -> Search Directories tab -> Linker tab -> add
that directory address (blah\blah\blah\stage\lib\)
Add that DLL flag to your linker settings
Mine was -lboost_regex-mgw44-1_52
Deep breath, prayers to your god, and fire up a test.
Further docs that may either help or confuse:
The Code::Blocks website has a version of this that I didn't find until I neared the end of my search. It was fairly helpful but had a few weird things. This post also is helpful.
Good luck!
I'm not sure what you mean by which build automatically. Most of the Boost libraries are header-only, but a few, such as regex, need to be compiled to a shared / static library. The compilation step is not automatic, you need to invoke the Boost build system (bjam) to do this. Of course, there are sources (BoostPro for instance) that distribute pre-built Boost binaries for various platforms.
Once that's done, you need to add the path where the libraries are present to the linker's search path. For MinGW, this option is -L"path/to/library". Boost does have directives to allow auto-linking of the required libraries, and this seems to work pretty well with MSVC, but I've never gotten it to work with MinGW. So you must also list the libraries to be linked explicitly. The Boost libraries include target and version information in the file name by default, so a typical linker command line option will look like -lboost_regex-mgw47-mt-1_51 for MinGW gcc 4.7 and Boost 1.51