CMake: boost aus lib/-Verzeichnis statt Systempfad benutzen

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
 
Du musst dem Compiler '-L/pfad/zu/deiner/lib' als Parameter mitgeben oder $LD_LIBRARY_PATH entsprechend setzen. Dann sollte es klappen.
 
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 :(
 
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.
 
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?
 
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.
 
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?
 
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 :)
 
Zurück
Oben