Repository: conan-io/conan
Pull request #15299 (2023-12-19 09:12:56)

[Bazel] Minor improvements
Changelog: Feature: Improved `get_libs` algorithm for BazelDeps.
Changelog: Feature: Changed shared lib name in conan-new templates.
Docs: omit



Patch:
diff --git a/conan/tools/google/bazeldeps.py b/conan/tools/google/bazeldeps.py
index 8d0cd37e1..233b4bb32 100644
--- a/conan/tools/google/bazeldeps.py
+++ b/conan/tools/google/bazeldeps.py
@@ -95,11 +95,13 @@ def _get_libs(dep, cpp_info=None) -> list:
         return default_value
 
     def _save_lib_path(lib_, lib_path_):
-        _, ext_ = os.path.splitext(lib_path_)
+        """Add each lib with its full library path"""
+        formatted_path = lib_path_.replace("\\", "/")
+        _, ext_ = os.path.splitext(formatted_path)
         if is_shared and ext_ == ".lib":  # Windows interface library
-            interface_lib_paths[lib_] = lib_path_
+            interface_lib_paths[lib_] = formatted_path
         else:
-            lib_paths[lib_] = lib_path_
+            lib_paths[lib_] = formatted_path
 
     cpp_info = cpp_info or dep.cpp_info
     is_shared = _is_shared()
@@ -119,23 +121,21 @@ def _get_libs(dep, cpp_info=None) -> list:
             # Users may not name their libraries in a conventional way. For example, directly
             # use the basename of the lib file as lib name.
             if f in libs:
-                lib = f
-                # libs.remove(f)
-                lib_path = full_path
-                _save_lib_path(lib, lib_path)
+                _save_lib_path(f, full_path)
                 continue
             name, ext = os.path.splitext(f)
             if name not in libs and name.startswith("lib"):
-                name = name[3:]
-            if name in libs:
-                # FIXME: Should it read a conf variable to know unexpected extensions?
-                if (is_shared and ext in (".so", ".dylib", ".lib", ".dll")) or \
-                   (not is_shared and ext in (".a", ".lib")):
-                    lib = name
-                    # libs.remove(name)
-                    lib_path = full_path
-                    _save_lib_path(lib, lib_path)
+                name = name[3:]  # libpkg -> pkg
+             # FIXME: Should it read a conf variable to know unexpected extensions?
+            if (is_shared and ext in (".so", ".dylib", ".lib", ".dll")) or \
+               (not is_shared and ext in (".a", ".lib")):
+                if name in libs:
+                    _save_lib_path(name, full_path)
                     continue
+                else:  # last chance: some cases the name could be pkg.if instead of pkg
+                    name = name.split(".", maxsplit=1)[0]
+                    if name in libs:
+                        _save_lib_path(name, full_path)
 
     libraries = []
     for lib, lib_path in lib_paths.items():
diff --git a/conans/assets/templates/new_v2_bazel.py b/conans/assets/templates/new_v2_bazel.py
index 8c6c6e4d7..dba49a8bb 100644
--- a/conans/assets/templates/new_v2_bazel.py
+++ b/conans/assets/templates/new_v2_bazel.py
@@ -55,7 +55,10 @@ class {package_name}Conan(ConanFile):
              os.path.join(self.package_folder, "include"), keep_path=False)
 
     def package_info(self):
-        self.cpp_info.libs = ["{name}"]
+        if self.options.shared and self.settings.os != "Linux":
+            self.cpp_info.libs = ["{name}_shared"]
+        else:
+            self.cpp_info.libs = ["{name}"]
 """
 
 
@@ -77,7 +80,7 @@ class {package_name}TestConan(ConanFile):
 
     def build(self):
         bazel = Bazel(self)
-        bazel.build()
+        bazel.build(target="//main:example")
 
     def layout(self):
         # DEPRECATED: Default generators folder will be "conan" in Conan 2.x
@@ -125,7 +128,7 @@ cc_library(
 
 cc_shared_library(
     name = "{name}_shared",
-    shared_lib_name = "lib{name}.{ext}",
+    shared_lib_name = "lib{name}_shared.{ext}",
     deps = [":{name}"],
 )
 """


