CMake: boost aus lib/-Verzeichnis statt Systempfad benutzen

bad_alloc

Member of Honour
Hallo HaBo,

ich möchte mit CMake ein C++-Projekt kompilieren welches boost 1.56.00 benutzt. Boost habe ich kompiliert und nach lib/ im Projektverzeichnis gepackt. Auf dem System (Ubuntu) ist über die Paketverwaltung noch boost 1.48.00 installiert (kann nicht entfernt werden, andere Sachen hängen davon ab). In meiner CMakeLists.txt setze ich folgendes:

Code:
set(BOOST_ROOT "lib/boost_1_56_00/")
set(Boost_INCLUDE_DIR "lib/boost_1_56_00/boost/")
set(Boost_LIBRARY_DIRS "lib/boost_1_56_00/lib/")
set(Boost_NO_SYSTEM_PATHS ON)

Wenn ich jedoch folgendes ausführe:

Code:
#include <iostream>
#include "boost/version.hpp"
using namespace std;

int main() {
    cout << "Using boost version " << BOOST_LIB_VERSION << endl; 
    return 0;
}

Kommt raus "1_48", also die alte Version. Wie bringe ich CMake bei ausschließlich in meinem lib/-Verzeichnis zu suchen?

Code:
cmake_minimum_required (VERSION 2.6)
project (GAME CXX)

set(CMAKE_CXX_COMPILER "g++-4.7")

# no-as-needed required 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wl,--no-as-needed")

# The version number.
set (GAME_VERSION_MAJOR 1)
set (GAME_VERSION_MINOR 0)
 
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
  "${PROJECT_SOURCE_DIR}/GAMECMakeConfig.h.in"
  "${PROJECT_BINARY_DIR}/GAMECMakeConfig.h"
  )

file(GLOB_RECURSE GAME_SOURCES "src/*.cpp")

# add the binary tree to the search path for include files
# so that we will find GAMEConfig.h
include_directories("${PROJECT_BINARY_DIR}")
include_directories("${PROJECT_SOURCE_DIR}/include/")
include_directories("${PROJECT_SOURCE_DIR}/lib/include/")
include_directories("${PROJECT_SOURCE_DIR}/lib/boost_1_56_00/boost/")

add_subdirectory (include)

# get all libraries
#set(CMAKE_LIBRARY_PATH "lib/" "lib/boost_1_54_0/installed/lib/")
set(CMAKE_LIBRARY_PATH "lib/" "lib/boost_1_56_0/lib/")
set(BOOST_ROOT "lib/boost_1_56_00/")
set(Boost_INCLUDE_DIR "lib/boost_1_56_00/boost/")
set(Boost_LIBRARY_DIRS "lib/boost_1_56_00/lib/")
set(Boost_NO_SYSTEM_PATHS ON)

#find_package(Boost 1.56 HINTS "lib/boost_1_56_00/")

find_library(GL NAMES GL gl HINTS "/usr/lib/x86_64-linux-gnu/mesa/libGL.so")
find_library(GLU NAMES GLU glu libglu)
find_library(Xxf86vm NAMES Xxf86vm HINTS "/usr/lib/libXxf86vm.so")
find_library(Xrandr NAMES Xrandr)
find_library(Xext NAMES Xext)

find_library(Irrlicht libIrrlicht.a)
find_library(Filesystem NAMES libboost_filesystem.so)
find_library(ProgramOptions NAMES libboost_program_options.so)
find_library(System NAMES libboost_system.so)
find_library(Thread NAMES libboost_thread.so)

# add the executable

add_executable(GAME.exe main.cpp ${GAME_SOURCES})
target_link_libraries (GAME.exe ${GL} ${GLU} ${X11} ${Xxf86vm} ${Xrandr} ${Xext} ${Irrlicht} ${System} ${Filesystem} ${Thread} ${ProgramOptions})

In der falschen Bibliothek,
bad_alloc
 

bitmuncher

Senior-Nerd
Du musst dem Compiler '-L/pfad/zu/deiner/lib' als Parameter mitgeben oder $LD_LIBRARY_PATH entsprechend setzen. Dann sollte es klappen.
 

bad_alloc

Member of Honour
Das geschieht auch, die Executable wird laut ldd korrekt gelinkt:

