使用scons没有正确选择显式依赖

时间:2016-02-03 05:03:11

标签: build scons

我的scons构建环境设置如下:

--SConstruct [Top level file]
  --dir1
    --Sconscript
    --src
    --inc
  --dir2
    --Sconscript
    --src
    --inc

[DIR1]

构建dir1导致生成几个.so,比如libdir1_a.so,libdir1_b.so,libdir1_c.so等。 所有这些共享库都放在一些文件夹中 - $ install / dir1 / lib /

[DIR2]

为dir2构建src时,需要从dir1,libdir1_b.so链接一个库 我用

env.Depends(dir2_target, $install/dir1/lib/libdir1_b.so)

指定依赖项。 但是,当构建源sin dir2时,它无法说明未找到显式依赖项。 我需要做些什么来确保在dir之前构建dir1?

1 个答案:

答案 0 :(得分:0)

您的用例的解决方案是不使用显式依赖项。这里不需要Depends功能。 SCons非常聪明,可以找出这些类型的依赖关系。

这是一个有效的例子,因为这总能让解释更好!

>> scons --version
SCons by Steven Knight et al.:
    script: v2.3.6.rel_2.3.5:3347:d31d5a4e74b6[MODIFIED], 2015/07/31 14:36:10, by bdbaddog on hpmicrodog
    engine: v2.3.6.rel_2.3.5:3347:d31d5a4e74b6[MODIFIED], 2015/07/31 14:36:10, by bdbaddog on hpmicrodog
    engine path: ['/usr/lib/scons/SCons']
Copyright (c) 2001 - 2015 The SCons Foundation

>> tree
.
├── dir1
│   ├── include
│   │   ├── dir1_a.h
│   │   ├── dir1_b.h
│   │   └── dir1_c.h
│   ├── SConscript
│   └── src
│       ├── dir1_a.cpp
│       ├── dir1_b.cpp
│       └── dir1_c.cpp
├── dir2
│   ├── include
│   │   └── dir2_a.h
│   ├── SConscript
│   └── src
│       └── dir2_a.cpp
└── SConstruct

6 directories, 11 files

>> find . -type f | xargs awk 'FNR==1{print FILENAME; }{ print }'
./dir2/src/dir2_a.cpp
#include <dir2_a.h>
#include <dir1_a.h>
#include <iostream>
void dir2_a::myhello() {dir1_a::hello();}

./dir2/include/dir2_a.h
#include <iostream>
namespace dir2_a { void myhello();}

./dir2/SConscript
Import('env')
local_env = env.Clone()
local_env.Append(CPPPATH=['include', '#include'],
                 LIBPATH=['#lib'],
                 LIBS=['dir1_a'],
                 RPATH=['$$$$\\{ORIGIN}/.'])
liba = local_env.SharedLibrary('src/dir2_a.cpp')
Install('#lib', [liba])
Install('#include', Glob('include/*.h'))

./SConstruct
env = Environment()
Export('env')
SConscript('dir1/SConscript')
SConscript('dir2/SConscript')

./dir1/src/dir1_a.cpp
#include <dir1_a.h>
#include <iostream>
void dir1_a::hello() {std::cout << "A" << std::endl;}

./dir1/src/dir1_b.cpp
#include <dir1_b.h>
#include <iostream>
void dir1_b::hello() {std::cout << "B" << std::endl;}

./dir1/src/dir1_c.cpp
#include <dir1_c.h>
#include <iostream>
void dir1_c::hello() {std::cout << "C" << std::endl;}

./dir1/include/dir1_c.h
#include <iostream>
namespace dir1_c { void hello();}

./dir1/include/dir1_b.h
#include <iostream>
namespace dir1_b { void hello();}

./dir1/include/dir1_a.h
#include <iostream>
namespace dir1_a { void hello();}

