【问题标题】:Linking local shared library with Waf (no lib compilation)将本地共享库与 Waf 链接(无库编译)
【发布时间】:2015-04-23 15:09:03
【问题描述】:

我正在尝试使用 waf-1.8.8 构建一个简单的c++11 程序与共享库(动态库)链接。

特殊之处在于我没有尝试构建这个库,因为我已经有了 dev 版本,这意味着声明(.hpp 标头)和定义(.so 下的文件linux.dll +.lib在windows下)。

我只是想这样链接:

$ 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

从我的项目的基本目录中效果很好。

用 wscript / waf 系统做这个是行不通的......我找不到如何制作与 -LthirdParty/SFML-2.2/lib 等效的方法(给链接器一个新的搜索目录,man gccAdd directory dir to the list of directories to be searched for -l. )。

这是我项目的简化树:

$ 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

编辑:在@mkaes 第一次解释后更新我的文件 根wscript 是:

#! /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')

src wscript 是:

#! /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
    )

src/main.cpp的源代码(很简单,取自SFML基本测试程序):

#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;
}

waf 命令./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']

怎么了?

编辑2: 此示例已解决,可以在 Github 上找到:https://github.com/Tyrben/SFMLProjectUsingWaf 谢谢@mkaes

【问题讨论】:

    标签: c++ compilation sfml waf


    【解决方案1】:

    解决此问题的一种方法是在配置阶段添加您的库。例如

    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']
    

    然后在您的构建中添加SFML 作为use 指令。

    更新: 将您的构建更改为:

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

    【讨论】:

    • 对不起,这对我不起作用。我收到许多链接错误,例如main.cpp:(.text+0x270): undefined reference to « sf::RenderWindow::~RenderWindow() » collect2: error: ld returned 1 exit status 我将编辑我的帖子以显示 wscript 文件。
    • 很奇怪,因为这对我来说适用于相同的用例。你也可以添加 waf 的命令行输出吗?
    • 我已经添加了输出。 ID:它说 Waf: Entering directory `/home/nounours/Documents/dev/wafTest/build' 所以它可能没有所有的 lib 头文件和构建子目录中的 .so ?!
    • @Sandburg:我希望如果您将构建更改为我添加的构建,它会起作用。这正是我的做法。
    • 如果在我的root configure 中我输入:cfg.LIB_SFML = ['sfml-graphics', 'sfml-system', 'sfml-window'] cfg.LIBPATH_SFML = ['thirdParty/SFML-2.2/lib'] cfg.INCLUDES_SFML = ['thirdParty/SFML-2.2/include'] 和我的build 部分(以递归方式启动)我输入:bld.program( features='cxx cxxprogram', source='main.cpp', target='app', use = ['SFML'] 然后我有一个编译错误,找不到标题fatal error: SFML/Graphics.hpp 但是如果我添加构建指令includes = '../thirdParty/SFML-2.2/include' 现在我有一个链接错误(更好)。那就是我一直卡住的地方
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 2018-07-05
    相关资源
    最近更新 更多