显式依赖项未使用 SCONS 正确选取



我有一个scons构建环境,设置了如下内容:

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

[目录1]

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

[目录2]

为 DIR2 构建 SRC 时,它需要从 DIR1 链接一个库,libdir1_b.so我使用

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

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

您的用例的解决方案是不使用显式依赖项。 此处不需要依赖函数。 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.

最新更新