Browse code

Make --follow-symlinks a global option. Generally improve flag generation during cmake and configure. Fix various problems

Nat! authored on 21-02-2017 13:44:31
Showing 17 changed files
... ...
@@ -549,6 +549,7 @@ bootstrap_main()
549 549
 
550 550
    # technical flags
551 551
    local MULLE_FLAG_EXECUTOR_DRY_RUN="NO"
552
+   local MULLE_FLAG_FOLLOW_SYMLINKS="YES"
552 553
    local MULLE_FLAG_LOG_DEBUG="NO"
553 554
    local MULLE_FLAG_LOG_EXECUTOR="NO"
554 555
    local MULLE_FLAG_LOG_EXECUTOR="NO"
... ...
@@ -582,6 +583,11 @@ bootstrap_main()
582 583
             MULLE_FLAG_ANSWER="YES"
583 584
          ;;
584 585
 
586
+         # used persistently throughout so it's global
587
+         --follow-symlinks)
588
+            MULLE_FLAG_FOLLOW_SYMLINKS="YES"
589
+         ;;
590
+
585 591
          -f|--force-fetch)
586 592
             MULLE_FLAG_DIRTY_HARRY="NO"
587 593
          ;;
... ...
@@ -35,27 +35,28 @@ MULLE_BOOTSTRAP_ARRAY_SH="included"
35 35
 # array contents can contain any characters except newline
36 36
 array_value_check()
37 37
 {
38
+   local value="$1"
39
+
38 40
    local n
39 41
 
40
-   n=`echo "$1" | wc -l  | awk '{ print $1}'`
42
+   n=`echo "${value}" | wc -l  | awk '{ print $1}'`
43
+
41 44
    [ "$n" -eq 0 ] && internal_fail "empty value"
42
-   [ "$n" -ne 1 ] && internal_fail "value \"$1\" has linebreaks"
45
+   [ "$n" -ne 1 ] && internal_fail "value \"${value}\" has linebreaks"
43 46
 
44
-   echo "$1"
47
+   echo "${value}"
45 48
 }
46 49
 
47 50
 
48 51
 array_index_check()
49 52
 {
50
-   local array
51
-   local i
52
-
53
-   array="$1"
54
-   i="$2"
53
+   local array="$1"
54
+   local i="$2"
55 55
 
56 56
    [ -z "$i" ] && internal_fail "empty index"
57 57
 
58 58
    local n
59
+
59 60
    n=`array_count "${array}"`
60 61
 
61 62
    [ "$i" -ge "$n" ] && internal_fail "index ${i} out of bounds ${n}"
... ...
@@ -66,11 +67,11 @@ array_index_check()
66 67
 
67 68
 array_add()
68 69
 {
69
-   local array
70
-   local value
70
+   local array="$1"
71
+   local value="$2"
71 72
 
72
-   array="$1"
73
-   value="`array_value_check "$2"`"
73
+# DEBUG code
74
+#   value="`array_value_check "${value}"`"
74 75
 
75 76
    if [ -z "${array}" ]
76 77
    then
... ...
@@ -84,9 +85,7 @@ ${value}"
84 85
 
85 86
 array_count()
86 87
 {
87
-   local array
88
-
89
-   array="$1"
88
+   local array="$1"
90 89
 
91 90
    if [ -z "${array}" ]
92 91
    then
... ...
@@ -94,92 +93,86 @@ array_count()
94 93
       return
95 94
    fi
96 95
 
97
-   local n
98
-
99
-   n=`echo "${array}" | wc -l | awk '{ print $1 }'`
100
-   echo "$n"
96
+   echo "${array}" | wc -l | awk '{ print $1 }'
101 97
 }
102 98
 
103 99
 
104 100
 array_get()
105 101
 {
106
-   local array
107
-   local i
102
+   local array="$1"
103
+   local i="$2"
108 104
 
109
-   array="$1"
110
-   i="`array_index_check "${array}" "$2"`"
111
-   i="`expr "$i" + 1`"
105
+# DEBUG code
106
+#   n="`array_count "${array}"`"
107
+#   [ "$i" -ge "$n" ] && internal_fail "index ${i} out of bounds ${n}"
112 108
 
113
-   echo "${array}" | head "-$i" | tail -1
109
+   ((i++))
110
+   sed -n "${i}p" <<< "${array}"
114 111
 }
115 112
 
116 113
 
117 114
 array_get_last()
118 115
 {
119
-   local array
120
-
121
-   array="$1"
116
+   local array="$1"
122 117
 
123
-   echo "${array}" | tail -1
118
+   tail -1 <<< "${array}"
124 119
 }
125 120
 
126 121
 
127 122
 array_insert()
128 123
 {
129
-   local array
130
-   local value
131
-   local i
124
+   local array="$1"
125
+   local i="$2"
126
+   local value="$3"
132 127
 
133
-   array="$1"
134
-   i="$2"
135
-   value="`array_value_check "$3"`"
128
+   value="`array_value_check "${value}"`"
136 129
 
137 130
    local head_count
138 131
    local tail_count
139
-   local n
140
-
141
-   [ -z "${i}" ] && internal_fail "empty index"
142 132
 
143
-   n="`array_count "${array}"`"
144
-   [ "$i" -gt "$n" ] && internal_fail "index ${i} out of bounds ${n}"
133
+# DEBUG code
134
+#   [ -z "${i}" ] && internal_fail "empty index"
135
+#
136
+#   local n
137
+#
138
+#   n="`array_count "${array}"`"
139
+#   [ "$i" -gt "$n" ] && internal_fail "index ${i} out of bounds ${n}"
145 140
 
146 141
    head_count="$i"
147
-   tail_count="`expr "$n" - "$i"`"
142
+   tail_count="$((n-$i))"
148 143
 
149 144
    if [ "${head_count}" -ne 0 ]
150 145
    then
151
-      echo "${array}" | head "-${head_count}"
146
+      head "-${head_count}" <<< "${array}"
152 147
    fi
153 148
 
154 149
    echo "${value}"
155 150
 
156 151
    if [ "${tail_count}" -ne 0 ]
157 152
    then
158
-      echo "${array}" | tail "-${tail_count}"
153
+      tail "-${tail_count}" <<< "${array}"
159 154
    fi
160 155
 }
161 156
 
162 157
 
163 158
 array_remove()
164 159
 {
165
-   local array
166
-   local value
160
+   local array="$1"
161
+   local value="$2"
167 162
 
168
-   array="$1"
169
-   value="`array_value_check "$2"`"
163
+# DEBUG code
164
+#   value="`array_value_check "${value}"`"
170 165
 
171 166
    if [ ! -z "${array}" ]
172 167
    then
173
-       echo "${array}" | fgrep -v -x "${value}"
168
+       fgrep -v -x "${value}" <<< "${array}"
174 169
    fi
175 170
 }
176 171
 
177 172
 
178 173
 array_remove_last()
179 174
 {
180
-   local array
181
-
182
-   array="$1"
175
+   local array="$1"
183 176
 
184 177
    local n
185 178
 
... ...
@@ -194,7 +187,7 @@ array_remove_last()
194 187
       ;;
195 188
 
196 189
       *)
197
-         n="`expr "$n" - 1`"
190
+         n="$((n-1))"
198 191
       ;;
199 192
    esac
200 193
 
... ...
@@ -246,13 +239,13 @@ _assoc_array_key_check()
246 239
 
247 240
 _assoc_array_add()
248 241
 {
249
-   local array
250
-   local key
251
-   local value
242
+   local array="$1"
243
+   local key="$2"
244
+   local value="$3"
252 245
 
253
-   array="$1"
254
-   key="`_assoc_array_key_check "$2"`"
255
-   value="`array_value_check "$3"`"
246
+# DEBUG code
247
+#   key="`_assoc_array_key_check "$2"`"
248
+#   value="`array_value_check "$3"`"
256 249
 
257 250
    local line
258 251
 
... ...
@@ -274,8 +267,9 @@ _assoc_array_remove()
274 267
 
275 268
    if [ ! -z "${array}" ]
276 269
    then
277
-       key="`_assoc_array_key_check "${key}"`"
278
-       echo "${array}" | grep -v "^${key}="
270
+# DEBUG code
271
+#       key="`_assoc_array_key_check "${key}"`"
272
+      grep -v "^${key}=" <<< "${array}"
279 273
    fi
280 274
 }
281 275
 
... ...
@@ -285,9 +279,11 @@ assoc_array_get()
285 279
    local array="$1"
286 280
    local key="$2"
287 281
 
288
-   key="`_assoc_array_key_check "${key}"`"
282
+# DEBUG code
283
+#   key="`_assoc_array_key_check "${key}"`"
289 284
 
290
-   echo "${array}" | grep "^${key}=" | sed -n 's/^[^=]*=\(.*\)$/\1/p'
285
+   grep "^${key}=" <<< "${array}" \
286
+      | sed -n 's/^[^=]*=\(.*\)$/\1/p'
291 287
 }
292 288
 
293 289
 
... ...
@@ -295,7 +291,8 @@ assoc_array_get_last()
295 291
 {
296 292
    local array="$1"
297 293
 
298
-   echo "${array}" | tail -1 | sed -n 's/^[^=]*=\(.*\)$/\1/p'
294
+   tail -1 <<< "${array}" \
295
+      | sed -n 's/^[^=]*=\(.*\)$/\1/p'
299 296
 }
300 297
 
301 298
 
... ...
@@ -303,7 +300,7 @@ assoc_array_all_keys()
303 300
 {
304 301
    local array="$1"
305 302
 
306
-   echo "${array}" | sed -n 's/^\([^=]*\)=.*$/\1/p'
303
+   sed -n 's/^\([^=]*\)=.*$/\1/p' <<< "${array}"
307 304
 }
308 305
 
309 306
 
... ...
@@ -311,20 +308,15 @@ assoc_array_all_values()
311 308
 {
312 309
    local array="$1"
313 310
 
314
-   echo "${array}" | sed -n 's/^[^=]*=\(.*\)$/\1/p'
311
+   sed -n 's/^[^=]*=\(.*\)$/\1/p' <<< "${array}"
315 312
 }
316 313
 
317 314
 
318 315
 assoc_array_set()
319 316
 {
320
-   local array
321
-   local key
322
-   local value
323
-   local old_value
324
-
325
-   array="$1"
326
-   key="$2"
327
-   value="$3"
317
+   local array="$1"
318
+   local key="$2"
319
+   local value="$3"
328 320
 
329 321
    if [ -z "${value}" ]
330 322
    then
... ...
@@ -393,6 +393,8 @@ _bootstrap_create_build_folders()
393 393
    local has_settings
394 394
    local has_overrides
395 395
 
396
+   log_debug ":_bootstrap_create_build_folders:"
397
+
396 398
    [ -d "${BOOTSTRAP_DIR}.auto/settings" ]
397 399
    has_settings=$?
398 400
 
... ...
@@ -482,6 +484,8 @@ _bootstrap_create_build_folders()
482 484
 
483 485
 bootstrap_auto_final()
484 486
 {
487
+   log_debug ":bootstrap_auto_final begin:"
488
+
485 489
    exekutor [ -d "${BOOTSTRAP_DIR}.auto" ] || internal_fail "${BOOTSTRAP_DIR}.auto does not exist"
486 490
 
487 491
    log_fluff "Analysing dependencies of repositories"
... ...
@@ -533,6 +537,8 @@ bootstrap_auto_final()
533 537
 
534 538
    clonenames="`read_root_setting "build_order"`"
535 539
    _bootstrap_create_build_folders "${clonenames}" "${REPOS_DIR}"
540
+
541
+   log_debug ":bootstrap_auto_final end:"
536 542
 }
537 543
 
538 544
 
... ...
@@ -809,7 +809,8 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO} in \"${builddir}\" ..."
809 809
 
810 810
       relative_srcdir="`relative_path_between "${owd}/${srcdir}" "${PWD}"`"
811 811
 
812
-      prefixbuild="`add_cmake_path_if_exists "${prefixbuild}" "${nativewd}/${BUILD_DEPENDENCIES_DIR}"`"
812
+      prefixbuild="`add_cmake_path "${prefixbuild}" "${nativewd}/${BUILD_DEPENDENCIES_DIR}"`"
813
+
813 814
       dependenciesdir="`add_cmake_path_if_exists "${dependenciesdir}" "${nativewd}/${REFERENCE_DEPENDENCIES_DIR}"`"
814 815
       addictionsdir="`add_cmake_path_if_exists "${addictionsdir}" "${nativewd}/${REFERENCE_ADDICTIONS_DIR}"`"
815 816
 
... ...
@@ -865,6 +866,7 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO} in \"${builddir}\" ..."
865 866
       for path in ${native_includelines}
