explicit dependency not being picked correctly with scons - build

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.

Related

Bazel can'f find my external lib header files

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.

cmake : shared library or sub-prjoect

I am builfing a new c++ project and i want to integrate cmake and i dont know what is the best approach i have to follow
my project tree looks like this :
.
├── http
| ├── include
| | └── http.h
| |
| └── src
| ├── http.cpp
| └── main.cpp
├── dns
| ├── include
| | └── dns.h
| |
| └── src
| ├── dns.cpp
| └── main.cpp
...
I dont really dont know what to do and i m not quite familiar with cmake
doing a shared library from every directory and link them together in cmake file
a sub-project for every directory .

OCaml open own module

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.

Unison: Ignore files with Regex doesn't work

I tried to ignore some files that end with ".NUMBERS" like .133443. I tried this Regex but it still copies the files:
unison -batch -owner -group -times -ignore "Regex ^*\.[0-9]+$" /hadoop/bigdata/giin/data ssh://cnp31ginhortonen1.giin.recouv//hadoop/bigdata/giin/data -prefer newer`
Source :
[root#cnp31ginhortonen1 .unison]# tree /hadoop/bigdata/giin/data/
/hadoop/bigdata/giin/data/
├── aefd.csv
├── aefd.log
├── aefd.xml
├── subdir
│   ├── aefd.csv
│   ├── aefd.log
│   ├── aefd.xml
│   └── TB5E.B01.117.210409074
├── TB5E.B01.117.10409074
└── TB5E.B01.117.210409074

Shell - copying directories recursively with RegEx matching preserving tree structure

I need to write a script, that would copy a directory recursively, but only copying subdirectories and files matched by a certain RegEx. For instance for a tree like this:
.
└── toCopy
├── A
│   ├── 123
│   ├── D
│   │   └── rybka23
│   ├── file
│   ├── file1
│   └── random
├── B
├── C
│   ├── file_25
│   └── somefile
└── E1
└── something
For a RegEx
.*[0-9]+
I need to get a new directory:
newDir
├── A
│   ├── 123
│   ├── D
│   │   └── rybka23
│   └── file1
├── C
│   └── file_25
└── E1
So my first thinking was something like this:
find toCopy -regex ".*[0-9]+" -exec cp -R '{}' newDir \;
But that doesn't really work, because I'm only getting the paths to the files/directories I need to copy and I have no idea how to build the tree from them.
I would really appreciate any hints on how to do that.
You can do that using find command and loop through the results:
#!/usr/bin/env bash
cd toDir
while IFS= read -rd '' elem; do
if [[ -d $elem ]]; then
mkdir -p ../newDir/"$elem"
else
d="${elem%/*}"
mkdir -p ../newDir/"$d"
cp "$elem" ../newDir/"$d"
fi
done < <(find . -name '*[0-9]*' -print0)
This requires bash as we are using process substitution.