Sandburg Sandburg - 26 days ago 9
C++ Question

Linking local shared library with Waf (no lib compilation) [SOLVED]

I'm trying to build a simple

c++11
program linking with a shared lib (dynamic library) using waf-1.8.8.

The particularity is that I'm not trying to build this lib, because I already have the dev version, which means the declarations (.hpp headers) and the definitions (
.so
files under
linux
,
.dll
+
.lib
under windows).

I am only trying to link like that:

$ g++ src/main.cpp -o mySFMLprogram.bin -std=c++11 -IthirdParty/SFML-2.2/include -LthirdParty/SFML-2.2/lib -lsfml-graphics -lsfml-system -lsfml-window


That works very well from the base dir of my project.

What does not work is making this with a wscript / waf system... I don't find how to make the equivalent to
-LthirdParty/SFML-2.2/lib
(giving a new search dir to the linker,
man gcc
says
Add directory dir to the list of directories to be searched for -l.
).

Here is the simplified tree of my project:

$ tree
.
├── src
│   ├── main.cpp
│   └── wscript
├── thirdParty
│   ├── SFML-2.2
│   │   ├── include
│   │   │   └── SFML
│   │   │   ├── Audio
│   │   │   │   └── **.hpp
│   │   │   ├── Audio.hpp
│   │   │   ├── Config.hpp
│   │   │   ├── Graphics
│   │   │   │   └── **.hpp
│   │   │   ├── Graphics.hpp
│   │   │   ├── Main.hpp
│   │   │   ├── Network
│   │   │   │   └── **.hpp
│   │   │   ├── Network.hpp
│   │   │   ├── OpenGL.hpp
│   │   │   ├── System
│   │   │   │   ├── **.hpp
│   │   │   │   └── **.inl
│   │   │   ├── System.hpp
│   │   │   ├── Window
│   │   │   │   └── **.hpp
│   │   │   └── Window.hpp
│   │   └── lib
│   │      ├── libsfml-audio.so -> libsfml-audio.so.2.2.0
│   │      ├── libsfml-audio.so.2.2.0
│   │      ├── libsfml-graphics.so -> libsfml-graphics.so.2.2.0
│   │      ├── libsfml-graphics.so.2.2.0
│   │      ├── libsfml-network.so -> libsfml-network.so.2.2.0
│   │      ├── libsfml-network.so.2.2.0
│   │      ├── libsfml-system.so -> libsfml-system.so.2.2.0
│   │      ├── libsfml-system.so.2.2.0
│   │      ├── libsfml-window.so -> libsfml-window.so.2.2.0
│   │      └── libsfml-window.so.2.2.0
│   └── wscript
├── waf
└── wscript


EDIT: update my files after @mkaes first explanation
The root
wscript
is:

#! /usr/bin/env python
# encoding: utf-8

import os

VERSION = "0.1"
APPNAME = "wafTest"

def options(opt):
opt.load('compiler_cxx')

def configure(cfg):
cfg.load('compiler_cxx')
cfg.LIB_SFML = ['sfml-graphics', 'sfml-system', 'sfml-window']
cfg.INCLUDES_SFML = ['thirdParty/SFML-2.2/include')]
cfg.LIBPATH_SFML = ['thirdParty/SFML-2.2/lib')]
cfg.check(
features='cxx cxxprogram',
cxxflags=['-std=c++11', '-Wall'],
)

def build(bld):
bld.recurse('src')


And the
src
wscript
is:

#! /usr/bin/env python
# encoding: utf-8

def build(bld):
#EDIT removed bld(name = 'sfml-graphics', export_includes = '../thirdParty/SFML-2.2/include')
#EDIT removed bld(name = 'sfml-window', export_includes = '../thirdParty/SFML-2.2/include')
#EDIT removed bld(name = 'sfml-system', export_includes = '../thirdParty/SFML-2.2/include')
bld.program(
features='cxx cxxprogram', #is it an option ?
source='main.cpp',
target='app',
use = ['SFML'], #first try> compilation error, headers missing
includes = '../thirdParty/SFML-2.2/include' #second try> link error, lib missing
)