./dir1/SConscript
Import('env')
local_env = env.Clone()
local_env.Append(CPPPATH='include')
liba = local_env.SharedLibrary('src/dir1_a.cpp')
libb = local_env.SharedLibrary('src/dir1_b.cpp')
libc = local_env.SharedLibrary('src/dir1_c.cpp')
Install('#lib', [liba, libb, libc])
Install('#include', Glob('include/*.h'))

>> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o dir1/src/dir1_a.os -c -fPIC -Idir1/include dir1/src/dir1_a.cpp
g++ -o dir1/src/dir1_b.os -c -fPIC -Idir1/include dir1/src/dir1_b.cpp
g++ -o dir1/src/dir1_c.os -c -fPIC -Idir1/include dir1/src/dir1_c.cpp
g++ -o dir1/src/libdir1_a.so -shared dir1/src/dir1_a.os
g++ -o dir1/src/libdir1_b.so -shared dir1/src/dir1_b.os
g++ -o dir1/src/libdir1_c.so -shared dir1/src/dir1_c.os
Install file: "dir1/include/dir1_a.h" as "include/dir1_a.h"
g++ -o dir2/src/dir2_a.os -c -fPIC -Idir2/include -Iinclude dir2/src/dir2_a.cpp
Install file: "dir1/src/libdir1_a.so" as "lib/libdir1_a.so"
g++ -o dir2/src/libdir2_a.so -shared -Wl,-rpath=$\{ORIGIN}/. dir2/src/dir2_a.os -Llib -ldir1_a
Install file: "dir1/include/dir1_b.h" as "include/dir1_b.h"
Install file: "dir1/include/dir1_c.h" as "include/dir1_c.h"
Install file: "dir2/include/dir2_a.h" as "include/dir2_a.h"
Install file: "dir1/src/libdir1_b.so" as "lib/libdir1_b.so"
Install file: "dir1/src/libdir1_c.so" as "lib/libdir1_c.so"
Install file: "dir2/src/libdir2_a.so" as "lib/libdir2_a.so"
scons: done building targets.

>> tree
.
├── dir1
│   ├── include
│   │   ├── dir1_a.h
│   │   ├── dir1_b.h
│   │   └── dir1_c.h
│   ├── SConscript
│   └── src
│       ├── dir1_a.cpp
│       ├── dir1_a.os
│       ├── dir1_b.cpp
│       ├── dir1_b.os
│       ├── dir1_c.cpp
│       ├── dir1_c.os
│       ├── libdir1_a.so
│       ├── libdir1_b.so
│       └── libdir1_c.so
├── dir2
│   ├── include
│   │   └── dir2_a.h
│   ├── SConscript
│   └── src
│       ├── dir2_a.cpp
│       ├── dir2_a.os
│       └── libdir2_a.so
├── include
│   ├── dir1_a.h
│   ├── dir1_b.h
│   ├── dir1_c.h
│   └── dir2_a.h
├── lib
│   ├── libdir1_a.so
│   ├── libdir1_b.so
│   ├── libdir1_c.so
│   └── libdir2_a.so
└── SConstruct

8 directories, 27 files

>> ldd lib/libdir2_a.so 
    linux-vdso.so.1 (0x00007ffdb53a5000)
    libdir1_a.so => ./libdir1_a.so (0x00007f0707bd7000)
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f070782f000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f070752d000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f0707316000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f0706f54000)
    /lib64/ld-linux-x86-64.so.2 (0x000055bd342e4000)

如果要查看依赖树实际上是自动设置的,只需执行以下内容......