866 867
       do
867 868
          IFS="${DEFAULT_IFS}"
869
+         path="$(sed 's/ /\\ /g' <<< "${path}")"
868 870
          other_cflags="`concat "${other_cflags}" "${includeprefix}${path}"`"
869 871
          other_cxxflags="`concat "${other_cxxflags}" "${includeprefix}${path}"`"
870 872
       done
... ...
@@ -873,6 +875,7 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO} in \"${builddir}\" ..."
873 875
       for path in ${native_librarylines}
874 876
       do
875 877
          IFS="${DEFAULT_IFS}"
878
+         path="$(sed 's/ /\\ /g' <<< "${path}")"
876 879
          other_ldflags="`concat "${other_ldflags}" "${libraryprefix}${path}"`"
877 880
       done
878 881
 
... ...
@@ -880,6 +883,7 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO} in \"${builddir}\" ..."
880 883
       for path in ${native_frameworklines}
881 884
       do
882 885
          IFS="${DEFAULT_IFS}"
886
+         path="$(sed 's/ /\\ /g' <<< "${path}")"
883 887
          other_cflags="`concat "${other_cflags}" "${frameworkprefix}${path}"`"
884 888
          other_cxxflags="`concat "${other_cxxflags}" "${frameworkprefix}${path}"`"
885 889
          other_ldflags="`concat "${other_ldflags}" "${frameworkprefix}${path}"`"
... ...
@@ -902,20 +906,47 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO} in \"${builddir}\" ..."
902 906
       oldpath="$PATH"
903 907
       PATH="${BUILDPATH}"
904 908
 
909
+      local cmake_flags
910
+
911
+      cmake_flags="-DCMAKE_C_FLAGS='${other_cflags}' \
912
+-DCMAKE_CXX_FLAGS='${other_cxxflags}' \
913
+-DCMAKE_EXE_LINKER_FLAGS='${other_ldflags}' \
914
+-DCMAKE_SHARED_LINKER_FLAGS='${other_ldflags}'"
915
+
916
+      local cmake_dirs
917
+
918
+      if [ ! -z "${dependenciesdir}" ]
919
+      then
920
+         cmake_dirs="-DDEPENDENCIES_DIR='${dependenciesdir}'"
921
+      fi
922
+
923
+      if [ ! -z "${addictionsdir}" ]
924
+      then
925
+         cmake_dirs="`add_word "${cmake_dirs}" "-DADDICTIONS_DIR='${addictionsdir}'"`"
926
+      fi
927
+
928
+      if [ ! -z "${includelines}" ]
929
+      then
930
+         cmake_dirs="`add_word "${cmake_dirs}" "-DCMAKE_INCLUDE_PATH='${includelines}'"`"
931
+      fi
932
+
933
+      if [ ! -z "${librarylines}" ]
934
+      then
935
+         cmake_dirs="`add_word "${cmake_dirs}" "-DCMAKE_LIBRARY_PATH='${librarylines}'"`"
936
+      fi
937
+
938
+      if [ ! -z "${frameworklines}" ]
939
+      then
940
+         cmake_dirs="`add_word "${cmake_dirs}" "-DCMAKE_FRAMEWORK_PATH='${frameworklines}'"`"
941
+      fi
942
+
905 943
       logging_redirect_eval_exekutor "${logfile1}" "'${CMAKE}'" \