Source code of
src/main.cpp
(easy it's taken from SFML basic test programs):

#include <SFML/Graphics.hpp>

int main()
{
// create the window
sf::RenderWindow window(sf::VideoMode(800, 600), "My window");

// run the program as long as the window is open
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();
}

// clear the window with black color
window.clear(sf::Color::Black);

// draw everything here...
// window.draw(...);

// end the current frame
window.display();
}

return 0;
}


Previous output from waf command
./waf clean configure build
:

'clean' finished successfully (0.004s)
Setting top to : /home/***/Documents/dev/wafTest
Setting out to : /home/***/Documents/dev/wafTest/build
Checking for 'g++' (C++ compiler) : /usr/bin/g++
Checking for compiler flags ['-std=c++11', '-Wall'] : yes
'configure' finished successfully (0.070s)
Waf: Entering directory `/home/***/Documents/dev/wafTest/build'
[1/2] Compiling src/main.cpp
[2/2] Linking build/src/app
src/main.cpp.4.o: dans la fonction « main »:
main.cpp:(.text+0x10f): référence indéfinie vers « sf::String::String(char const*, std::locale const&) »
main.cpp:(.text+0x12d): référence indéfinie vers « sf::VideoMode::VideoMode(unsigned int, unsigned int, unsigned int) »
main.cpp:(.text+0x160): référence indéfinie vers « sf::RenderWindow::RenderWindow(sf::VideoMode, sf::String const&, unsigned int, sf::ContextSettings const&) »
main.cpp:(.text+0x19b): référence indéfinie vers « sf::Window::close() »
main.cpp:(.text+0x1b4): référence indéfinie vers « sf::Window::pollEvent(sf::Event&) »
main.cpp:(.text+0x1c8): référence indéfinie vers « sf::Color::Black »
main.cpp:(.text+0x1d0): référence indéfinie vers « sf::RenderTarget::clear(sf::Color const&) »
main.cpp:(.text+0x1df): référence indéfinie vers « sf::Window::display() »
main.cpp:(.text+0x1ee): référence indéfinie vers « sf::Window::isOpen() const »
main.cpp:(.text+0x206): référence indéfinie vers « sf::RenderWindow::~RenderWindow() »
main.cpp:(.text+0x23f): référence indéfinie vers « sf::RenderWindow::~RenderWindow() »
main.cpp:(.text+0x270): référence indéfinie vers « sf::RenderWindow::~RenderWindow() »
collect2: error: ld returned 1 exit status

Waf: Leaving directory `/home/***/Documents/dev/wafTest/build'
Build failed
-> task in 'app' failed (exit status 1):
{task 140412749536784: cxxprogram main.cpp.4.o -> app}
['/usr/bin/g++', 'src/main.cpp.4.o', '-o', '/home/***/Documents/dev/wafTest/build/src/app', '-Wl,-Bstatic', '-Wl,-Bdynamic']


What's wrong?

EDIT2:
This example is SOLVED and can be found on Github: https://github.com/Tyrben/SFMLProjectUsingWaf
Thanks @mkaes

Answer

One way to solve this would be to add your library during the configure phase. E.g

cfg.env.LIB_SFML = ['sfml-graphics', 'sfml-system', 'sfml-window']
cfg.env.LIBPATH_SFML = [os.path.join(os.getcwd(), 'thirdParty/SFML-2.2/lib')]
cfg.env.INCLUDES_SFML = [os.path.join(os.getcwd(), 'thirdParty/SFML-2.2/include']

and then in your build just add SFML as a use directive.

Update: Change your build to this:

def build(bld):
    bld.program(
        features='cxx cxxprogram', #is it an option ?
        source='main.cpp', 
        target='app', 
        use = ['SFML']
)
Comments