Code:
    linux-vdso.so.1 =>  (0x00007fff160a5000)
    libGL.so.1 => /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1 (0x00007f64b02a7000)
    libGLU.so.1 => /usr/lib/x86_64-linux-gnu/libGLU.so.1 (0x00007f64b0039000)
    libXxf86vm.so.1 => /usr/lib/x86_64-linux-gnu/libXxf86vm.so.1 (0x00007f64afe33000)
    libXrandr.so.2 => /usr/lib/x86_64-linux-gnu/libXrandr.so.2 (0x00007f64afc2b000)
    libXext.so.6 => /usr/lib/x86_64-linux-gnu/libXext.so.6 (0x00007f64afa1a000)
  [B]  libboost_system.so.1.56.0 => /home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_0/lib/libboost_system.so.1.56.0 (0x00007f64af815000)
    libboost_filesystem.so.1.56.0 => /home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_0/lib/libboost_filesystem.so.1.56.0 (0x00007f64af5ff000)
    libboost_thread.so.1.56.0 => /home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_0/lib/libboost_thread.so.1.56.0 (0x00007f64af3dd000)
    libboost_program_options.so.1.56.0 => /home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_0/lib/libboost_program_options.so.1.56.0 (0x00007f64af16a000)[/B]
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f64aee66000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f64aeb6a000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f64ae953000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f64ae593000)
    libX11.so.6 => /usr/lib/x86_64-linux-gnu/libX11.so.6 (0x00007f64ae25e000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f64ae040000)
    libglapi.so.0 => /usr/lib/x86_64-linux-gnu/libglapi.so.0 (0x00007f64ade1b000)
    libXdamage.so.1 => /usr/lib/x86_64-linux-gnu/libXdamage.so.1 (0x00007f64adc18000)
    libXfixes.so.3 => /usr/lib/x86_64-linux-gnu/libXfixes.so.3 (0x00007f64ada11000)
    libX11-xcb.so.1 => /usr/lib/x86_64-linux-gnu/libX11-xcb.so.1 (0x00007f64ad80f000)
    libxcb-glx.so.0 => /usr/lib/x86_64-linux-gnu/libxcb-glx.so.0 (0x00007f64ad5f8000)
    libxcb.so.1 => /usr/lib/x86_64-linux-gnu/libxcb.so.1 (0x00007f64ad3d9000)
    libdrm.so.2 => /usr/lib/x86_64-linux-gnu/libdrm.so.2 (0x00007f64ad1ce000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f64acfca000)
    libXrender.so.1 => /usr/lib/x86_64-linux-gnu/libXrender.so.1 (0x00007f64acdbf000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f64acbb7000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f64b0527000)
    libXau.so.6 => /usr/lib/x86_64-linux-gnu/libXau.so.6 (0x00007f64ac9b3000)
    libXdmcp.so.6 => /usr/lib/x86_64-linux-gnu/libXdmcp.so.6 (0x00007f64ac7ad000)

Das Problem liegt wohl darin, dass g++ die boost-Header vom System holt, obwohl ich ihm per -I die korrekten Includepfade mitgebe:

Code:
g++-4.7 -std=c++11 -Wl,--no-as-needed
-I/home/user/Programme/GAME/GAME_Beta
-I/home/user/Programme/GAME/GAME_Beta/include
-I/home/user/Programme/GAME/GAME_Beta/lib/include
[B] -I/home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_00/boost[/B] -o
CMakeFiles/GAME.exe.dir/main.cpp.o -c
/home/user/Programme/GAME/GAME_Beta/main.cpp

g++-4.7 -std=c++11 -Wl,--no-as-needed
-I/home/user/Programme/GAME/GAME_Beta
-I/home/user/Programme/GAME/GAME_Beta/include
-I/home/user/Programme/GAME/GAME_Beta/lib/include
[B] -I/home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_00/boost -o[/B]
CMakeFiles/GAME.exe.dir/src/crosshairObj.cpp.o -c
/home/user/Programme/GAME/GAME_Beta/src/crosshairObj.cpp

g++-4.7 -std=c++11 -Wl,--no-as-needed
-I/home/user/Programme/GAME/GAME_Beta
-I/home/user/Programme/GAME/GAME_Beta/include
-I/home/user/Programme/GAME/GAME_Beta/lib/include
[B] -I/home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_00/boost[/B] -o
CMakeFiles/GAME.exe.dir/src/RendererObj.cpp.o -c
/home/user/Programme/GAME/GAME_Beta/src/RendererObj.cpp