906 944
 -G "'${CMAKE_GENERATOR}'" \
907 945
 "-DMULLE_BOOTSTRAP_VERSION=${MULLE_BOOTSTRAP_VERSION}" \
908 946
 "-DCMAKE_BUILD_TYPE='${mapped}'" \
909
-"-DDEPENDENCIES_DIR='${dependenciesdir}'" \
910
-"-DADDICTIONS_DIR='${addictionsdir}'" \
911 947
 "-DCMAKE_INSTALL_PREFIX:PATH='${prefixbuild}'"  \
912
-"-DCMAKE_INCLUDE_PATH='${includelines}'" \
913
-"-DCMAKE_LIBRARY_PATH='${librarylines}'" \
914
-"-DCMAKE_FRAMEWORK_PATH='${frameworklines}'" \
915
-"-DCMAKE_C_FLAGS='${other_cflags}'" \
916
-"-DCMAKE_CXX_FLAGS='${other_cxxflags}'" \
917
-"-DCMAKE_EXE_LINKER_FLAGS='${other_ldflags}'" \
918
-"-DCMAKE_SHARED_LINKER_FLAGS='${other_ldflags}'" \
948
+"${cmake_dirs}" \
949
+"${cmake_flags}" \
919 950
 "${sdkparameter}" \
920 951
 "${c_compiler_line}" \
921 952
 "${cxx_compiler_line}" \
... ...
@@ -1096,7 +1127,7 @@ ${C_MAGENTA}${C_BOLD}${sdk}${C_INFO} in \"${builddir}\" ..."
1096 1127
       local addictionsdir
1097 1128
       #local linker
1098 1129
 
1099
-      prefixbuild="`add_path_if_exists "${prefixbuild}" "${nativewd}/${BUILD_DEPENDENCIES_DIR}"`"
1130
+      prefixbuild="`add_path "${prefixbuild}" "${nativewd}/${BUILD_DEPENDENCIES_DIR}"`"
1100 1131
       dependenciesdir="`add_path_if_exists "${dependenciesdir}" "${nativewd}/${REFERENCE_DEPENDENCIES_DIR}"`"
1101 1132
       addictionsdir="`add_path_if_exists "${addictionsdir}" "${nativewd}/${REFERENCE_ADDICTIONS_DIR}"`"
1102 1133
 
... ...
@@ -2242,8 +2273,9 @@ build_main()
2242 2273
             OPTION_ADD_USR_LOCAL=YES
2243 2274
          ;;
2244 2275
 
2245
-         # fetch options, are just ignored
2246
-         -i|--ignore-branch|-fc|--force-checkout|-nr|--no-recursion|-e|--embedded-only|-es|--embedded-symlink|-u|--update-symlinks)
2276
+         # TODO: outdated!
2277
+         # fetch options, are just ignored (need to update this!)
2278
+         -i|--ignore-branch|-fc|--force-checkout|-nr|--no-recursion|-e|--embedded-only|-es|--embedded-symlink|-u|--follow-symlinks)
2247 2279
             :
2248 2280
          ;;
2249 2281
 
... ...
@@ -32,6 +32,92 @@
32 32
 MULLE_BOOTSTRAP_CLEAN_SH="included"
33 33
 
34 34
 
35
+_collect_stashdir()
36
+{
37
+   log_debug ":_collect_stashdir:" "$*"
38
+
39
+   # local reposdir="$1"  # ususally .bootstrap.repos
40
+   # local name="$2"      # name of the clone
41
+   # local url="$3"       # URL of the clone
42
+   # local branch="$4"    # branch of the clone
43
+   # local scm="$5"       # scm to use for this clone
44
+   # local tag="$6"       # tag to checkout of the clone
45
+   local stashdir="$7"  # stashdir of this clone (absolute or relative to $PWD)
46
+
47
+   is_minion_bootstrap_project "${stashdir}" && return
48
+
49
+   local stashparentdir
50
+
51
+   stashparentdir="`dirname -- "${stashdir}"`"
52
+
53
+   [ "${stashparentdir}" = "${STASHES_DEFAULT_DIR}" ] && return
54
+
55
+   echo "${stashdir}"
56
+}
57
+
58
+
59
+#
60
+# MEMO don't walk via .bootstrap.auto here, use information from
61
+# .bootstrap.repos
62
+#
63
+print_stashdir_repositories()
64
+{
65
+   local permissions
66
+
67
+   permissions=""
68
+   walk_repos_repositories "${REPOS_DIR}" \
69
+                           "_collect_stashdir" \
70
+                           "${permissions}"
71
+}
72
+
73
+
74
+print_embedded_stashdir_repositories()
75
+{
76
+   local permissions
77
+
78
+   permissions=""
79
+   walk_repos_repositories "${EMBEDDED_REPOS_DIR}" \
80
+                            "_collect_stashdir" \
81
+                            "${permissions}"
82
+}
83
+
84
+
85
+print_stashdir_deep_embedded_repositories()
86
+{
87
+   local permissions
88
+
89
+   permissions="minion"
90
+   walk_deep_embedded_repos_repositories "_collect_stashdir" \
91
+                                         "${permissions}"
92
+}
93
+
94
+
95
+_collect_embedded_stashdir()
96
+{
97
+   # local reposdir="$1"  # ususally .bootstrap.repos
98
+   # local name="$2"      # name of the clone
99
+   # local url="$3"       # URL of the clone
100
+   # local branch="$4"    # branch of the clone
101
+   # local scm="$5"       # scm to use for this clone
102
+   # local tag="$6"       # tag to checkout of the clone
103
+   local stashdir="$7"  # stashdir of this clone (absolute or relative to $PWD)
104
+
105
+   stashparentdir="`dirname -- "${stashdir}"`"
106
+
107
+   [ "${stashparentdir}" = "${STASHES_DEFAULT_DIR}" ] && return
108
+   echo "${stashdir}"
109
+}
110
+
111
+
112
+print_stashdir_embedded_repositories()
113
+{
114
+   walk_auto_repositories "embedded_repositories" \
115
+                     "_collect_embedded_stashdir" \
116
+                     "" \
117
+                     "${EMBEDDED_REPOS_DIR}"
118
+}
119
+
120
+
35 121
 setup_clean_environment()
