I'm testing bazel and now have a problem with external library.
My demo project is like this: a simple main.cpp trying to use 3rd party libary of fastcdr.
bazel-demo/
├── src
│ ├── BUILD
│ └── main.cpp
├── third_party
│ └── fastcdr
│ └── fastcdr.BUILD
└── WORKSPACE
my WORKSPACE file:
new_local_repository(
name = "fastcdr",
path = "/usr/local/fast-rtps/include",
build_file = "third_party/fastcdr/fastcdr.BUILD",
)
it defines a new package in /usr/local/fast-rtps/include, where the fastcdr library is pre-built and installed. (Please note that this is not standard /usr/local/include)
The main BUILD is like:
cc_binary(
name = "main",
srcs = [
"main.cpp",
],
deps = [
"#fastcdr"
],
)
I have added fastcdr as deps to main target.
In my fastcdr.BUILD,
cc_library(
name = "fastcdr",
includes = [
".",
],
linkopts = [
"-L/usr/local/fast-rtps/lib",
"-lfastcdr",
],
visibility = ["//visibility:public"],
)
this is the place I'm not very sure about, but it looks correct to me.
3rd party files are already there:
/usr/local/fast-rtps/
├── examples
│ └── C++
├── include
│ ├── fastcdr
│ │ ├── Cdr.h
│ │ ├── config.h
├── lib
│ ├── libfastcdr.so.1.0.7
│ └── libfastrtps.so.1.5.0
└── share
My understand is that /usr/local/fast-rtps/include is already added into the system include, so in my main.cpp, I can include the file like this:
//#include "fastrcdr/Cdr.h"
#include <fastrcdr/config.h>
int main()
{
return 0;
}
but bazel does not compile and has an error:
src/main.cpp:4:10: fatal error: fastrcdr/config.h: No such file or directory
#include <fastrcdr/config.h>
^~~~~~~~~~~~~~~~~~~
then I use --sandbox_debug to debug like this (re-formatted a little bit):
ERROR: /home/f/gitlab/bazel-demo/src/BUILD:1:10: Compiling src/main.cpp failed: (Exit 1): linux-sandbox failed: error executing command
(cd /home/f/.cache/bazel/_bazel_f/dc41fd263ad6b7cccaa1b7608cdfd5aa/sandbox/linux-sandbox/32/execroot/__main__ && \
exec env - \
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin \
PWD=/proc/self/cwd \
TMPDIR=/tmp \
/home/f/.cache/bazel/_bazel_f/install/64841bf12de13c7518c7ada0994bafe2/linux-sandbox -t 15
-w /home/f/.cache/bazel/_bazel_f/dc41fd263ad6b7cccaa1b7608cdfd5aa/sandbox/linux-sandbox/32/execroot/__main__
-w /tmp -w /dev/shm -D -- /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector
-Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer '-std=c++0x'
-MD -MF bazel-out/k8-fastbuild/bin/src/_objs/main/main.pic.d '-frandom-seed=bazel-out/k8-fastbuild/bin/src/_objs/main/main.pic.o' -fPIC -iquote .
-iquote bazel-out/k8-fastbuild/bin
-iquote external/bazel_tools -iquote bazel-out/k8-fastbuild/bin/external/bazel_tools
-iquote external/fastcdr -iquote bazel-out/k8-fastbuild/bin/external/fastcdr
-isystem external/fastcdr -isystem bazel-out/k8-fastbuild/bin/external/fastcdr
-fno-canonical-system-headers -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"'
-c src/main.cpp -o bazel-out/k8-fastbuild/bin/src/_objs/main/main.pic.o)
From this line
-w /home/f/.cache/bazel/_bazel_f/dc41fd263ad6b7cccaa1b7608cdfd5aa/sandbox/linux-sandbox/32/execroot/__main__
I know my working path.
From these two lines:
-iquote external/fastcdr -iquote bazel-out/k8-fastbuild/bin/external/fastcdr
-isystem external/fastcdr -isystem bazel-out/k8-fastbuild/bin/external/fastcdr
I know external/fastcdr & bazel-out/k8-fastbuild/bin/external/fastcdr are added into my system include.
They are relative paths, so what's the full absolute path? I assume the external and bazel-out are below my working path. I check them, neither folder has the fastcdr path.
But if I go several folder level above, there is another external folder:
dc41fd263ad6b7cccaa1b7608cdfd5aa/
├── execroot
│ └── __main__
├── external <- another `external` folder here
│ ├── bazel_tools -> /home/f/.cache/bazel/_bazel_f/install/64841bf12de13c7518c7ada0994bafe2/embedded_tools
│ ├── #bazel_tools.marker
│ ├── fastcdr <- but fastcdr is here!!!!
│ ├── #fastcdr.marker
│ ├── fastrtps
│ ├── #fastrtps.marker
│ ├── local_config_cc
├── sandbox
│ ├── inaccessibleHelperDir
│ ├── inaccessibleHelperFile
│ └── linux-sandbox <- the working path in bazel output, no fastcdr
I guess I'm very close to fix the problem, but what BUILD file should I change?
Thanks.
Related
This question already has answers here:
Make file Doesn't detect changes in source files
(2 answers)
How do I ensure my makefile detects changes in my header and cpp files?
(2 answers)
Closed 5 months ago.
My folder structure for C++ project is:
└── compiler
├── Makefile
├── README.md
├── build
└── src
├── components
│ ├── lexer
│ │ ├── lexer.cpp
│ │ ├── lexer.h
│ │ └── tokens
│ │ ├── tokens.cpp
│ │ └── tokens.h
│ └── parser
│ ├── parser.cpp
│ ├── parser.h
│ └── syntax
│ ├── syntax.cpp
│ └── syntax.h
├── main.cpp
└── utilities
└── evaluator
├── evaluator.cpp
└── evaluator.h
I want to write my Makefile in such a way that it recompiles only changed .cpp and .h files on command make. My Makefile is:
# Flags
flags_linker = -g -Wall -std=c++11 -lm -ldl -fPIC -rdynamic
flags_compiler = -g -Wall -std=c++11 -fPIC
# Directories and files
# Filenames and paths
main = main
lexer = lexer
tokens = tokens
parser = parser
syntax = syntax
evaluator = evaluator
# Source directories
source_dir = ./src
source_components_dir = $(source_dir)/components
source_lexer_dir = $(source_components_dir)/$(lexer)
source_tokens_dir = $(source_lexer_dir)/$(tokens)
source_parser_dir = $(source_components_dir)/$(parser)
source_syntax_dir = $(source_parser_dir)/$(syntax)
source_utilities_dir = $(source_dir)/utilities
source_evaluator_dir = $(source_utilities_dir)/$(evaluator)
# Build directories
build_dir = ./build
build_components_dir = $(build_dir)/components
build_lexer_dir = $(build_components_dir)/$(lexer)
build_tokens_dir = $(build_lexer_dir)/$(tokens)
build_parser_dir = $(build_components_dir)/$(parser)
build_syntax_dir = $(build_parser_dir)/$(syntax)
build_utilities_dir = $(build_dir)/utilities
build_evaluator_dir = $(build_utilities_dir)/$(evaluator)
run: $(build_dir)/$(main)
$(build_dir)/$(main)
$(build_dir)/$(main):
make executable
executable: compile
g++ $(flags_linker) -v $(build_dir)/$(main).o $(build_lexer_dir)/$(lexer).o $(build_tokens_dir)/$(tokens).o $(build_parser_dir)/$(parser).o $(build_syntax_dir)/$(syntax).o $(build_evaluator_dir)/$(evaluator).o -o $(build_dir)/$(main)
compile: $(main) $(lexer) $(parser) $(evaluator)
$(main): $(source_dir)/$(main).cpp $(lexer) $(parser)
g++ $(flags_compiler) -c $< -o $(build_dir)/$#.o
$(lexer): $(source_lexer_dir)/$(lexer).cpp $(build_lexer_dir) $(tokens)
g++ $(flags_compiler) -c $< -o $(build_lexer_dir)/$#.o
$(tokens): $(source_tokens_dir)/$(tokens).cpp $(build_tokens_dir)
g++ $(flags_compiler) -c $< -o $(build_tokens_dir)/$#.o
$(parser): $(source_parser_dir)/$(parser).cpp $(build_parser_dir) $(syntax)
g++ $(flags_compiler) -c $< -o $(build_parser_dir)/$#.o
$(syntax): $(source_syntax_dir)/$(syntax).cpp $(build_syntax_dir) $(lexer)
g++ $(flags_compiler) -c $< -o $(build_syntax_dir)/$#.o
$(evaluator): $(source_evaluator_dir)/$(evaluator).cpp $(build_evaluator_dir) $(syntax)
g++ $(flags_compiler) -c $< -o $(build_evaluator_dir)/$#.o
$(build_lexer_dir):
mkdir -p $(build_lexer_dir)
$(build_tokens_dir):
mkdir -p $(build_tokens_dir)
$(build_parser_dir):
mkdir -p $(build_parser_dir)
$(build_syntax_dir):
mkdir -p $(build_syntax_dir)
$(build_evaluator_dir):
mkdir -p $(build_evaluator_dir)
clean:
rm -rf ./build/*
My when I run make command, it doesn't recompile the project but just runs the executable. I have just started using Makefiles and not able to figure out what should I change.
I want to open Vegetables in my shoppinglist.ml but I get an error message Unbound module Vegetables
My directory structure looks like this:
market/
|_ src/
|_ shoppinglist.ml
|_ shoppinglist.mli
|_ vegetables/
|_ vegetables.ml
shoppinglist.ml:
open Vegetables
I use dune build and usually after that dune utop . to build my project.
dune in src:
(library
(name shoppinglist)
(libraries vegetables)
(flags
(:standard -warn-error -27)))
dune in vegetables:
(library
(name vegetables)
(modules vegetables)
(flags
(:standard -warn-error -27)))
I already tried many "solutions" but non of them worked out for me...
With the following architecture I have no problem at all:
.
├── bin
│ ├── dune
│ └── main.ml
let () = Shoppinglist.a ()
├── dune-project
├── program.opam
├── src
│ ├── dune
│ └── shoppinglist.ml
let a () = Vegetables.a ()
└── vegetables
├── dune
└── vegetables.ml
let a () = Printf.printf "vegetables\n"
dune files are the same as yours, I just added a bin directory with a main.ml file to execute some code from the library.
The dune file in bin is:
(executable
(name main)
(public_name program)
(libraries shoppinglist)
(flags
(:standard -warn-error -27)))
And
❯ dune exec program
vegetables
So I'm not exactly sure what's your problem here.
The demo structure like this:
.
├── demo
│ ├── include
│ │ └── func.h
│ │
│ └── src
│ ├── BUILD
│ │
│ └── func.cc
└── WORKSPACE
func.h:
#pragma once
int square(int);
func.cc: include from the root
#include "demo/include/func.h"
int square(int i) { return i * i; }
BUILD:
cc_library(
name = "simple_demo",
srcs = ["func.cc"],
visibility = ["//visibility:public"],
)
Bazel build command in the dir of WORKSPACE:
bazel build //demo/src:simple_demo
The error occurs.
demo/src/func.cc:1:10: fatal error: 'demo/include/func.h' file not found
And I saw this in https://docs.bazel.build/versions/1.1.0/be/c-cpp.html#hdrs
All header files that are used in the build must be declared in the hdrs or srcs of cc_* rules. This is enforced.
However, if I add hdrs = "../include/func.h" to the BUILD, another error will occur
segment '..' not permitted
By default in Bazel labels are not allowed to cross the package boundaries. In your case func.h lives outside the package defined by the BUILD file, that is limited to demo/src (and sub-folders).
Assuming you're creating a library where func.h is the public header visible from outside, I would change the folder structure to:
.
├── demo
│ ├── include
│ │ └── func.h
│ ├── src
│ │ └── func.cc
│ └── BUILD
└── WORKSPACE
and the BUILD file to also include func.h:
cc_library(
name = "simple_demo",
hdrs = ["include/func.h"],
srcs = ["src/func.cc"],
visibility = ["//visibility:public"],
)
Notice that even with the suggested folder structure, if you don't include the hdrs = ... line (or don't include func.h in srcs = ..., if the header is not meant to be public), you will get an error for the reason you mentioned.
I am not sure if this might work, but can you try giving
'../include/func.h'
instead of 'demo/include/func.h' because I believe its not able to find a demo folder inside your src folder since it starts searching from there.
I have the following directory structure for a C++ project:
.
├── bin
├── build
├── include
│ ├── dir1
│ │ ├── file1.hpp
│ │ └── file2.hpp
│ ├── dir2
│ │ ├── file3.hpp
│ │ └── file4.hpp
│ └── third_party
│ └── catch.hpp
├── Makefile
├── src
│ ├── dir1
│ │ ├── file1.cpp
│ │ └── file2.cpp
│ └── dir2
│ ├── file3.cpp
│ └── file4.cpp
└── test
├── dir1
│ ├── file1.test.cpp
│ └── file2.test.cpp
└── dir2
├── file3.test.cpp
└── file4.test.cpp
How can I write the Makefile to compile the code in src and test directories and obtain the object files in the build directory and the binaries in the bin directory, maintaining the same directory structure within them, without having to name every file and its dependency explicitly? Would it be better to use multiple Makefiles in each dir* within src and test?
My Makefile currently looks like this: (it's probably nonsensical, sorry about that!)
binaries_dir = bin
build_dir = build
sources_dir = src
include_dir = include
compile_flags = -std=c++14 -Wall
binaries := $(wildcard *.out)
objects := $(wildcard *.o)
sources := $(wildcard *.cpp)
headers := $(wildcard *.hpp)
objects: $(sources)
g++ $(compile_flags) -c $(sources_dir)/$(sources) -I $(include_dir)
binaries: $(objects)
for object in $(objects); do
g++ $(compile_flags) -o $(binaries_dir)/ $(build_dir)/$object
done
I don't think this is fool proof but I think it pretty much does what you are after. You should study up on building Makefiles because it this turns out not to quite fit your needs, how are you going to fix it?
CXX := g++
RM := rm -f
MD := mkdir -p
# don't change, this is for dependencies
CXXFLAGS += -MMD -MP
# add compiler flags here
CXXFLAGS += -std=c++14 -pedantic-errors
CXXFLAGS += -Wall -Wextra
CXXFLAGS += -g3 -O0
# add external includes here
CPPFLAGS += -Iinclude
# add library flags here
LDFLAGS +=
DIRS := $(patsubst src/%, %, $(wildcard src/*))
DIRS += $(patsubst test/%, %, $(wildcard test/*))
PROG_SOURCES := $(wildcard src/*/*.cpp)
TEST_SOURCES := $(wildcard test/*/*.cpp)
OBJECTS := $(patsubst src/%.cpp, build/%.o, $(PROG_SOURCES))
OBJECTS += $(patsubst test/%.cpp, build/%.o, $(TEST_SOURCES))
EXECUTABLES := $(patsubst src/%.cpp, bin/%, $(PROG_SOURCES))
EXECUTABLES += $(patsubst test/%.cpp, bin/%, $(TEST_SOURCES))
DEPENDENCIES := $(patsubst src/%.cpp, build/%.d, $(PROG_SOURCES))
DEPENDENCIES += $(patsubst test/%.cpp, build/%.d, $(TEST_SOURCES))
all: dirs $(EXECUTABLES)
build/%.o: src/%.cpp
$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $# $<
build/%.o: test/%.cpp
$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $# $<
bin/%: build/%.o
$(CXX) $(CXXFLAGS) -o $# $< $(LDFLAGS)
-include $(DEPENDENCIES)
clean:
#echo Removing build files
#$(RM) $(EXECUTABLES) $(OBJECTS) $(DEPENDENCIES)
dirs:
#$(MD) $(patsubst %, build/%, $(DIRS)) $(patsubst %, bin/%, $(DIRS))
.PHONY: show dirs
You might find some inspiration from this: https://github.com/jschmerge/DasBuild
I have a scons build environment set up something like :
--SConstruct [Top level file]
--dir1
--Sconscript
--src
--inc
--dir2
--Sconscript
--src
--inc
[dir1]
building dir1 results in several .so being generated, lets say libdir1_a.so, libdir1_b.so, libdir1_c.so etc.
all these shared libs ar eplaced in some folder - $install/dir1/lib/
[dir2]
when building src for dir2, it needs one library to be linked from dir1, libdir1_b.so
I use
env.Depends(dir2_target, $install/dir1/lib/libdir1_b.so)
to specify the dependency.
However, when building source sin dir2 it fails saying explicit dependency not found.
What do i need to do to make sure dir1 builds before dir ?
The solution for your use case is to not use explicit dependencies. The Depends function is not needed here. SCons is smart enough to figure out these types of dependencies.
Here is a working example, because that always makes an explanation better!
>> 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)
If you want to see that the dependency tree is really being automatically setup, just execute the following...
>> 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.