g++-4.7 -std=c++11 -Wl,--no-as-needed
CMakeFiles/GAME.exe.dir/main.cpp.o
CMakeFiles/GAME.exe.dir/src/crosshairObj.cpp.o
CMakeFiles/GAME.exe.dir/src/RendererObj.cpp.o -o GAME.exe -rdynamic
-lGL -lGLU -lXxf86vm -lXrandr -lXext lib/libIrrlicht.a
lib/boost_1_56_0/lib/libboost_system.so
lib/boost_1_56_0/lib/libboost_filesystem.so
lib/boost_1_56_0/lib/libboost_thread.so
lib/boost_1_56_0/lib/libboost_program_options.so
-Wl,-rpath,/home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_0/lib

Nur wie sage ich g++, dass alles mit -I dem Systempfad vorzuziehen ist?

Danke schonmal für die Hilfe :)

EDIT: Gerade include_directories(SYSTEM "${PROJECT_SOURCE_DIR}/lib/boost_1_56_00/boost/") probiert, sodass g++ noch das -isystem Flag mitbekommt, was eigentlich™ vor Systemincludes kommen sollte, aber er findet immer noch nur 1.48 :(
 

bitmuncher

Senior-Nerd
Gibt's das Problem denn schon beim Kompilieren der Objekt-Dateien oder erst bei der fertigen Exe? Denn beim letzten Schritt, dem linken der Objekte zur Binary, wird kein Include-Path gesetzt.
 

bad_alloc

Member of Honour
Denn beim letzten Schritt, dem linken der Objekte zur Binary, wird kein Include-Path gesetzt.
Alle #includes werden zur Kompilierzeit ausgeführt indem Headerdateien an die Stellen kopiert werden wo das #include steht. Damit hat meine exe Header von boost 1.48.00 einkompiliert, greift aber auf die neuen 1.56.00 shared libraries zu. Warnungen schmeißt g++ keine.

Ich habe folgendes getestet:
Code:
#include "/home/user/path/to/game/lib/boost_1_56_00/boost/version.hpp"
Damit bekomme ich tatsächlich die neuen Header eingebunden, aber das ist keine Lösung.

Hier bin ich mit meinem Latein ziemlich am Ende :( Die neuen Includes existieren, können mit absoluten Pfaden eingebunden werden und funktionieren dann auch. g++ nutzt aber nur Includedateien aus dem Systempfad und ignoriert sowohl -I als auch -isystem. Was kann man noch tun um g++ von 1.48-headern fernzuhalten?
 

bitmuncher

Senior-Nerd
Wenn du die include-Anweisungen in folgender Form schreibst, werden die des Systems verwendet:

Code:
#include <headerfile>

Schreibst du hingegen

Code:
#include "headerfile"

wobei der Pfad relativ oder absolut angegeben werden kann, wird der Include- und Source-Path danach durchsucht, wobei mit - I angegebene Ordner bevorzugt werden.

So war es zumindest in der Zeit, als ich noch mit C zu tun hatte. Wenn das noch immer so ist, musst du die Header einfach nur in doppelten Anführungszeichen angeben und nicht in spitzen Klammern.
 

bad_alloc

Member of Honour
Ich habe jetzt etwas tiefer gegraben und siehe da:

Code:
$g++ -v [...]
ignoring nonexistent directory "/home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_00"
Aber:
Code:
$ file /home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_0/
/home/user/Programme/GAME/GAME_Beta/lib/boost_1_56_0/: directory

Die Lösung scheint näerzukommen; jetzt ist es ein Linuxproblem. :D Wie behebe ich das?
 

bad_alloc

Member of Honour
Jap, dieses Linux aber auch ;)
Jetzt ist es ein Userproblem; wie behebe ich das? Ah ich weiß, ne Brille 8).

Ursache war wohl ein Copypaste-Fehler:

Code:
$ ls -l
drwxrwxr-x 4 user user     4096 Oct  8  2013 boost_1_51_00
drwxrwxr-x 4 user user     4096 Oct  8  2013 boost_1_54_00
drwxrwxr-x 4 user user     4096 Sep  4 21:21 boost_1_56_0

Danke für die rege Hilfe :)
 
Oben