36 122
 {
37 123
    [ -z "${DEPENDENCIES_DIR}"  ]   && internal_fail "DEPENDENCIES_DIR is empty"
... ...
@@ -41,7 +127,7 @@ setup_clean_environment()
41 127
 
42 128
    CLEAN_EMPTY_PARENTS="`read_config_setting "clean_empty_parent_folders" "YES"`"
43 129
 
44
-   BUILD_CLEANABLE_FILES="${REPOS_DIR}/.bootstrap_build_done"
130
+   OUTPUT_CLEANABLE_FILES="${REPOS_DIR}/.bootstrap_build_done"
45 131
 
46 132
    BUILD_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "clean_folders" "${CLONESBUILD_SUBDIR}
47 133
 ${DEPENDENCIES_DIR}/tmp"`"
... ...
@@ -49,13 +135,33 @@ ${DEPENDENCIES_DIR}/tmp"`"
49 135
    INSTALL_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "install_clean_folders" "${REPOS_DIR}
50 136
 ${STASHES_DEFAULT_DIR}
51 137
 .bootstrap.auto"`"
52
-   DIST_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "dist_clean_folders" "${REPOS_DIR}
138
+   DIST_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "dist_clean_folders" \
139
+"${REPOS_DIR}
53 140
 ${ADDICTIONS_DIR}
54 141
 ${STASHES_DEFAULT_DIR}
55
-.bootstrap.auto"`"
56
-   EMBEDDED="`stashes_of_embedded_repositories "${REPOS_DIR}"`"
142
+${BOOTSTRAP_DIR}.auto"`"
143
+
144
+   # scrub old stuff
145
+   if [ -d ".repos" ]
146
+   then
147
+      DIST_CLEANABLE_SUBDIRS="`add_line "${DIST_CLEANABLE_SUBDIRS}" ".repos"`"
148
+   fi
149
+
150
+   [ -z "${MULLE_BOOTSTRAP_REPOSITORIES_SH}" ] && . mulle-bootstrap-repositories.sh
151
+
152
+   #
153
+   # as a master we don't throw the minions out
154
+   #
155
+   local stashes
156
+
157
+   stashes="`print_stashdir_repositories`"
158
+   DIST_CLEANABLE_SUBDIRS="`add_line "${DIST_CLEANABLE_SUBDIRS}" "${stashes}"`"
57 159
 
58
-   DIST_CLEANABLE_SUBDIRS="`add_line "${EMBEDDED}" "${DIST_CLEANABLE_SUBDIRS}"`"
160
+   stashes="`print_stashdir_embedded_repositories`"
161
+   DIST_CLEANABLE_SUBDIRS="`add_line "${DIST_CLEANABLE_SUBDIRS}" "${stashes}"`"
162
+
163
+   stashes="`print_stashdir_deep_embedded_repositories`"
164
+   DIST_CLEANABLE_SUBDIRS="`add_line "${DIST_CLEANABLE_SUBDIRS}" "${stashes}"`"
59 165
 }
60 166
 
61 167
 
... ...
@@ -70,31 +176,23 @@ EOF
70 176
    setup_clean_environment
71 177
 
72 178
    cat <<EOF >&2
73
-   build   : useful to remove intermediate build files. it cleans
74
-${BUILD_CLEANABLE_SUBDIRS}
75
-${BUILD_CLEANABLE_FILES}
76
-
77
-   output  : useful to rebuild. It cleans
78
-${BUILD_CLEANABLE_SUBDIRS}
79
-${BUILD_CLEANABLE_FILES}
80
-${OUTPUT_CLEANABLE_SUBDIRS}
179
+   build : remove intermediate build files to conserve space. It deletes
180
+`echo "${BUILD_CLEANABLE_SUBDIRS}" | sort | sed '/^$/d' | sed -e 's/^/      /'`
181
+
182
+   output : useful to rebuild. It deletes
183
+`echo "${BUILD_CLEANABLE_SUBDIRS}
184
+${OUTPUT_CLEANABLE_FILES}
185
+${OUTPUT_CLEANABLE_SUBDIRS}"  | sort| sed '/^$/d' | sed -e 's/^/      /'`
81 186
 
82
-   install : useful if you know, you don't want to rebuild.
83
-${BUILD_CLEANABLE_SUBDIRS}
84
-${INSTALL_CLEANABLE_SUBDIRS}
187
+   install : keep only addictions and dependencies
188
+`echo "${BUILD_CLEANABLE_SUBDIRS}
189
+${OUTPUT_CLEANABLE_FILES}
190
+${INSTALL_CLEANABLE_SUBDIRS}" | sort | sed '/^$/d' | sed -e 's/^/      /'`
85 191
 
86
-   dist    : remove all clones, dependencies, addictions. It cleans
87
-${BUILD_CLEANABLE_SUBDIRS}
192
+   dist : remove all clones, dependencies, addictions. It deletes
193
+`echo "${BUILD_CLEANABLE_SUBDIRS}
88 194
 ${OUTPUT_CLEANABLE_SUBDIRS}
89
-${DIST_CLEANABLE_SUBDIRS}
195
+${DIST_CLEANABLE_SUBDIRS}"    | sort | sed '/^$/d' | sed -e 's/^/      /'`
90 196
 EOF
91 197
 
92 198
    exit 1
... ...
@@ -127,17 +225,13 @@ clean_asserted_file()
127 225
 }
128 226
 
129 227
 
130
-
131 228
 clean_parent_folders_if_empty()
132 229
 {
133
-   local dir
134
-   local stop
230
+   local dir="$1"
231
+   local stop="$2"
135 232
 
136 233
    if [ "${CLEAN_EMPTY_PARENTS}" = "YES" ]
137 234
    then
138
-      dir="$1"
139
-      stop="$2"
140
-
141 235
       local parent
142 236
 
143 237
       parent="${dir}"
... ...
@@ -163,9 +257,7 @@ clean_parent_folders_if_empty()
163 257
 
164 258
 clean_files()
165 259
 {
166
-   local files
167
-
168
-   files="$1"
260
+   local files="$1"
169 261
 
170 262
    local file
171 263
 
... ...
@@ -182,13 +274,10 @@ clean_files()
182 274
 }
183 275
 
184 276
 
277
+
185 278
 clean_directories()
186 279
 {
187
-   local directories
188
-   local flag
189
-
190
-   directories="$1"
191
-   flag="$2"
280
+   local directories="$1"
192 281
 
193 282
    local directory
194 283
 
... ...
@@ -200,93 +289,9 @@ clean_directories()
200 289
 
201 290
       clean_asserted_folder "${directory}"
202 291
       clean_parent_folders_if_empty "${directory}" "${PWD}"
203
-      flag="YES"
204 292
    done
205
-   IFS="${DEFAULT_IFS}"
206
-
207
-   echo "$flag"
208
-}
209
-
210
-
211
-
212
-_collect_stashdir()
213
-{
214
-   # local reposdir="$1"  # ususally .bootstrap.repos
215
-   # local name="$2"      # name of the clone
216
-   # local url="$3"       # URL of the clone
217
-   # local branch="$4"    # branch of the clone
218
-   # local scm="$5"       # scm to use for this clone
219
-   # local tag="$6"       # tag to checkout of the clone
220
-   local stashdir="$7"  # stashdir of this clone (absolute or relative to $PWD)
221
-
222
-   is_minion_bootstrap_project "${stashdir}" && return
223
-
224
-   local stashparentdir
225
-
226
-   stashparentdir="`dirname -- "${stashdir}"`"
227
-
228
-   [ "${stashparentdir}" = "${STASHES_DEFAULT_DIR}" ] && return
229
-
230
-   echo "${stashdir}"
231
-}
232
-
233
-
234
-print_stashdir_repositories()
235
-{
236
-   walk_repositories "repositories" \
237
-                     "_collect_stashdir" \
238
-                     "" \
239
-                     "${REPOS_DIR}"
240
-}
241
-
242
-
243
-print_stashdir_embedded_repositories()
244
-{
245
-   walk_repositories "embedded_repositories" \
246
-                     "_collect_stashdir" \
247
-                     "" \
248
-                     "${EMBEDDED_REPOS_DIR}"
249
-}
250
-
251
-
252
-#
253
-# dist cleaning is dangerous
254
-#
255
-_dist_clean()
256
-{
257
-   # dependencies already done before
258 293
 
259
-   DIST_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "dist_clean_folders" \
260
-"${REPOS_DIR}
261
-${ADDICTIONS_DIR}
262
-${STASHES_DEFAULT_DIR}
263
-${BOOTSTRAP_DIR}.auto"`"
264
-
265
-   # scrub old stuff
266
-   if [ -d ".repos" ]
267
-   then
268
-      DIST_CLEANABLE_SUBDIRS="`add_line "${DIST_CLEANABLE_SUBDIRS}" ".repos"`"
269
-   else
270
-      [ -z "${MULLE_BOOTSTRAP_REPOSITORIES_SH}" ] && . mulle-bootstrap-repositories.sh
271
-
272
-      #
273
-      # as a master we don't throw the minions out
274
-      #
275
-      if ! is_master_bootstrap_project
276
-      then
277
-         local stashes
278
-
279
-         stashes="`print_stashdir_repositories`"
280
-         DIST_CLEANABLE_SUBDIRS="`add_line "${DIST_CLEANABLE_SUBDIRS}" "${stashes}"`"
281
-
282
-         stashes="`print_stashdir_embedded_repositories`"
283
-         DIST_CLEANABLE_SUBDIRS="`add_line "${DIST_CLEANABLE_SUBDIRS}" "${stashes}"`"
284
-      fi
285
-   fi
286
-
287
-   clean_directories "${DIST_CLEANABLE_SUBDIRS}" "${flag}"
288
-
289
-   clean_files "${DIST_CLEANABLE_FILES}"
294
+   IFS="${DEFAULT_IFS}"
290 295
 }
291 296
 
292 297
 
... ...
@@ -297,37 +302,30 @@ ${BOOTSTRAP_DIR}.auto"`"
297 302
 # to have other tools provide stuff besides /include and /lib
298 303
 # and sometimes  projects install other stuff into /share
299 304
 #
300
-_clean_execute()
305
+clean_execute()
301 306
 {
302 307
    local style="$1"
303 308
 
304
-   local flag
305
-
306 309
    [ -z "${DEPENDENCIES_DIR}"  ]   && internal_fail "DEPENDENCIES_DIR is empty"
307 310
    [ -z "${CLONESBUILD_SUBDIR}" ]  && internal_fail "CLONESBUILD_SUBDIR is empty"
308 311
    [ -z "${ADDICTIONS_DIR}"   ]    && internal_fail "ADDICTIONS_DIR is empty"
309 312
    [ -z "${STASHES_DEFAULT_DIR}" ] && internal_fail "STASHES_DEFAULT_DIR is empty"
310 313
 
311
-   flag=
312
-   CLEAN_EMPTY_PARENTS="`read_config_setting "clean_empty_parent_folders" "YES"`"
313
-
314
+   setup_clean_environment
314 315
 
315 316
    case "${style}" in
316 317
       build)
317 318
          BUILD_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "clean_folders" "${CLONESBUILD_SUBDIR}
318 319
 ${DEPENDENCIES_DIR}/tmp"`"
319
-         BUILD_CLEANABLE_FILES="${REPOS_DIR}/.bootstrap_build_done"
320
-         clean_directories "${BUILD_CLEANABLE_SUBDIRS}" "${flag}"
321
-         clean_files "${BUILD_CLEANABLE_FILES}"
320
+         clean_directories "${BUILD_CLEANABLE_SUBDIRS}"
322 321
          return
323 322
       ;;
324 323
 
325 324
       dist|output|install)