Test patch:
diff --git a/conans/test/functional/toolchains/google/test_bazel.py b/conans/test/functional/toolchains/google/test_bazel.py
index da78fb19a..b4ce17c3c 100644
--- a/conans/test/functional/toolchains/google/test_bazel.py
+++ b/conans/test/functional/toolchains/google/test_bazel.py
@@ -135,7 +135,7 @@ def test_transitive_libs_consuming(shared):
 
         cc_shared_library(
             name = "mysecondlib_shared",
-            shared_lib_name = "libmysecondlib.{}",
+            shared_lib_name = "libmysecondlib_shared.{}",
             deps = [":mysecondlib"],
         )
         """.format("dylib" if os_ == "Darwin" else "dll"))
diff --git a/conans/test/unittests/tools/google/test_bazel.py b/conans/test/unittests/tools/google/test_bazel.py
index fa9c88db8..64172d413 100644
--- a/conans/test/unittests/tools/google/test_bazel.py
+++ b/conans/test/unittests/tools/google/test_bazel.py
@@ -17,15 +17,17 @@ def cpp_info():
     bindirs = os.path.join(folder, "bin")
     libdirs = os.path.join(folder, "lib")
     save(ConanFileMock(), os.path.join(bindirs, "mylibwin.dll"), "")
+    save(ConanFileMock(), os.path.join(bindirs, "mylibwin2.dll"), "")
     save(ConanFileMock(), os.path.join(bindirs, "myliblin.so"), "")
     save(ConanFileMock(), os.path.join(bindirs, "mylibmac.dylib"), "")
     save(ConanFileMock(), os.path.join(libdirs, "myliblin.a"), "")
     save(ConanFileMock(), os.path.join(libdirs, "mylibmac.a"), "")
     save(ConanFileMock(), os.path.join(libdirs, "mylibwin.lib"), "")
+    save(ConanFileMock(), os.path.join(libdirs, "mylibwin2.if.lib"), "")
     save(ConanFileMock(), os.path.join(libdirs, "libmylib.so"), "")
     save(ConanFileMock(), os.path.join(libdirs, "subfolder", "libmylib.a"), "")  # recursive
     cpp_info_mock = MagicMock(_base_folder=None, libdirs=None, bindirs=None, libs=None)
-    cpp_info_mock._base_folder = folder
+    cpp_info_mock._base_folder = folder.replace("\\", "/")
     cpp_info_mock.libdirs = [libdirs]
     cpp_info_mock.bindirs = [bindirs]
     return cpp_info_mock
@@ -81,9 +83,13 @@ def test_bazeldeps_relativize_path(path, pattern, expected):
     (["mylibwin"], False, [('mylibwin', False, '{base_folder}/lib/mylibwin.lib', None)]),
     # Win + shared
     (["mylibwin"], True, [('mylibwin', True, '{base_folder}/bin/mylibwin.dll', '{base_folder}/lib/mylibwin.lib')]),
+    # Win + shared (interface with another ext)
+    (["mylibwin2"], True,
+     [('mylibwin2', True, '{base_folder}/bin/mylibwin2.dll', '{base_folder}/lib/mylibwin2.if.lib')]),
     # Win + Mac + shared
     (["mylibwin", "mylibmac"], True, [('mylibmac', True, '{base_folder}/bin/mylibmac.dylib', None),
-                                      ('mylibwin', True, '{base_folder}/bin/mylibwin.dll', '{base_folder}/lib/mylibwin.lib')]),
+                                      ('mylibwin', True, '{base_folder}/bin/mylibwin.dll',
+                                       '{base_folder}/lib/mylibwin.lib')]),
     # Linux + Mac + static
     (["myliblin", "mylibmac"], False, [('mylibmac', False, '{base_folder}/lib/mylibmac.a', None),
                                        ('myliblin', False, '{base_folder}/lib/myliblin.a', None)]),
@@ -105,4 +111,8 @@ def test_bazeldeps_get_libs(cpp_info, libs, is_shared, expected):
         if interface_lib_path:
             interface_lib_path = interface_lib_path.format(base_folder=cpp_info._base_folder)
         ret.append((lib, is_shared, lib_path, interface_lib_path))
-    assert _get_libs(ConanFileMock(options_values={"shared": is_shared}), cpp_info).sort() == ret.sort()
+    found_libs = _get_libs(ConanFileMock(options_values={"shared": is_shared}),
+                           cpp_info)
+    found_libs.sort()
+    ret.sort()
+    assert found_libs == ret