>> scons --tree=prune 
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o dir1/src/dir1_a.os -c -fPIC -Idir1/include dir1/src/dir1_a.cpp
g++ -o dir1/src/dir1_b.os -c -fPIC -Idir1/include dir1/src/dir1_b.cpp
g++ -o dir1/src/dir1_c.os -c -fPIC -Idir1/include dir1/src/dir1_c.cpp
g++ -o dir1/src/libdir1_a.so -shared dir1/src/dir1_a.os
g++ -o dir1/src/libdir1_b.so -shared dir1/src/dir1_b.os
g++ -o dir1/src/libdir1_c.so -shared dir1/src/dir1_c.os
Install file: "dir1/include/dir1_a.h" as "include/dir1_a.h"
g++ -o dir2/src/dir2_a.os -c -fPIC -Idir2/include -Iinclude dir2/src/dir2_a.cpp
Install file: "dir1/src/libdir1_a.so" as "lib/libdir1_a.so"
g++ -o dir2/src/libdir2_a.so -shared -Wl,-rpath=$\{ORIGIN}/. dir2/src/dir2_a.os -Llib -ldir1_a
Install file: "dir1/include/dir1_b.h" as "include/dir1_b.h"
Install file: "dir1/include/dir1_c.h" as "include/dir1_c.h"
Install file: "dir2/include/dir2_a.h" as "include/dir2_a.h"
Install file: "dir1/src/libdir1_b.so" as "lib/libdir1_b.so"
Install file: "dir1/src/libdir1_c.so" as "lib/libdir1_c.so"
Install file: "dir2/src/libdir2_a.so" as "lib/libdir2_a.so"
+-.
  +-SConstruct
  +-dir1
  | +-dir1/SConscript
  | +-dir1/include
  | | +-dir1/include/dir1_a.h
  | | +-dir1/include/dir1_b.h
  | | +-dir1/include/dir1_c.h
  | +-dir1/src
  |   +-dir1/src/dir1_a.cpp
  |   +-dir1/src/dir1_a.os
  |   | +-dir1/src/dir1_a.cpp
  |   | +-dir1/include/dir1_a.h
  |   | +-/bin/g++
  |   +-dir1/src/dir1_b.cpp
  |   +-dir1/src/dir1_b.os
  |   | +-dir1/src/dir1_b.cpp
  |   | +-dir1/include/dir1_b.h
  |   | +-/bin/g++
  |   +-dir1/src/dir1_c.cpp
  |   +-dir1/src/dir1_c.os
  |   | +-dir1/src/dir1_c.cpp
  |   | +-dir1/include/dir1_c.h
  |   | +-/bin/g++
  |   +-dir1/src/libdir1_a.so
  |   | +-[dir1/src/dir1_a.os]
  |   +-dir1/src/libdir1_b.so
  |   | +-[dir1/src/dir1_b.os]
  |   +-dir1/src/libdir1_c.so
  |     +-[dir1/src/dir1_c.os]
  +-dir2
  | +-dir2/SConscript
  | +-dir2/include
  | | +-dir2/include/dir2_a.h
  | +-dir2/src
  |   +-dir2/src/dir2_a.cpp
  |   +-dir2/src/dir2_a.os
  |   | +-dir2/src/dir2_a.cpp
  |   | +-include/dir1_a.h
  |   | | +-dir1/include/dir1_a.h
  |   | +-dir2/include/dir2_a.h
  |   | +-/bin/g++
  |   +-dir2/src/libdir2_a.so
  |     +-[dir2/src/dir2_a.os]
  |     +-lib/libdir1_a.so
  |       +-[dir1/src/libdir1_a.so]
  +-include
  | +-[include/dir1_a.h]
  | +-include/dir1_b.h
  | | +-dir1/include/dir1_b.h
  | +-include/dir1_c.h
  | | +-dir1/include/dir1_c.h
  | +-include/dir2_a.h
  |   +-dir2/include/dir2_a.h
  +-lib
    +-[lib/libdir1_a.so]
    +-lib/libdir1_b.so
    | +-[dir1/src/libdir1_b.so]
    +-lib/libdir1_c.so
    | +-[dir1/src/libdir1_c.so]
    +-lib/libdir2_a.so
      +-[dir2/src/libdir2_a.so]
scons: done building targets.