Fundamentals of cross-compiling (with CMake) [duplicate] - c++

I'm working with QT and embedded devices and in many documentation items ( like here) they are talking about sysroots. I've searched the web but I couldn't find anything about what a sysroot is. I have a cross-compiler-toolchain though. What's a sysroot and how do I create one ?

A sysroot is a directory which is considered to be the root directory for the purpose of locating headers and libraries. So for example if your build toolchain wants to find /usr/include/foo.h but you are cross-compiling and the appropriate foo.h is in /my/other/place/usr/include/foo.h, you would use /my/other/place as your sysroot.

Related

Cmake: find_library doesn't work but find_path does (same path)

I am trying to build a cross platform school project in C++ with CMake. My project requires the use of the Irrlicht library and must compile under Linux and Windows 10.
The project source path contains a lib folder, containing the Irrlicht header (in an include subfolder), an Irrlicht.dll, an Irrlicht.lib and a FindIrrlicht.cmake module.
I set CMAKE_MODULE_PATH to point to this directory, then call find_package(Irrlicht REQUIRED) in my CMakeLists.txt.
When I try to compile under Linux, everything works fine. However, when I try to run the configuration with CMake (using the CMake GUI) under Windows, the FindIrrlicht.cmake module that I have does not work (it should, since it is provided by the school and they say it should, also I know other people had it work without modifications). I believe that I have identified the cause of the problem, but I do not understance why it occurs nor how to fix it.
FindIrrlicht.cmake looks for the include directory and the Irrlicht.lib (or libIrrlicht.so under Linux, using prefix/suffix options) in some standard Linux include/library path AND under CMAKE_MODULE_PATH. When compiling on Windows, it should find everything in CMAKE_MODULE_PATH.
It calls find_library like this:
FIND_LIBRARY(Irrlicht_LIBRARIES
NAMES
Irrlicht
PATHS
"/usr/lib64/"
"/usr/lib/"
"/usr/lib/x86_64-linux-gnu/"
"/usr/local/lib/"
"/usr/local/lib64/"
"${CMAKE_MODULE_PATH}/" #Should find in this path for Windows configuration
"${Irrlicht_DIR}/"
)
The problem is, the path in CMAKE_MODULE_PATH is correct, since find_path() (see below) is able to find the include directory for Irrlicht. But it sets the Irrlicht_LIBRARIES as NOTFOUND. I verified times and again that the files are there and that the files are in the right place. I also checked the permissions on the files.
IF (NOT Irrlicht_INCLUDE_DIRS OR NOT Irrlicht_LIBRARIES)
FIND_PATH(Irrlicht_INCLUDE_DIRS
NAMES
irrlicht.h
PATHS
"/usr/include/irrlicht/"
"/usr/local/include/irrlicht/"
"${CMAKE_MODULE_PATH}/include/" #Does find in Windows
"${Irrlicht_DIR}/include/"
)
Also, later in the CMakeLists.txt I call a file(COPY "${CMAKE_MODULE_PATH}/Irrlicht.dll" DESTINATION ${EXECUTABLE_OUTPUT_PATH}) successfully, and tried it too with Irrlicht.lib with success. So the path is definitely not the problem here.
Thank you in advance for any help !
P.S.: This is my first time asking a question on StackOverflow, if I did/wrote something not right please let me know, I would be grateful.
Well, I found my problem. I feel stupid for not thinking about this sooner...
The problem was in the pre/suffixes, with some debugging output I realised that they were set for Linux instead of Windows, hence not founding the library file.
The reason for that is that in the CMakeLists.txt, the call to find_package was done before the call to project(), thus the MSVC variables was not set during the call to find_package, which led the script to believe it was called under Linux.

Best way to structure include/lib directories for CMake cross-compilation?

I have a general question that stems from a more specific issue I'm having with cross-compiling for aarch64/ARMv8.
First, my specific issue is that I can't seem to get my arm toolchain's ld binary to link against glibc/libc objects.
example_path/aarch64-linux-gnu/bin/ld: cannot find crt1.o: No such file or directory
I suppose that because it is an .o, I should probably use the one from my target platform instead of my host one. So I have copied sysroot from my target platform (no bin, just /usr/include and /usr/lib), and I have added that into a directory in my workspace called aarch64. Now, in my toolchain.cmake file, I've set this, because I don't want to use an x86-64 libs or headers:
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_SYSROOT /usr/bin/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu)
Because CMAKE_FIND_ROOT_PATH_MODE_LIBRARY is sent to ONLY, CMake should ignore usual library paths.
So this has led to my general question:
What is the best/most-commonly accepted way to structure directories etc for cross-compiling? Obviously, I don't want to put my target's sysroot in /usr/... but I need to be able to link against the ARM sysroot for all the libs installed there. Is it as simple as using:
link_directories(...)
in the toolchain file?
Where do people usually store the sysroot?
Thanks for your time, and apologies if this is a simple question - I am new to cross-compiling.

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.

How to direct CMake to use libraries in specific directory only

I am trying to get all dependent libraries in my project in one directory and read from only that directory in CMake. I want to do this so that I may have portability of my project and so that it can run on any computer as long as that directory with all the libraries is present with the executable. Is this possible somehow? I am using Ubuntu 14.10.
I have a LOT of static libraries used in my project and they are in places such as usr/lib, usr/lib/i386-linux-gnu, usr/lib/x86_64-linux-gnu.
Any help would be appreciated! Thanks in advance.
Seems that you need to use link_directories to tell where to find your libs.

How to Exclude /usr/include Path from Linux Application?

I am running into a problem I have not been able to avoid. Redhat 6 (or most linux packages) comes with a default QT package installed with headers/etc in the /usr/lib and /usr/include folders.
Now, I am wanting to link against a newer version of QT without removing the older version. Unfortunately, since the headers are in the /include/ folder, gcc automatically finds them, and then uses the wrong include files (instead of those which I have elsewhere).
I cannot seem to stop the compiler from automatically doing this. I have gotten around it previously by simply manually removing the old libraries/headers but this is a terrible solution long term.
I do not think this problem is specific to QT either, it just happens to be my current instance of it.
Any suggestions?
Many thanks :)
If you give the include directories of the newer Qt installation through -I option, it should be searched before the standard include directories (i.e. /usr/include, etc.) Removing the standard include directories from the search path completely is likely not a good idea because standard headers will also be found there (note that the Qt headers themselves most likely include standard headers and will not work if those are not found).
However if you really don't want the standard include directories to be searched, the option -nostdinc should do what you want.
My issue turned out to be related to an incorrect version of qmake being used. It was finding a previous version of qmake, and even though it was from qt4, it was linking to the wrong includes.
Updating the qmake paths worked to fix this issue.