326 325
          BUILD_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "clean_folders" "${CLONESBUILD_SUBDIR}
327 326
 ${DEPENDENCIES_DIR}/tmp"`"
328
-         BUILD_CLEANABLE_FILES="${REPOS_DIR}/.bootstrap_build_done"
329
-         flag="`clean_directories "${BUILD_CLEANABLE_SUBDIRS}" "${flag}"`"
330
-         clean_files "${BUILD_CLEANABLE_FILES}"
327
+
328
+         clean_directories "${BUILD_CLEANABLE_SUBDIRS}"
331 329
       ;;
332 330
 
333 331
       *)
... ...
@@ -338,14 +336,16 @@ ${DEPENDENCIES_DIR}/tmp"`"
338 336
    case "${style}" in
339 337
       output)
340 338
          OUTPUT_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "output_clean_folders" "${DEPENDENCIES_DIR}"`"
341
-         clean_directories "${OUTPUT_CLEANABLE_SUBDIRS}" "${flag}"
339
+
340
+         clean_directories "${OUTPUT_CLEANABLE_SUBDIRS}"
342 341
          clean_files "${OUTPUT_CLEANABLE_FILES}"
343 342
          return
344 343
       ;;
345 344
 
346 345
       dist)
347 346
          OUTPUT_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "output_clean_folders" "${DEPENDENCIES_DIR}"`"
348
-         flag="`clean_directories "${OUTPUT_CLEANABLE_SUBDIRS}" "${flag}"`"
347
+
348
+         clean_directories "${OUTPUT_CLEANABLE_SUBDIRS}"
349 349
          clean_files "${OUTPUT_CLEANABLE_FILES}"
350 350
       ;;
351 351
    esac
... ...
@@ -354,32 +354,20 @@ ${DEPENDENCIES_DIR}/tmp"`"
354 354
       install)
355 355
          INSTALL_CLEANABLE_SUBDIRS="`read_sane_config_path_setting "install_clean_folders" "${REPOS_DIR}
356 356
 .bootstrap.auto"`"
357
-         clean_directories "${INSTALL_CLEANABLE_SUBDIRS}" "${flag}"
358
-         clean_files "${INSTALL_CLEANABLE_FILES}"
357
+
358
+         clean_directories "${INSTALL_CLEANABLE_SUBDIRS}"
359 359
          return
360 360
       ;;
361 361
    esac
362 362
 
363 363
    case "${style}" in
364 364
       dist)
365
-         _dist_clean
365
+         clean_directories "${DIST_CLEANABLE_SUBDIRS}"
366 366
       ;;
367 367
    esac
368 368
 }
369 369
 
370 370
 
371
-clean_execute()
372
-{
373
-   local flag
374
-
375
-   flag="`_clean_execute "$@"`"
376
-   if [ "$flag" = "NO" ]
377
-   then
378
-      log_info "Nothing configured to clean"
379
-   fi
380
-}
381
-
382
-
383 371
 #
384 372
 # don't rename these settings anymore, the consequences can be catastrophic
385 373
 # for users of previous versions.
... ...
@@ -391,6 +379,7 @@ clean_main()
391 379
 
392 380
    [ -z "${MULLE_BOOTSTRAP_SETTINGS_SH}" ]        && . mulle-bootstrap-settings.sh
393 381
    [ -z "${MULLE_BOOTSTRAP_COMMON_SETTINGS_SH}" ] && . mulle-bootstrap-common-settings.sh
382
+   [ -z "${MULLE_BOOTSTRAP_REPOSITORIES_SH}" ]    && . mulle-bootstrap-repositories.sh
394 383
 
