Repository: conan-io/conan

Issue:
[bug] cpp_info.exelinkflags and cpp_info.sharedlinkflags are both included regardless of target type for CMake
I'm trying to add a transitive linker flag to my conan package, but wanted to restrict this only to executables. I stumbled upon the [cpp_info.exelinkflags attribute](https://docs.conan.io/en/latest/reference/conanfile/attributes.html#cpp-info) and reading the documentation I was under the assumption that it did exactly that.

In my conanfile.py:
```
def package_info():
    self.cpp_info.exelinkflags.extend(['-Wl,--unresolved-symbols=ignore-in-shared-libs'])
    # ...
```
But inspecting the generated `conanbuildinfo.cmake` for a consumer using the CMake generator, i noticed that this was the result:

```
# Property INTERFACE_LINK_FLAGS do not work, necessary to add to INTERFACE_LINK_LIBRARIES
set_property(TARGET CONAN_PKG::embedded-shared PROPERTY INTERFACE_LINK_LIBRARIES
${CONAN_PACKAGE_TARGETS_EMBEDDED-SHARED}
${_CONAN_PKG_LIBS_EMBEDDED-SHARED_DEPENDENCIES}
${CONAN_SHARED_LINKER_FLAGS_EMBEDDED-SHARED_LIST}
${CONAN_EXE_LINKER_FLAGS_EMBEDDED-SHARED_LIST}
...
)  
```
Effectively, both exelinkflags and sharedlinkflags are included transitively, regardless of the target type.

As a test, by manually changing the conanbuildinfo.cmake section to:
```
set_property(TARGET CONAN_PKG::embedded-shared PROPERTY INTERFACE_LINK_LIBRARIES
${CONAN_PACKAGE_TARGETS_EMBEDDED-SHARED}
${_CONAN_PKG_LIBS_EMBEDDED-SHARED_DEPENDENCIES}
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:${CONAN_SHARED_LINKER_FLAGS_EMBEDDED-SHARED_LIST}>
$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:${CONAN_EXE_LINKER_FLAGS_EMBEDDED-SHARED_LIST}>
``` 
I got the behavior that I expected.

Am I misunderstanding the purpose of those flags? If not, would my solution be a viable one?

### Environment Details (include every applicable attribute)
  * Operating System+version: Ubuntu 18.04
  * Compiler+version: gcc 7.5
  * Conan version: 1.20
  * Python version: 3.6

### Steps to reproduce (Include if Applicable)
In the `package_info()` step of a conanfile.py, add the following line:
```
self.cpp_info.exelinkflags.extend(['-Wl,--unresolved-symbols=ignore-in-shared-libs'])
```
When consuming the package with a CMake generator, the flag '-Wl,--unresolved-symbols=ignore-in-shared-libs' will be added also to libraries.


Discussion:
Hi, @hardsetting 

Really nice catch and nice fix! 😃 Do you want to submit a PR? Probably this is something to add not only to the `cmake` generator, but also to the `cmake_find_package` one (and the `_multi` versions). Yes, source code around those classes is a bit.... well, we need to refactor it.

Thanks!


Resolving patch:
diff --git a/conans/client/generators/cmake_common.py b/conans/client/generators/cmake_common.py
--- a/conans/client/generators/cmake_common.py
+++ b/conans/client/generators/cmake_common.py
@@ -166,11 +166,25 @@ def cmake_global_vars(deps, build_type=""):
     add_library({name} INTERFACE IMPORTED)
 
     # Property INTERFACE_LINK_FLAGS do not work, necessary to add to INTERFACE_LINK_LIBRARIES
