Fix using Bazel-built libraries by cmake_external and configure_make (#249)
Fix #232 - enable usage of Bazel-built libraries as dependencies of cmake_external and configure_make. - fix logic of reading library data described by C/C++ Bazel interface (as CcInfo.linking_context appeared) - symlink transitive include directories under $EXT_BUILD_DEPS - gather all possible transitive include directories to pass to CMake, pass transitive include directories to CMAKE_PREFIX_PATH so that the transitive include directories were scanned by CMake - fix logic of passing transitive libraries into CPPFLAGS (configure_make) - add test with the chain: Bazel lib -> CMake lib -> Bazel cc_test - add synthetic configure-make test with the chain: Bazel lib -> configure_make lib -> Bazel cc_test - also notice, that passed include directories from Bazel C/C++ Sandwich interface are not always existing; for now, make symlinking code resistant to that see https://www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Preset-Output-Variables.html
This commit is contained in:
parent
6b04da2262
commit
e36f3cee8c
|
@ -22,9 +22,11 @@ test_suite(
|
|||
name = "tests",
|
||||
tests = tests + [
|
||||
"//cmake_synthetic:test_libs",
|
||||
"//cmake_with_bazel_transitive:test",
|
||||
"//configure_gnuplot:configure_libgd_tests",
|
||||
"//cmake_hello_world_lib/shared:test_libhello",
|
||||
"//cmake_hello_world_lib/binary:test_binary",
|
||||
"//configure_with_bazel_transitive:test",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
load("@rules_foreign_cc//tools/build_defs:cmake.bzl", "cmake_external")
|
||||
|
||||
filegroup(
|
||||
name = "b_srcs",
|
||||
srcs = glob(["libb/**"]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
generate_crosstool = select({
|
||||
"@bazel_tools//src/conditions:windows": True,
|
||||
"//conditions:default": False,
|
||||
|
@ -41,7 +35,7 @@ cc_test(
|
|||
],
|
||||
tags = ["windows"],
|
||||
deps = [
|
||||
":liba",
|
||||
# liba should come from transitive dependencies
|
||||
":libb",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -3,3 +3,11 @@ filegroup(
|
|||
srcs = glob(["**"]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "lib_a_bazel",
|
||||
srcs = ["src/liba.cpp"],
|
||||
hdrs = ["src/liba.h"],
|
||||
includes = ["src"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
load("@rules_foreign_cc//tools/build_defs:cmake.bzl", "cmake_external")
|
||||
|
||||
# Example of the cmake_external target built with Bazel-built dependency
|
||||
cmake_external(
|
||||
name = "cmake_libb",
|
||||
cache_entries = {
|
||||
# as currently we copy all libraries, built with Bazel, into $EXT_BUILD_DEPS/lib
|
||||
# and the headers into $EXT_BUILD_DEPS/include
|
||||
"LIBA_DIR": "$EXT_BUILD_DEPS",
|
||||
# CMake's find_package wants to find cmake config for liba,
|
||||
# which we do not have -> disable search
|
||||
"CMAKE_DISABLE_FIND_PACKAGE_LIBA": "True",
|
||||
},
|
||||
cmake_options = ["-GNinja"],
|
||||
lib_source = "//cmake_with_bazel_transitive/libb:b_srcs",
|
||||
make_commands = [
|
||||
"ninja",
|
||||
"ninja install",
|
||||
],
|
||||
static_libraries = ["libb.a"],
|
||||
# This library is with public visibility, we can reuse it here.
|
||||
deps = ["//cmake_synthetic/liba:lib_a_bazel"],
|
||||
)
|
||||
|
||||
# And cc_test built with cmake_external dependency and transitive Bazel dependency
|
||||
cc_test(
|
||||
name = "test",
|
||||
srcs = [
|
||||
"test_libb.cpp",
|
||||
],
|
||||
deps = [
|
||||
# liba should come from transitive dependencies
|
||||
":cmake_libb",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,5 @@
|
|||
filegroup(
|
||||
name = "b_srcs",
|
||||
srcs = glob(["**"]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,5 @@
|
|||
cmake_minimum_required(VERSION 2.8.4)
|
||||
|
||||
project(libb)
|
||||
|
||||
add_subdirectory(src)
|
|
@ -0,0 +1,24 @@
|
|||
cmake_minimum_required(VERSION 2.8.4)
|
||||
|
||||
set(LIBB_SRC libb.cpp libb.h)
|
||||
|
||||
add_library(libb_static STATIC ${LIBB_SRC})
|
||||
set_target_properties(libb_static PROPERTIES OUTPUT_NAME "libb")
|
||||
IF (WIN32)
|
||||
set_target_properties(libb_static PROPERTIES ARCHIVE_OUTPUT_NAME "libb")
|
||||
ELSE()
|
||||
set_target_properties(libb_static PROPERTIES ARCHIVE_OUTPUT_NAME "b")
|
||||
ENDIF()
|
||||
|
||||
find_package(LIBA NAMES alib liba libliba)
|
||||
|
||||
# LIBA_INCLUDE_DIRS is not set, so giving the path relative to liba_config.cmake
|
||||
# would be happy to improve that
|
||||
target_link_libraries(libb_static PUBLIC ${LIBA_DIR}/lib/liba.a)
|
||||
target_include_directories(libb_static PUBLIC ${LIBA_DIR}/include)
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
|
||||
|
||||
install(TARGETS libb_static ARCHIVE DESTINATION lib)
|
||||
|
||||
install(FILES libb.h DESTINATION include)
|
|
@ -0,0 +1,5 @@
|
|||
#include "libb.h"
|
||||
|
||||
std::string hello_libb(void) {
|
||||
return hello_liba() + " Hello from LIBB!";
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef LIBB_H_
|
||||
#define LIBB_H_ (1)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include "liba.h"
|
||||
|
||||
std::string hello_libb(void);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,13 @@
|
|||
#include "libb.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
std:: string result = hello_libb();
|
||||
if (result != "Hello from LIBA! Hello from LIBB!") {
|
||||
throw std::runtime_error("Wrong result: " + result);
|
||||
}
|
||||
std::cout << "Everything's fine!";
|
||||
}
|
|
@ -8,6 +8,9 @@ configure_make(
|
|||
|
||||
configure_make(
|
||||
name = "libpng",
|
||||
configure_options = [
|
||||
"--with-zlib=\"$$EXT_BUILD_DEPS$$/libz\"",
|
||||
],
|
||||
lib_source = "@libpng//:all",
|
||||
out_include_dir = "include/libpng16",
|
||||
static_libraries = ["libpng16.a"],
|
||||
|
@ -16,13 +19,13 @@ configure_make(
|
|||
|
||||
configure_make(
|
||||
name = "freetype",
|
||||
lib_source = "@freetype//:all",
|
||||
out_include_dir = "include/freetype2",
|
||||
static_libraries = ["libfreetype.a"],
|
||||
configure_options = [
|
||||
"--with-png=\"$$EXT_BUILD_DEPS$$/libpng\"",
|
||||
"--with-zlib=\"$$EXT_BUILD_DEPS$$/libz\"",
|
||||
],
|
||||
lib_source = "@freetype//:all",
|
||||
out_include_dir = "include/freetype2",
|
||||
static_libraries = ["libfreetype.a"],
|
||||
deps = [
|
||||
":libpng",
|
||||
":libz",
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
load("@rules_foreign_cc//tools/build_defs:configure.bzl", "configure_make")
|
||||
|
||||
cc_library(
|
||||
name = "built_with_bazel",
|
||||
srcs = ["builtWithBazel.c"],
|
||||
hdrs = ["builtWithBazel.h"],
|
||||
includes = ["."],
|
||||
)
|
||||
|
||||
configure_make(
|
||||
name = "simple",
|
||||
configure_in_place = True,
|
||||
lib_source = "//configure_with_bazel_transitive/simple_lib:simple_srcs",
|
||||
make_commands = [
|
||||
"make simple",
|
||||
"make install",
|
||||
],
|
||||
deps = [":built_with_bazel"],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "test",
|
||||
srcs = ["testSimple.c"],
|
||||
deps = [":simple"],
|
||||
)
|
|
@ -0,0 +1,5 @@
|
|||
#include "builtWithBazel.h"
|
||||
|
||||
char* bazelSays(void) {
|
||||
return "It's me, Bazel!";
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef BUILT_WITH_BAZEL_H_
|
||||
#define BUILT_WITH_BAZEL_H_ (1)
|
||||
|
||||
char* bazelSays(void);
|
||||
|
||||
#endif // BUILT_WITH_BAZEL_H_
|
|
@ -0,0 +1,5 @@
|
|||
filegroup(
|
||||
name = "simple_srcs",
|
||||
srcs = glob(["**"]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
|
@ -0,0 +1,7 @@
|
|||
simple: ./src/simple.c
|
||||
gcc $(CPPFLAGS) $(LDFLAGS) -o simple.a -c ./src/simple.c -I./include -I.
|
||||
install:
|
||||
mkdir -p simple
|
||||
mkdir -p simple/lib
|
||||
cp simple.a ./simple/lib/simple.a
|
||||
cp -r ./include ./simple
|
|
@ -0,0 +1,5 @@
|
|||
ls "$EXT_BUILD_DEPS/lib"
|
||||
echo "CPPFLAGS = $CPPFLAGS" > Makefile
|
||||
echo "LDFLAGS = $LDFLAGS" >> Makefile
|
||||
echo "BUILT_WITH_BAZEL = $EXT_BUILD_DEPS/lib/libbuilt_with_bazel.a" >> Makefile
|
||||
cat Makefile.in >> Makefile
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef SIMPLE_H_
|
||||
#define SIMPLE_H_ (1)
|
||||
|
||||
void simpleFun(void);
|
||||
|
||||
#endif // SIMPLE_H_
|
|
@ -0,0 +1,7 @@
|
|||
#include <stdio.h>
|
||||
#include "simple.h"
|
||||
#include "builtWithBazel.h"
|
||||
|
||||
void simpleFun(void) {
|
||||
printf("simpleFun: %s", bazelSays());
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
#include "builtWithBazel.h"
|
||||
#include "simple.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
printf("Call bazelSays() directly: %s\n", bazelSays());
|
||||
simpleFun();
|
||||
return 0;
|
||||
}
|
|
@ -65,19 +65,20 @@ def _create_configure_script(configureParameters):
|
|||
|
||||
define_install_prefix = "export INSTALL_PREFIX=\"" + _get_install_prefix(ctx) + "\"\n"
|
||||
configure_script = create_cmake_script(
|
||||
ctx.workspace_name,
|
||||
workspace_name = ctx.workspace_name,
|
||||
# as default, pass execution OS as target OS
|
||||
os_name(ctx),
|
||||
configureParameters.attrs.cmake_path,
|
||||
tools,
|
||||
flags,
|
||||
"$$INSTALL_PREFIX$$",
|
||||
root,
|
||||
no_toolchain_file,
|
||||
dict(ctx.attr.cache_entries),
|
||||
dict(ctx.attr.env_vars),
|
||||
ctx.attr.cmake_options,
|
||||
is_debug_mode(ctx),
|
||||
target_os = os_name(ctx),
|
||||
cmake_path = configureParameters.attrs.cmake_path,
|
||||
tools = tools,
|
||||
flags = flags,
|
||||
install_prefix = "$$INSTALL_PREFIX$$",
|
||||
root = root,
|
||||
no_toolchain_file = no_toolchain_file,
|
||||
user_cache = dict(ctx.attr.cache_entries),
|
||||
user_env = dict(ctx.attr.env_vars),
|
||||
options = ctx.attr.cmake_options,
|
||||
include_dirs = inputs.include_dirs,
|
||||
is_debug_mode = is_debug_mode(ctx),
|
||||
)
|
||||
return define_install_prefix + configure_script
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ def create_cmake_script(
|
|||
user_cache,
|
||||
user_env,
|
||||
options,
|
||||
include_dirs = [],
|
||||
is_debug_mode = True):
|
||||
""" Constructs CMake script to be passed to cc_external_rule_impl.
|
||||
Args:
|
||||
|
@ -29,7 +30,7 @@ def create_cmake_script(
|
|||
user_env - dictionary with user's values for CMake environment variables
|
||||
options - other CMake options specified by user
|
||||
"""
|
||||
merged_prefix_path = _merge_prefix_path(user_cache)
|
||||
merged_prefix_path = _merge_prefix_path(user_cache, include_dirs)
|
||||
|
||||
toolchain_dict = _fill_crossfile_from_toolchain(workspace_name, target_os, tools, flags)
|
||||
params = None
|
||||
|
@ -72,13 +73,14 @@ def wipe_empty_values(cache, user_cache):
|
|||
cache.pop(key)
|
||||
|
||||
# From CMake documentation: ;-list of directories specifying installation prefixes to be searched...
|
||||
def _merge_prefix_path(user_cache):
|
||||
def _merge_prefix_path(user_cache, include_dirs):
|
||||
user_prefix = user_cache.get("CMAKE_PREFIX_PATH")
|
||||
values = ["$EXT_BUILD_DEPS"] + include_dirs
|
||||
if user_prefix != None:
|
||||
# remove it, it is gonna be merged specifically
|
||||
user_cache.pop("CMAKE_PREFIX_PATH")
|
||||
return "$EXT_BUILD_DEPS;" + user_prefix.strip("\"'")
|
||||
return "$EXT_BUILD_DEPS"
|
||||
values.append(user_prefix.strip("\"'"))
|
||||
return ";".join(values)
|
||||
|
||||
_CMAKE_ENV_VARS_FOR_CROSSTOOL = {
|
||||
"CC": struct(value = "CMAKE_C_COMPILER", replace = True),
|
||||
|
|
|
@ -41,19 +41,19 @@ def _create_configure_script(configureParameters):
|
|||
define_install_prefix = "export INSTALL_PREFIX=\"" + _get_install_prefix(ctx) + "\"\n"
|
||||
|
||||
configure = create_configure_script(
|
||||
ctx.workspace_name,
|
||||
workspace_name = ctx.workspace_name,
|
||||
# as default, pass execution OS as target OS
|
||||
os_name(ctx),
|
||||
tools,
|
||||
flags,
|
||||
root,
|
||||
ctx.attr.configure_options,
|
||||
dict(ctx.attr.configure_env_vars),
|
||||
is_debug_mode(ctx),
|
||||
ctx.attr.configure_command,
|
||||
ctx.attr.deps,
|
||||
inputs,
|
||||
ctx.attr.configure_in_place,
|
||||
target_os = os_name(ctx),
|
||||
tools = tools,
|
||||
flags = flags,
|
||||
root = root,
|
||||
user_options = ctx.attr.configure_options,
|
||||
user_vars = dict(ctx.attr.configure_env_vars),
|
||||
is_debug = is_debug_mode(ctx),
|
||||
configure_command = ctx.attr.configure_command,
|
||||
deps = ctx.attr.deps,
|
||||
inputs = inputs,
|
||||
configure_in_place = ctx.attr.configure_in_place,
|
||||
)
|
||||
return "\n".join([define_install_prefix, configure])
|
||||
|
||||
|
|
|
@ -17,9 +17,11 @@ def create_configure_script(
|
|||
vars = _get_configure_variables(tools, flags, user_vars)
|
||||
deps_flags = _define_deps_flags(deps, inputs)
|
||||
|
||||
vars["LDFLAGS"] = vars["LDFLAGS"] + deps_flags["LDFLAGS"]
|
||||
vars["CPPFLAGS"] = deps_flags["CPPFLAGS"]
|
||||
# vars["SYSROOT"] = "$EXT_BUILD_DEPS"
|
||||
vars["LDFLAGS"] = vars["LDFLAGS"] + deps_flags.libs
|
||||
|
||||
# -I flags should be put into preprocessor flags, CPPFLAGS
|
||||
# https://www.gnu.org/software/autoconf/manual/autoconf-2.63/html_node/Preset-Output-Variables.html
|
||||
vars["CPPFLAGS"] = deps_flags.flags
|
||||
|
||||
env_vars_string = " ".join(["{}=\"{}\"".format(key, _join_flags_list(workspace_name, vars[key])) for key in vars])
|
||||
|
||||
|
@ -57,14 +59,12 @@ def _define_deps_flags(deps, inputs):
|
|||
lib_dirs += ["-L$$EXT_BUILD_ROOT$$/" + dir_]
|
||||
|
||||
include_dirs_set = {}
|
||||
for dir_list in inputs.include_dirs:
|
||||
for include_dir in dir_list:
|
||||
for include_dir in inputs.include_dirs:
|
||||
include_dirs_set[include_dir] = "-I$$EXT_BUILD_ROOT$$/" + include_dir
|
||||
for header in inputs.headers:
|
||||
include_dir = header.dirname
|
||||
if not include_dirs_set.get(include_dir):
|
||||
include_dirs_set[include_dir] = "-I$$EXT_BUILD_ROOT$$/" + include_dir
|
||||
for header_list in inputs.headers:
|
||||
for header in header_list:
|
||||
include_dir = header.dirname
|
||||
if not include_dirs_set.get(include_dir):
|
||||
include_dirs_set[include_dir] = "-I$$EXT_BUILD_ROOT$$/" + include_dir
|
||||
include_dirs = include_dirs_set.values()
|
||||
|
||||
# For the external libraries, we need to refer to the places where
|
||||
|
@ -85,10 +85,10 @@ def _define_deps_flags(deps, inputs):
|
|||
include_dirs += ["-I$$EXT_BUILD_DEPS$$/{}/{}".format(dir_name, artifact.include_dir_name)]
|
||||
lib_dirs += ["-L$$EXT_BUILD_DEPS$$/{}/{}".format(dir_name, artifact.lib_dir_name)]
|
||||
|
||||
return {
|
||||
"LDFLAGS": lib_dirs,
|
||||
"CPPFLAGS": include_dirs,
|
||||
}
|
||||
return struct(
|
||||
libs = lib_dirs,
|
||||
flags = include_dirs,
|
||||
)
|
||||
|
||||
# See https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
|
||||
_CONFIGURE_FLAGS = {
|
||||
|
|
|
@ -449,10 +449,13 @@ def _symlink_contents_to_dir(dir_name, files_list):
|
|||
|
||||
paths_list = []
|
||||
for file in files_list:
|
||||
paths_list += [_file_path(file)]
|
||||
paths_list += [_file_path(file).strip()]
|
||||
|
||||
for path in paths_list:
|
||||
lines += ["##symlink_contents_to_dir## $$EXT_BUILD_ROOT$$/{} $$EXT_BUILD_DEPS$$/{}".format(path, dir_name)]
|
||||
# Filter out empty subpaths
|
||||
# (current directory may be passed as quote_includes, but we should not symlink it)
|
||||
if path and path != ".":
|
||||
lines += ["##symlink_contents_to_dir## $$EXT_BUILD_ROOT$$/{} $$EXT_BUILD_DEPS$$/{}".format(path, dir_name)]
|
||||
|
||||
return lines
|
||||
|
||||
|
@ -599,7 +602,11 @@ def get_foreign_cc_dep(dep):
|
|||
|
||||
# consider optimization here to do not iterate both collections
|
||||
def _get_headers(compilation_info):
|
||||
include_dirs = collections.uniq(compilation_info.system_includes.to_list())
|
||||
# NB: current directory (".") is passed by quote_includes;
|
||||
# ignore it by now, will be filtered by symlinking code.
|
||||
include_dirs = collections.uniq(compilation_info.system_includes.to_list() +
|
||||
compilation_info.includes.to_list() +
|
||||
compilation_info.quote_includes.to_list())
|
||||
headers = []
|
||||
for header in compilation_info.headers:
|
||||
path = header.path
|
||||
|
@ -635,17 +642,18 @@ def _define_out_cc_info(ctx, attrs, inputs, outputs):
|
|||
|
||||
return cc_common.merge_cc_infos(cc_infos = [cc_info, inputs_info])
|
||||
|
||||
def _extract_link_params(cc_linking):
|
||||
def _extract_libraries(library_to_link):
|
||||
return [
|
||||
cc_linking.static_mode_params_for_dynamic_library,
|
||||
cc_linking.static_mode_params_for_executable,
|
||||
cc_linking.dynamic_mode_params_for_dynamic_library,
|
||||
cc_linking.dynamic_mode_params_for_executable,
|
||||
library_to_link.static_library,
|
||||
library_to_link.pic_static_library,
|
||||
library_to_link.dynamic_library,
|
||||
library_to_link.interface_library,
|
||||
]
|
||||
|
||||
def _collect_libs(cc_linking):
|
||||
libs = []
|
||||
for params in _extract_link_params(cc_linking):
|
||||
libs += [lib.artifact() for lib in params.libraries_to_link]
|
||||
libs += params.dynamic_libraries_for_runtime.to_list()
|
||||
for library_to_link in cc_linking.libraries_to_link:
|
||||
for library in _extract_libraries(library_to_link):
|
||||
if library:
|
||||
libs.append(library)
|
||||
return collections.uniq(libs)
|
||||
|
|
|
@ -73,10 +73,12 @@ if [[ -f $1 ]]; then
|
|||
return 0
|
||||
fi
|
||||
|
||||
local children=$(find $1 -maxdepth 1 -mindepth 1)
|
||||
for child in $children; do
|
||||
##symlink_to_dir## $child $target
|
||||
done
|
||||
if [[ -d $1 || -L $1 ]]; then
|
||||
local children=$(find $1 -maxdepth 1 -mindepth 1)
|
||||
for child in $children; do
|
||||
##symlink_to_dir## $child $target
|
||||
done
|
||||
fi
|
||||
"""
|
||||
return FunctionAndCall(text = text)
|
||||
|
||||
|
|
|
@ -73,10 +73,12 @@ if [[ -f $1 ]]; then
|
|||
return 0
|
||||
fi
|
||||
|
||||
local children=$(find $1 -maxdepth 1 -mindepth 1)
|
||||
for child in $children; do
|
||||
##symlink_to_dir## $child $target
|
||||
done
|
||||
if [[ -d $1 || -L $1 ]]; then
|
||||
local children=$(find $1 -maxdepth 1 -mindepth 1)
|
||||
for child in $children; do
|
||||
##symlink_to_dir## $child $target
|
||||
done
|
||||
fi
|
||||
"""
|
||||
return FunctionAndCall(text = text)
|
||||
|
||||
|
|
|
@ -81,10 +81,12 @@ if [[ -f $1 ]]; then
|
|||
return 0
|
||||
fi
|
||||
|
||||
local children=$(find $1 -maxdepth 1 -mindepth 1)
|
||||
for child in $children; do
|
||||
##symlink_to_dir## $child $target
|
||||
done
|
||||
if [[ -d $1 || -L $1 ]]; then
|
||||
local children=$(find $1 -maxdepth 1 -mindepth 1)
|
||||
for child in $children; do
|
||||
##symlink_to_dir## $child $target
|
||||
done
|
||||
fi
|
||||
"""
|
||||
return FunctionAndCall(text = text)
|
||||
|
||||
|
|
|
@ -71,10 +71,12 @@ if [[ -f $1 ]]; then
|
|||
return 0
|
||||
fi
|
||||
|
||||
local children=$($REAL_FIND $1 -maxdepth 1 -mindepth 1)
|
||||
for child in $children; do
|
||||
##symlink_to_dir## $child $target
|
||||
done
|
||||
if [[ -d $1 || -L $1 ]]; then
|
||||
local children=$(find $1 -maxdepth 1 -mindepth 1)
|
||||
for child in $children; do
|
||||
##symlink_to_dir## $child $target
|
||||
done
|
||||
fi
|
||||
"""
|
||||
return FunctionAndCall(text = text)
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
VERSION = "0.0.7" # output refactoring
|
||||
VERSION = "0.0.8" # supports transitive dependencies bazel -> cmake -> bazel
|
||||
|
|
Loading…
Reference in New Issue