395 384
    [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
396 385
 
... ...
@@ -60,6 +60,8 @@ EOF
60 60
 
61 61
 defer_main()
62 62
 {
63
+   local OPTION_FORCE="NO"
64
+
63 65
    log_debug ":defer_main:"
64 66
 
65 67
    while [ $# -ne 0 ]
... ...
@@ -69,6 +71,10 @@ defer_main()
69 71
             defer_usage
70 72
          ;;
71 73
 
74
+         --force)
75
+            OPTION_FORCE=YES
76
+         ;;
77
+
72 78
          -*)
73 79
             log_error "${MULLE_EXECUTABLE_FAIL_PREFIX}: Unknown option $1"
74 80
             defer_usage
... ...
@@ -83,6 +89,8 @@ defer_main()
83 89
    done
84 90
 
85 91
    [ -z "${MULLE_BOOTSTRAP_PROJECT_SH}" ] && . mulle-bootstrap-project.sh
92
+   [ -z "${MULLE_BOOTSTRAP_COMMON_SETTINGS_SH}" ] && . mulle-bootstrap-common-settings.sh
93
+   [ -z "${MULLE_BOOTSTRAP_CLEAN_SH}" ]           && . mulle-bootstrap-clean.sh
86 94
 
87 95
    unpostpone_trace
88 96
 
... ...
@@ -96,8 +104,12 @@ defer_main()
96 104
    then
97 105
       masterpath="`get_master_of_minion_bootstrap_project "${minionpath}"`"
98 106
       [ ! -z "${masterpath}" ]  || internal_fail "is_minion file empty"
99
-      log_info "Master \"${masterpath}\" already owns \"${minionpath}\""
100
-      return
107
+      log_warning "Master \"${masterpath}\" already owns \"${minionpath}\""
108
+
109
+      if [ "${OPTION_FORCE}" = "NO" ]
110
+      then
111
+         return
112
+      fi
101 113
    fi
102 114
 
103 115
    masterpath="${1:-..}"
... ...
@@ -108,6 +120,16 @@ defer_main()
108 120
       fail "Master \"${masterpath}\" not found"
109 121
    fi
110 122
 
123
+   if [ -L "${masterpath}" ]
124
+   then
125
+      log_warning "Mater \"${masterpath}\" is a symlink. Don't overcomplicate it."
126
+   fi
127
+
128
+   if [ -L "${minionpath}" ]
129
+   then
130
+      log_warning "Minion \"${minionpath}\" is a symlink. Don't overcomplicate it."
131
+   fi
132
+
111 133
    if ! can_be_master_bootstrap_project "${masterpath}"
112 134
    then
113 135
       fail "\"${masterpath}\" contains a .bootstrap folder. It can't be used as a master"
... ...
@@ -115,25 +137,26 @@ defer_main()
115 137
 
116 138
    if master_owns_minion_bootstrap_project "${masterpath}" "${minionpath}"
117 139
    then
118
-      internal_fail "Master \"${masterpath}\" already owns \"${minionpath}\", but it was not detected before"
140
+      if [ "${OPTION_FORCE}" = "NO" ]
141
+      then
142
+         internal_fail "Master \"${masterpath}\" already owns \"${minionpath}\", but it was not detected before"
143
+      fi
144
+      log_warning "Master \"${masterpath}\" already owns \"${minionpath}\", but it was not detected before"
119 145
    fi
120 146
 
121
-   log_info "Deferring to \"${masterpath}\""
122
-
123
-   make_master_bootstrap_project "${masterpath}"
124
-   make_minion_bootstrap_project "${minionpath}" "${masterpath}"
125
-
126
-   [ -z "${MULLE_BOOTSTRAP_COMMON_SETTINGS_SH}" ] && . mulle-bootstrap-common-settings.sh
127
-   [ -z "${MULLE_BOOTSTRAP_CLEAN_SH}" ]           && . mulle-bootstrap-clean.sh
128
-
129 147
    #
130 148
    # dist clean ourselves
131 149
    #
132 150
    log_info "Cleaning minion before deferral"
133 151
 
134
-   clean_execute "dist"
152
+   ( clean_execute "dist" )
153
+
154
+
155
+   log_info "Deferring \"${minionpath}\" to \"${masterpath}\""
135 156
 
157
+   make_master_bootstrap_project "${masterpath}"
136 158
    master_add_minion_bootstrap_project "${masterpath}" "${minionpath}"
159
+   make_minion_bootstrap_project "${minionpath}" "${masterpath}"
137 160
 
138 161
    #
139 162
    # clean the master, because cmake doesn't like old paths
... ...
@@ -147,6 +170,8 @@ emancipate_main()
147 170
 {
148 171
    log_debug ":emancipate_main:"
149 172
 
173
+   local OPTION_FORCE="NO"
174
+
150 175
    while [ $# -ne 0 ]
151 176
    do
152 177
       case "$1" in
... ...
@@ -154,6 +179,10 @@ emancipate_main()
154 179
             defer_usage
155 180
          ;;
156 181
 
182
+         --force)
183
+            OPTION_FORCE=YES
184
+         ;;
185
+
157 186
          -*)
158 187
             log_error "${MULLE_EXECUTABLE_FAIL_PREFIX}: Unknown option $1"
159 188
             defer_usage
... ...
@@ -168,6 +197,8 @@ emancipate_main()
168 197
    done
169 198
 
170 199
    [ -z "${MULLE_BOOTSTRAP_PROJECT_SH}" ] && . mulle-bootstrap-project.sh
200
+   [ -z "${MULLE_BOOTSTRAP_COMMON_SETTINGS_SH}" ] && . mulle-bootstrap-common-settings.sh
201
+   [ -z "${MULLE_BOOTSTRAP_CLEAN_SH}" ] && . mulle-bootstrap-clean.sh
171 202
 
172 203
    unpostpone_trace
173 204
 
... ...
@@ -180,8 +211,12 @@ emancipate_main()
180 211
    minionpath="`absolutepath "${minionpath}"`"
181 212
    if ! is_minion_bootstrap_project "${minionpath}"
182 213
    then
183
-      log_info "Project \"${minionpath}\" does not defer to a master and is already emancipated"
184
-      return
214
+      log_warning "Project \"${minionpath}\" does not defer to a master and is already emancipated"
215
+
216
+      if [ "${OPTION_FORCE}" = "NO" ]
217
+      then
218
+         return
219
+      fi
185 220
    fi
186 221
 
187 222
    masterpath="`get_master_of_minion_bootstrap_project \"${minionpath}\"`"
... ...
@@ -200,16 +235,13 @@ emancipate_main()
200 235
       fail "\"${masterpath}\" is not a master project"
201 236
    fi
202 237
 
203
-   log_info "Emancipating from \"${masterpath}\""
204
-   master_remove_minion_bootstrap_project "${masterpath}" "${minionpath}"
205
-
206 238
    log_info "Cleaning master before emancipation"
207
-   clean_execute "output"
239
+   ( clean_execute "output" )  # not really critical if fails
208 240
 
209
-   emancipate_minion_bootstrap_project "${minionpath}"
241
+   log_info "Emancipating \"${minionpath}\" from \"${masterpath}\""
242
+   master_remove_minion_bootstrap_project "${masterpath}" "${minionpath}"
210 243
 
211
-   [ -z "${MULLE_BOOTSTRAP_COMMON_SETTINGS_SH}" ] && . mulle-bootstrap-common-settings.sh
212
-   [ -z "${MULLE_BOOTSTRAP_CLEAN_SH}" ] && . mulle-bootstrap-clean.sh
244
+   emancipate_minion_bootstrap_project "${minionpath}"
213 245
 
214 246
    #
215 247
    # dist clean ourselves
... ...
@@ -65,7 +65,7 @@ usage:
65 65
 
66 66
       --allow-symlinks    :  allow symlinking instead of cloning
67 67
       --embedded-symlinks :  allow embedded symlinks (very experimental)
68
-      --update-symlinks   :  follow symlinks when updating (not recommended)
68
+      --follow-symlinks   :  follow symlinks when updating (not recommended)
69 69
       --no-caches         :  don't use caches. Useful to counter flag -y
70 70
       --no-symlinks       :  don't create symlinks. Useful to counter flag -y
71 71
 
... ...
@@ -649,16 +649,11 @@ _update_operation_walk_repositories()
649 649
 
650 650
    local permissions
651 651
 
652
-   permissions=""
653
-   if [ "${OPTION_ALLOW_UPDATING_SYMLINKS}" = "YES" ]
654
-   then
655
-      permissions="`add_line "${permissions}" "symlink"`"
656
-   fi
657
-
658
-   walk_repositories "repositories"  \
659
-                     "${operation}" \
660
-                     "${permissions}" \
661
-                     "${REPOS_DIR}"
652
+   permissions="minion"
653
+   walk_auto_repositories "repositories"  \
654
+                          "${operation}" \
655
+                          "${permissions}" \
656
+                          "${REPOS_DIR}"
662 657
 }