-    set_property(TARGET {name} PROPERTY INTERFACE_LINK_LIBRARIES ${{CONAN_PACKAGE_TARGETS_{uname}}} ${{_CONAN_PKG_LIBS_{uname}_DEPENDENCIES}} ${{CONAN_SHARED_LINKER_FLAGS_{uname}_LIST}} ${{CONAN_EXE_LINKER_FLAGS_{uname}_LIST}}
-                                                                 $<$<CONFIG:Release>:${{CONAN_PACKAGE_TARGETS_{uname}_RELEASE}} ${{_CONAN_PKG_LIBS_{uname}_DEPENDENCIES_RELEASE}} ${{CONAN_SHARED_LINKER_FLAGS_{uname}_RELEASE_LIST}} ${{CONAN_EXE_LINKER_FLAGS_{uname}_RELEASE_LIST}}>
-                                                                 $<$<CONFIG:RelWithDebInfo>:${{CONAN_PACKAGE_TARGETS_{uname}_RELWITHDEBINFO}} ${{_CONAN_PKG_LIBS_{uname}_DEPENDENCIES_RELWITHDEBINFO}} ${{CONAN_SHARED_LINKER_FLAGS_{uname}_RELWITHDEBINFO_LIST}} ${{CONAN_EXE_LINKER_FLAGS_{uname}_RELWITHDEBINFO_LIST}}>
-                                                                 $<$<CONFIG:MinSizeRel>:${{CONAN_PACKAGE_TARGETS_{uname}_MINSIZEREL}} ${{_CONAN_PKG_LIBS_{uname}_DEPENDENCIES_MINSIZEREL}} ${{CONAN_SHARED_LINKER_FLAGS_{uname}_MINSIZEREL_LIST}} ${{CONAN_EXE_LINKER_FLAGS_{uname}_MINSIZEREL_LIST}}>
-                                                                 $<$<CONFIG:Debug>:${{CONAN_PACKAGE_TARGETS_{uname}_DEBUG}} ${{_CONAN_PKG_LIBS_{uname}_DEPENDENCIES_DEBUG}} ${{CONAN_SHARED_LINKER_FLAGS_{uname}_DEBUG_LIST}} ${{CONAN_EXE_LINKER_FLAGS_{uname}_DEBUG_LIST}}>)
+    set_property(TARGET {name} PROPERTY INTERFACE_LINK_LIBRARIES ${{CONAN_PACKAGE_TARGETS_{uname}}} ${{_CONAN_PKG_LIBS_{uname}_DEPENDENCIES}}
+                                                                 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:${{CONAN_SHARED_LINKER_FLAGS_{uname}_LIST}}>
+                                                                 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:${{CONAN_EXE_LINKER_FLAGS_{uname}_LIST}}>
+
+                                                                 $<$<CONFIG:Release>:${{CONAN_PACKAGE_TARGETS_{uname}_RELEASE}} ${{_CONAN_PKG_LIBS_{uname}_DEPENDENCIES_RELEASE}}
+                                                                 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:${{CONAN_SHARED_LINKER_FLAGS_{uname}_RELEASE_LIST}}>
+                                                                 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:${{CONAN_EXE_LINKER_FLAGS_{uname}_RELEASE_LIST}}>>
+
+                                                                 $<$<CONFIG:RelWithDebInfo>:${{CONAN_PACKAGE_TARGETS_{uname}_RELWITHDEBINFO}} ${{_CONAN_PKG_LIBS_{uname}_DEPENDENCIES_RELWITHDEBINFO}}
+                                                                 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:${{CONAN_SHARED_LINKER_FLAGS_{uname}_RELWITHDEBINFO_LIST}}>
+                                                                 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:${{CONAN_EXE_LINKER_FLAGS_{uname}_RELWITHDEBINFO_LIST}}>>
+
+                                                                 $<$<CONFIG:MinSizeRel>:${{CONAN_PACKAGE_TARGETS_{uname}_MINSIZEREL}} ${{_CONAN_PKG_LIBS_{uname}_DEPENDENCIES_MINSIZEREL}}
+                                                                 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:${{CONAN_SHARED_LINKER_FLAGS_{uname}_MINSIZEREL_LIST}}>
+                                                                 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:${{CONAN_EXE_LINKER_FLAGS_{uname}_MINSIZEREL_LIST}}>>
+
+                                                                 $<$<CONFIG:Debug>:${{CONAN_PACKAGE_TARGETS_{uname}_DEBUG}} ${{_CONAN_PKG_LIBS_{uname}_DEPENDENCIES_DEBUG}}
+                                                                 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:${{CONAN_SHARED_LINKER_FLAGS_{uname}_DEBUG_LIST}}>
+                                                                 $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:${{CONAN_EXE_LINKER_FLAGS_{uname}_DEBUG_LIST}}>>)
     set_property(TARGET {name} PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${{CONAN_INCLUDE_DIRS_{uname}}}
                                                                       $<$<CONFIG:Release>:${{CONAN_INCLUDE_DIRS_{uname}_RELEASE}}>
                                                                       $<$<CONFIG:RelWithDebInfo>:${{CONAN_INCLUDE_DIRS_{uname}_RELWITHDEBINFO}}>
diff --git a/conans/client/generators/cmake_find_package_common.py b/conans/client/generators/cmake_find_package_common.py
--- a/conans/client/generators/cmake_find_package_common.py
+++ b/conans/client/generators/cmake_find_package_common.py
@@ -8,7 +8,10 @@
 set({name}_INCLUDES{build_type_suffix} {deps.include_paths})
 set({name}_RES_DIRS{build_type_suffix} {deps.res_paths})
 set({name}_DEFINITIONS{build_type_suffix} {deps.defines})
-set({name}_LINKER_FLAGS{build_type_suffix}_LIST "{deps.sharedlinkflags_list}" "{deps.exelinkflags_list}")
+set({name}_LINKER_FLAGS{build_type_suffix}_LIST
+        $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:{deps.sharedlinkflags_list}>
+        $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:{deps.exelinkflags_list}>
+)
 set({name}_COMPILE_DEFINITIONS{build_type_suffix} {deps.compile_definitions})
 set({name}_COMPILE_OPTIONS{build_type_suffix}_LIST "{deps.cxxflags_list}" "{deps.cflags_list}")
 set({name}_LIBRARIES_TARGETS{build_type_suffix} "") # Will be filled later, if CMake 3
@@ -124,7 +127,7 @@ class CMakeFindPackageCommonMacros:
                 endif()
                 unset(CONAN_FOUND_LIBRARY CACHE)
             endforeach()
-            
+
             if(NOT ${CMAKE_VERSION} VERSION_LESS "3.0")
                 # Add all dependencies to all targets
                 string(REPLACE " " ";" deps_list "${deps}")
@@ -132,7 +135,7 @@ class CMakeFindPackageCommonMacros:
                     set_property(TARGET ${_CONAN_ACTUAL_TARGET} PROPERTY INTERFACE_LINK_LIBRARIES "${_CONAN_FOUND_SYSTEM_LIBS};${deps_list}")
                 endforeach()
             endif()
-                
+
             set(${out_libraries} ${_out_libraries} PARENT_SCOPE)
             set(${out_libraries_target} ${_out_libraries_target} PARENT_SCOPE)
         endfunction()


Test patch:
diff --git a/conans/test/functional/generators/cmake_find_package_multi_test.py b/conans/test/functional/generators/cmake_find_package_multi_test.py
--- a/conans/test/functional/generators/cmake_find_package_multi_test.py
+++ b/conans/test/functional/generators/cmake_find_package_multi_test.py
@@ -206,9 +206,19 @@ def package_info(self):
             self.assertNotIn("-- Library %s not found in package, might be system one" %
                              library_name, client.out)
             if build_type == "Release":
-                target_libs = "$<$<CONFIG:Release>:lib1;sys1;>;$<$<CONFIG:RelWithDebInfo>:;>;$<$<CONFIG:MinSizeRel>:;>;$<$<CONFIG:Debug>:;>"
+                target_libs = "$<$<CONFIG:Release>:lib1;sys1;" \
+                              "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;" \
+                              "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>;" \
+                              "$<$<CONFIG:RelWithDebInfo>:;>;" \
+                              "$<$<CONFIG:MinSizeRel>:;>;" \
+                              "$<$<CONFIG:Debug>:;>"
             else:
-                target_libs = "$<$<CONFIG:Release>:;>;$<$<CONFIG:RelWithDebInfo>:;>;$<$<CONFIG:MinSizeRel>:;>;$<$<CONFIG:Debug>:lib1;sys1d;>"
+                target_libs = "$<$<CONFIG:Release>:;>;" \
+                              "$<$<CONFIG:RelWithDebInfo>:;>;" \
+                              "$<$<CONFIG:MinSizeRel>:;>;" \
+                              "$<$<CONFIG:Debug>:lib1;sys1d;" \
+                              "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;" \
+                              "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>"
             self.assertIn("Target libs: %s" % target_libs, client.out)
 
     def cpp_info_name_test(self):
@@ -255,12 +265,18 @@ def build(self):
         client.save({"conanfile.py": conanfile, "CMakeLists.txt": cmakelists})
         client.run("install .")
         client.run("build .")
-        self.assertIn("Target libs (hello2): $<$<CONFIG:Release>:CONAN_LIB::MYHELLO2_hello_RELEASE;MYHELLO::MYHELLO;>;"
+        self.assertIn("Target libs (hello2): "
+                      "$<$<CONFIG:Release>:CONAN_LIB::MYHELLO2_hello_RELEASE;MYHELLO::MYHELLO;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>;"
                       "$<$<CONFIG:RelWithDebInfo>:;>;"
                       "$<$<CONFIG:MinSizeRel>:;>;"
                       "$<$<CONFIG:Debug>:;>",
                       client.out)
-        self.assertIn("Target libs (hello): $<$<CONFIG:Release>:CONAN_LIB::MYHELLO_hello_RELEASE;>;"
+        self.assertIn("Target libs (hello): "
+                      "$<$<CONFIG:Release>:CONAN_LIB::MYHELLO_hello_RELEASE;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>;"
                       "$<$<CONFIG:RelWithDebInfo>:;>;"
                       "$<$<CONFIG:MinSizeRel>:;>;"
                       "$<$<CONFIG:Debug>:;>",
@@ -355,18 +371,18 @@ def build(self):
     def cpp_info_config_test(self):
         conanfile = textwrap.dedent("""
             from conans import ConanFile
-            
+
             class Requirement(ConanFile):
                 name = "requirement"
                 version = "version"
-            
+
                 settings = "os", "arch", "compiler", "build_type"
-            
+
                 def package_info(self):
                     self.cpp_info.libs = ["lib_both"]
                     self.cpp_info.debug.libs = ["lib_debug"]
                     self.cpp_info.release.libs = ["lib_release"]
-                    
+
                     self.cpp_info.cxxflags = ["-req_both"]
                     self.cpp_info.debug.cxxflags = ["-req_debug"]
                     self.cpp_info.release.cxxflags = ["-req_release"]
diff --git a/conans/test/functional/generators/cmake_find_package_test.py b/conans/test/functional/generators/cmake_find_package_test.py
--- a/conans/test/functional/generators/cmake_find_package_test.py
+++ b/conans/test/functional/generators/cmake_find_package_test.py
@@ -64,7 +64,9 @@ def build(self):
         self.assertIn("Library fake_lib not found in package, might be system one", client.out)
         self.assertIn("Libraries to Link: fake_lib", client.out)
         self.assertIn("Version: 0.1", client.out)
-        self.assertIn("Target libs: fake_lib;;shared_link_flag;", client.out)
+        self.assertIn("Target libs: fake_lib;;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:shared_link_flag>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>", client.out)
         self.assertIn("Compile options: a_cxx_flag;a_flag", client.out)
 
     def cmake_lock_target_redefinition_test(self):
@@ -116,7 +118,7 @@ class Consumer(ConanFile):
                 generators = "cmake_find_package"
                 exports_sources = "CMakeLists.txt"
                 settings = "os", "arch", "compiler"
-    
+
                 def build(self):
                     cmake = CMake(self)
                     cmake.configure()
@@ -470,9 +472,14 @@ def build(self):
         client.run("build .")
         self.assertIn('Found MYHELLO2: 1.0 (found version "1.0")', client.out)
         self.assertIn('Found MYHELLO: 1.0 (found version "1.0")', client.out)
-        self.assertIn("Target libs (hello2): CONAN_LIB::MYHELLO2_hello;MYHELLO::MYHELLO;;",
+        self.assertIn("Target libs (hello2): "
+                      "CONAN_LIB::MYHELLO2_hello;MYHELLO::MYHELLO;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>",
                       client.out)
-        self.assertIn("Target libs (hello): CONAN_LIB::MYHELLO_hello;;;",
+        self.assertIn("Target libs (hello): CONAN_LIB::MYHELLO_hello;;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>",
                       client.out)
 
     def cpp_info_config_test(self):
diff --git a/conans/test/functional/generators/cmake_test.py b/conans/test/functional/generators/cmake_test.py
--- a/conans/test/functional/generators/cmake_test.py
+++ b/conans/test/functional/generators/cmake_test.py
@@ -245,8 +245,21 @@ def build(self):
 
         self.assertNotIn("Library sys1 not found in package, might be system one", client.out)
         self.assertIn("CONAN_PKG::mylib libs: "
-                      "CONAN_LIB::mylib_lib1;CONAN_LIB::mylib_lib11;sys1;$<$<CONFIG:Release>:;>;"
-                      "$<$<CONFIG:RelWithDebInfo>:;>;$<$<CONFIG:MinSizeRel>:;>;$<$<CONFIG:Debug>:;>",
+                      "CONAN_LIB::mylib_lib1;CONAN_LIB::mylib_lib11;sys1;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>;"
+                      "$<$<CONFIG:Release>:;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>;"
+                      "$<$<CONFIG:RelWithDebInfo>:;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>;"
+                      "$<$<CONFIG:MinSizeRel>:;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>;"
+                      "$<$<CONFIG:Debug>:;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>",
                       client.out)
         self.assertIn("CONAN_LIB::mylib_lib1 libs: ;sys1;;", client.out)
         self.assertIn("CONAN_LIB::mylib_lib11 libs: ;sys1;;", client.out)
@@ -254,10 +267,20 @@ def build(self):
         self.assertNotIn("Library sys2 not found in package, might be system one", client.out)
         self.assertIn("CONAN_PKG::myotherlib libs: "
                       "CONAN_LIB::myotherlib_lib2;sys2;CONAN_PKG::mylib;"
-                      "$<$<CONFIG:Release>:;CONAN_PKG::mylib;>;"
-                      "$<$<CONFIG:RelWithDebInfo>:;CONAN_PKG::mylib;>;"
-                      "$<$<CONFIG:MinSizeRel>:;CONAN_PKG::mylib;>;"
-                      "$<$<CONFIG:Debug>:;CONAN_PKG::mylib;>",
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>;"
+                      "$<$<CONFIG:Release>:;CONAN_PKG::mylib;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>;"
+                      "$<$<CONFIG:RelWithDebInfo>:;CONAN_PKG::mylib;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>;"
+                      "$<$<CONFIG:MinSizeRel>:;CONAN_PKG::mylib;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>;"
+                      "$<$<CONFIG:Debug>:;CONAN_PKG::mylib;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:>;"
+                      "$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:>>",
                       client.out)
         self.assertIn("CONAN_LIB::myotherlib_lib2 libs: ;sys2;;CONAN_PKG::mylib", client.out)
 
diff --git a/conans/test/functional/generators/link_order_test.py b/conans/test/functional/generators/link_order_test.py
--- a/conans/test/functional/generators/link_order_test.py
+++ b/conans/test/functional/generators/link_order_test.py
@@ -17,28 +17,28 @@ class LinkOrderTest(unittest.TestCase):
 
     conanfile = Template(textwrap.dedent("""
         from conans import ConanFile
-        
+
         class Recipe(ConanFile):
             name = "{{ref.name}}"
             version = "{{ref.version}}"
-            
+
             {% if requires %}
             requires = {% for req in requires %}"{{ req }}"{% if not loop.last %}, {% endif %}{% endfor %}
             {% endif %}
-            
+
             def build(self):
                 with open("lib" + self.name + ".a", "w+") as f:
                     f.write("fake library content")
                 with open(self.name + ".lib", "w+") as f:
                     f.write("fake library content")
-                    
+
                 {% for it in libs_extra %}
                 with open("lib{{ it }}.a", "w+") as f:
                     f.write("fake library content")
                 with open("{{ it }}.lib", "w+") as f:
                     f.write("fake library content")
                 {% endfor %}
-            
+
             def package(self):
                 self.copy("*.a", dst="lib")
                 self.copy("*.lib", dst="lib")
@@ -59,18 +59,18 @@ def package_info(self):
 
     conanfile_headeronly= Template(textwrap.dedent("""
         from conans import ConanFile
-        
+
         class HeaderOnly(ConanFile):
             name = "{{ref.name}}"
             version = "{{ref.version}}"
-            
+
             {% if requires %}
             requires = {% for req in requires %}"{{ req }}"{% if not loop.last %}, {% endif %}{% endfor %}
             {% endif %}
-            
+
             def package_id(self):
                 self.info.header_only()
-        
+
             def package_info(self):
                 # It may declare system libraries
                 {% for it in libs_system %}
@@ -144,7 +144,8 @@ def setUpClass(cls):
 
     def _validate_link_order(self, libs):
         # Check that all the libraries are there:
-        self.assertEqual(len(libs), 19 if platform.system() == "Darwin" else 16 if platform.system() == "Linux" else 26)
+        self.assertEqual(len(libs), 19 if platform.system() == "Darwin" else 16 if platform.system() == "Linux" else 26,
+                         msg="Unexpected number of libs ({}): '{}'".format(len(libs), "', '".join(libs)))
         # - Regular libs
         ext = ".lib" if platform.system() == "Windows" else ".a"
         prefix = "" if platform.system() == "Windows" else "lib"