663 658
 
664 659
 
... ...
@@ -668,12 +663,7 @@ _update_operation_walk_embedded_repositories()
668 663
 
669 664
    local permissions
670 665
 
671
-   permissions=""
672
-   if [ "${OPTION_ALLOW_UPDATING_SYMLINKS}" = "YES" ]
673
-   then
674
-      permissions="`add_line "${permissions}" "symlink"`"
675
-   fi
676
-
666
+   permissions="minion"
677 667
    #
678 668
    # embedded repositories can't be symlinked by default
679 669
    # embedded repositories are by default not put into
... ...
@@ -684,31 +674,27 @@ _update_operation_walk_embedded_repositories()
684 674
       STASHES_DEFAULT_DIR=""
685 675
       OPTION_ALLOW_CREATING_SYMLINKS="${OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS}" ;
686 676
 
687
-      walk_repositories "embedded_repositories"  \
688
-                        "${operation}" \
689
-                        "${permissions}" \
690
-                        "${EMBEDDED_REPOS_DIR}"
677
+      walk_auto_repositories "embedded_repositories"  \
678
+                             "${operation}" \
679
+                             "${permissions}" \
680
+                             "${EMBEDDED_REPOS_DIR}"
691 681
    ) || exit 1
692 682
 }
693 683
 
694 684
 
695
-_update_operation_walk_deep_embedded_repositories()
685
+_update_operation_walk_deep_embedded_auto_repositories()
696 686
 {
697 687
    local operation="$1"
698 688
 
699 689
    local permissions
700 690
 
701
-   permissions=""
702
-   if [ "${OPTION_ALLOW_UPDATING_SYMLINKS}" = "YES" ]
703
-   then
704
-      permissions="`add_line "${permissions}" "symlink"`"
705
-   fi
691
+   permissions="minion"
706 692
 
707 693
    (
708 694
       OPTION_ALLOW_CREATING_SYMLINKS="${OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS}" ;
709 695
 
710
-      walk_deep_embedded_repositories "${operation}" \
711
-                                      "${permissions}"
696
+      walk_deep_embedded_auto_repositories "${operation}" \
697
+                                           "${permissions}"
712 698
    ) || exit 1
713 699
 }
714 700
 
... ...
@@ -730,7 +716,7 @@ update_embedded_repositories()
730 716
 
731 717
 update_deep_embedded_repositories()
732 718
 {
733
-   _update_operation_walk_deep_embedded_repositories "update_repository"
719
+   _update_operation_walk_deep_embedded_auto_repositories "update_repository"
734 720
 }
735 721
 
736 722
 
... ...
@@ -751,7 +737,7 @@ upgrade_embedded_repositories()
751 737
 
752 738
 upgrade_deep_embedded_repositories()
753 739
 {
754
-   _update_operation_walk_deep_embedded_repositories "upgrade_repository"
740
+   _update_operation_walk_deep_embedded_auto_repositories "upgrade_repository"
755 741
 }
756 742
 
757 743
 
... ...
@@ -1183,13 +1169,8 @@ fetch_once_deep_embedded_repositories()
1183 1169
 {
1184 1170
    log_debug "fetch_once_deep_embedded_repositories"
1185 1171
 
1186
-   permissions=""
1187
-   if [ "${OPTION_ALLOW_UPDATING_SYMLINKS}" = "YES" ]
1188
-   then
1189
-      permissions="`add_line "${permissions}" "symlink"`"
1190
-   fi
1191
-
1192
-   walk_repositories "repositories"  \
1172
+   permissions="minion"
1173
+   walk_auto_repositories "repositories"  \
1193 1174
                      "_fetch_once_deep_repository" \
1194 1175
                      "${permissions}" \
1195 1176
                      "${REPOS_DIR}" > /dev/null
... ...
@@ -1282,6 +1263,8 @@ fetch_loop()
1282 1263
 
1283 1264
    bootstrap_auto_create
1284 1265
 
1266
+   log_info "Checking repositories..."
1267
+
1285 1268
    fetch_once_embedded_repositories
1286 1269
 
1287 1270
    if [ "${OPTION_EMBEDDED_ONLY}" = "NO" ]
... ...
@@ -1359,7 +1342,7 @@ _common_main()
1359 1342
    [ -z "${MULLE_BOOTSTRAP_SETTINGS_SH}" ]          && . mulle-bootstrap-settings.sh
1360 1343
 
1361 1344
    local OPTION_CHECK_USR_LOCAL_INCLUDE="NO"
1362
-   local OPTION_ALLOW_UPDATING_SYMLINKS="NO"
1345
+   local MULLE_FLAG_FOLLOW_SYMLINKS="NO"
1363 1346
    local OPTION_ALLOW_CREATING_SYMLINKS="NO"
1364 1347
    local OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS="NO"
1365 1348
    local OPTION_ALLOW_SEARCH_CACHES="NO"
... ...
@@ -1399,7 +1382,7 @@ _common_main()
1399 1382
    case "${UNAME}" in
1400 1383
       mingw)
1401 1384
          OPTION_ALLOW_CREATING_SYMLINKS="NO"
1402
-         OPTION_ALLOW_UPDATING_SYMLINKS="NO"
1385
+         MULLE_FLAG_FOLLOW_SYMLINKS="NO"
1403 1386
       ;;
1404 1387
 
1405 1388
       *)
... ...
@@ -1432,9 +1415,9 @@ _common_main()
1432 1415
             OPTION_EMBEDDED_ONLY="YES"
1433 1416
          ;;
1434 1417
 
1435
-         # update symlinks, dangerous!
1436
-         --update-symlinks)
1437
-            OPTION_ALLOW_UPDATING_SYMLINKS="YES"
1418
+         # update symlinks, dangerous (duplicate to flags for laziness reasons)
1419
+         --follow-symlinks)
1420
+            MULLE_FLAG_FOLLOW_SYMLINKS="YES"
1438 1421
          ;;
1439 1422
 
1440 1423
          # create symlinks instead of clones for repositories
... ...
@@ -1442,7 +1425,12 @@ _common_main()
1442 1425
             OPTION_ALLOW_CREATING_SYMLINKS="YES"
1443 1426
          ;;
1444 1427
 
1428
+         #
1445 1429
          # create symlinks instead of clones for embedded_repositories
1430
+         # and deep embedded_repositories. If the clones are symlinked
1431
+         # this will be ignored, except if follow-symlinks is
1432
+         # active. --follow-symlinks is really not safe!
1433
+         #
1446 1434
          --embedded-symlink-creation|--embedded-symlinks)
1447 1435
             OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS="YES"
1448 1436
          ;;
... ...
@@ -1453,11 +1441,12 @@ _common_main()
1453 1441
          ;;
1454 1442
 
1455 1443
          --no-symlink-creation|--no-symlinks)
1456
-            OPTION_ALLOW_UPDATING_SYMLINKS="NO"
1444
+            MULLE_FLAG_FOLLOW_SYMLINKS="NO"
1457 1445
             OPTION_ALLOW_CREATING_EMBEDDED_SYMLINKS="NO"
1458 1446
             OPTION_ALLOW_CREATING_SYMLINKS="NO"
1459 1447
          ;;
1460 1448
 
1449
+         # TODO: outdated!
1461 1450
          # build options with no parameters
1462 1451
          -K|--clean|-k|--no-clean|--use-prefix-libraries|--debug|--release)
1463 1452
             if [ -z "${MULLE_BOOTSTRAP_WILL_BUILD}" ]
... ...
@@ -1468,6 +1457,7 @@ _common_main()
1468 1457
          ;;
1469 1458
 
1470 1459
          # build options with one parameter
1460
+         # TODO: outdated!
1471 1461
          -j|--cores|-c|--configuration|--prefix)
1472 1462
             if [ -z "${MULLE_BOOTSTRAP_WILL_BUILD}" ]
1473 1463
             then
... ...
@@ -203,17 +203,19 @@ is_yes()
203 203
 
204 204
 add_cmake_path_if_exists()
205 205
 {
206
-   local line
207
-   local path
208
-
209
-   line="$1"
210
-   path="$2"
206
+   local line="$1"
207
+   local path="$2"
211 208
 
212
-   if [ -z "${line}" -o ! -e "${line}" ]
209
+   if [ ! -e "${path}" ]
213 210
    then
214
-      echo "${path}"
211
+      echo "${line}"
215 212
    else
216
-      echo "${line};${path}"
213
+      if [ -z "${line}" ]
214
+      then
215
+         echo "${path}"
216
+      else
217
+         echo "${line};${path}"
218
+      fi
217 219
    fi
218 220
 }
219 221
 
... ...
@@ -235,13 +237,24 @@ add_cmake_path()
235 237
 }
236 238
 
237 239
 
238
-add_line()
240
+add_word()
239 241
 {
240
-   local lines
241
-   local line
242
+   local line="$1"
243
+   local word="$2"
242 244
 
243
-   lines="$1"
244
-   line="$2"
245
+   if [ -z "${line}" ]
246
+   then
247
+      echo "${word}"
248
+   else
249
+      echo "${line} ${word}"
250
+   fi
251
+}
252
+
253
+
254
+add_line()
255
+{
256
+   local lines="$1"
257
+   local line="$2"
245 258
 
246 259
    if [ -z "${lines}" ]
247 260
    then
... ...
@@ -111,11 +111,14 @@ add_path()
111 111
 
112 112
 add_path_if_exists()
113 113
 {
114
+   local line="$1"
115
+   local path="$2"
116
+
114 117
    if [ -e "${path}" ]
115 118
    then
116 119
       add_path "$@"
117 120
    else
118
-      echo "$1"
121
+      echo "${line}"
119 122
    fi
120 123
 }
121 124
 
... ...
@@ -192,11 +195,12 @@ fetch_needed()
192 195
    [ -z "${REPOS_DIR}" ]     && internal_fail "REPOS_DIR undefined"
193 196
    [ -z "${BOOTSTRAP_DIR}" ] && internal_fail "BOOTSTRAP_DIR undefined"
194 197
 
195
-   if [ ! -f "${BOOTSTRAP_DIR}.local/build_order" ]
196
-   then
197
-      log_fluff "Need fetch because \"${BOOTSTRAP_DIR}.local/build_order\" does not exist."
198
-      return 0
199
-   fi
198
+   # doppelt gemoppelt
199
+   # if [ ! -f "${BOOTSTRAP_DIR}.auto/build_order" ]
200
+   # then
201
+   #    log_fluff "Need fetch because \"${BOOTSTRAP_DIR}.auto/build_order\" does not exist."
202
+   #    return 0
203
+   # fi
200 204
 
201 205
    if [ ! -f "${REPOS_DIR}/.bootstrap_fetch_done" ]
202 206
    then
... ...
@@ -226,9 +230,8 @@ set_fetch_needed()
226 230
 {
227 231
    [ -z "${MULLE_BOOTSTRAP_FUNCTIONS_SH}" ] && . mulle-bootstrap-functions.sh
228 232
 
229
-   remove_file_if_present "${BOOTSTRAP_DIR}.local/build_order"
230
-   remove_file_if_present "${BOOTSTRAP_DIR}.local/.bootstrap_fetch_started"
231
-   remove_file_if_present "${BOOTSTRAP_DIR}.local/.bootstrap_fetch_done"
233
+   remove_file_if_present "${REPOS_DIR}/.bootstrap_fetch_started"
234
+   remove_file_if_present "${REPOS_DIR}/.bootstrap_fetch_done"
232 235
 }
233 236
 
234 237
 
... ...
@@ -236,8 +239,8 @@ set_build_needed()
236 239
 {
237 240
    [ -z "${MULLE_BOOTSTRAP_FUNCTIONS_SH}" ] && . mulle-bootstrap-functions.sh
238 241
 
239
-   remove_file_if_present "${BOOTSTRAP_DIR}.local/.bootstrap_build_started"
240
-   remove_file_if_present "${BOOTSTRAP_DIR}.local/.bootstrap_build_done"
242
+   remove_file_if_present "${REPOS_DIR}/.bootstrap_build_started"
243
+   remove_file_if_present "${REPOS_DIR}/.bootstrap_build_done"
241 244
 }
242 245
 
243 246
 
... ...
@@ -105,7 +105,14 @@ log_debug()
105 105
 {
106 106
    if [ "${MULLE_FLAG_LOG_DEBUG}" = "YES"  ]
107 107
    then
108
-      log_printf "${C_BR_RED}%b${C_RESET}\n" "$*"
108
+      case "${UNAME}" in
109
+         linux)
110
+            log_printf "${C_BR_RED}$(date "+%s.%N") %b${C_RESET}\n" "$*"
111
+         ;;
112
+         *)
113
+            log_printf "${C_BR_RED}$(date "+%s") %b${C_RESET}\n" "$*"
114
+         ;;
115
+      esac
109 116
    fi
110 117
 }
111 118
 
... ...
@@ -125,11 +132,10 @@ log_trace2()
125 132
 #
126 133
 # some common fail log functions
127 134
 #
128
-fail()
129
-{
130
-   log_error "${MULLE_EXECUTABLE_FAIL_PREFIX}:" "$@"
131 135
 
132
-   local i=0
136
+stacktrace()
137
+{
138
+   local i=1
133 139
    local line
134 140
 
135 141
    while line="`caller $i`"
... ...
@@ -137,7 +143,11 @@ fail()
137 143
       log_info "$i: #${line}"
138 144
       ((i++))
139 145
    done
146
+}
140 147
 
148
+
149
+_bail()
150
+{
141 151
    # should kill process group...
142 152
    kill 0
143 153
 
... ...
@@ -155,9 +165,18 @@ fail()
155 165
 }
156 166
 
157 167
 
168
+fail()
169
+{
170
+   log_error "${MULLE_EXECUTABLE_FAIL_PREFIX}:" "$@"
171
+   _bail
172
+}
173
+
174
+
158 175
 internal_fail()
159 176
 {
160
-   fail "${C_RED}*** internal error: ${C_BR_RED}$*"
177
+   log_error "${MULLE_EXECUTABLE_FAIL_PREFIX}:" "${C_RED}*** internal error: ${C_BR_RED}$*"
178
+   stacktrace
179
+   _bail
161 180
 }
162 181
 
163 182
 
... ...
@@ -217,7 +236,7 @@ logging_initialize()
217 236
             C_FAINT="\033[2m"
218 237
 
219 238
             C_RESET_BOLD="${C_RESET}${C_BOLD}"
220
-            trap 'printf "${C_RESET} >&2 ; exit 1"' TERM INT
239
+            trap 'printf "${C_RESET}" >&2 ; exit 1' TERM INT
221 240
             ;;
222 241
       esac
223 242
    fi
... ...
@@ -186,6 +186,11 @@ all_repository_stashes()
186 186
 }
187 187
 
188 188
 
189
+all_embedded_repository_stashes()
190
+{
191
+   _all_repository_stashes "${EMBEDDED_REPOS_DIR}"
192
+}
193
+
189 194
 
190 195
 #
191 196
 # Walkers
... ...
@@ -194,29 +199,27 @@ all_repository_stashes()
194 199
 #
195 200
 walk_check()
196 201
 {
197
-   local name="$1" ; shift
198