def components_libs_order_test(self): info = CppInfo("dep1", "") info.components["liba"].libs = ["liba"] info.components["libb"].libs = ["libb"] dep_cpp_info = DepCppInfo(info) self.assertListEqual(["liba", "libb"], dep_cpp_info.libs) deps_cpp_info = DepsCppInfo() deps_cpp_info.add("dep1", dep_cpp_info) self.assertListEqual(["liba", "libb"], deps_cpp_info["dep1"].libs) self.assertListEqual(["liba", "libb"], list(deps_cpp_info.libs)) info = CppInfo("dep1", "") info.components["liba"].libs = ["liba"] info.components["libb"].libs = ["libb"] dep_cpp_info = DepCppInfo(info) info2 = CppInfo("dep2", "") info2.components["libc"].libs = ["libc"] dep_cpp_info2 = DepCppInfo(info2) deps_cpp_info = DepsCppInfo() # Update in reverse order deps_cpp_info.add("dep2", dep_cpp_info2) deps_cpp_info.add("dep1", dep_cpp_info) self.assertListEqual(["liba", "libb"], deps_cpp_info["dep1"].libs) self.assertListEqual(["libc"], deps_cpp_info["dep2"].libs) self.assertListEqual(["libc", "liba", "libb"], list(deps_cpp_info.libs)) info = CppInfo("dep1", "") info.components["liba"].libs = ["liba"] info.components["libb"].libs = ["libb"] info.components["libb"].requires = ["liba"] dep_cpp_info = DepCppInfo(info) self.assertListEqual(["libb", "liba"], dep_cpp_info.libs) deps_cpp_info = DepsCppInfo() deps_cpp_info.add("dep1", dep_cpp_info) self.assertListEqual(["libb", "liba"], deps_cpp_info["dep1"].libs) self.assertListEqual(["libb", "liba"], list(deps_cpp_info.libs)) info = CppInfo("dep1", "") info.components["liba"].libs = ["liba"] info.components["libb"].libs = ["libb"] info.components["libb"].requires = ["liba"] dep_cpp_info = DepCppInfo(info) info2 = CppInfo("dep2", "") info2.components["libc"].libs = ["libc"] dep_cpp_info2 = DepCppInfo(info2) deps_cpp_info = DepsCppInfo() # Update in reverse order deps_cpp_info.add("dep2", dep_cpp_info2) deps_cpp_info.add("dep1", dep_cpp_info) self.assertListEqual(["libb", "liba"], deps_cpp_info["dep1"].libs) self.assertListEqual(["libc"], deps_cpp_info["dep2"].libs) self.assertListEqual(["libc", "libb", "liba"], list(deps_cpp_info.libs))
def cpp_info_link_order_test(self): def _assert_link_order(sorted_libs): """ Assert that dependent libs of a component are always found later in the list """ assert sorted_libs, "'sorted_libs' is empty" for num, lib in enumerate(sorted_libs): component_name = lib[-1] for dep in info.components[component_name].requires: for comp_lib in info.components[dep].libs: self.assertIn(comp_lib, sorted_libs[num:]) info = CppInfo("dep1", "") info.components["6"].libs = ["lib6"] info.components["6"].requires = ["4", "5"] info.components["5"].libs = ["lib5"] info.components["5"].requires = ["2"] info.components["4"].libs = ["lib4"] info.components["4"].requires = ["1"] info.components["3"].libs = ["lib3"] info.components["3"].requires = ["1"] info.components["1"].libs = ["lib1"] info.components["1"].requires = ["2"] info.components["2"].libs = ["lib2"] info.components["2"].requires = [] dep_cpp_info = DepCppInfo(info) _assert_link_order(dep_cpp_info.libs) self.assertEqual(["lib6", "lib5", "lib4", "lib3", "lib1", "lib2"], dep_cpp_info.libs) deps_cpp_info = DepsCppInfo() deps_cpp_info.add("dep1", dep_cpp_info) self.assertEqual(["lib6", "lib5", "lib4", "lib3", "lib1", "lib2"], list(deps_cpp_info.libs)) info = CppInfo("dep2", "") info.components["K"].libs = ["libK"] info.components["K"].requires = ["G", "H"] info.components["J"].libs = ["libJ"] info.components["J"].requires = ["F"] info.components["G"].libs = ["libG"] info.components["G"].requires = ["F"] info.components["H"].libs = ["libH"] info.components["H"].requires = ["F", "E"] info.components["L"].libs = ["libL"] info.components["L"].requires = ["I"] info.components["F"].libs = ["libF"] info.components["F"].requires = ["C", "D"] info.components["I"].libs = ["libI"] info.components["I"].requires = ["E"] info.components["C"].libs = ["libC"] info.components["C"].requires = ["A"] info.components["D"].libs = ["libD"] info.components["D"].requires = ["A"] info.components["E"].libs = ["libE"] info.components["E"].requires = ["A", "B"] info.components["A"].libs = ["libA"] info.components["A"].requires = [] info.components["B"].libs = ["libB"] info.components["B"].requires = [] dep_cpp_info = DepCppInfo(info) _assert_link_order(dep_cpp_info.libs) self.assertEqual([ "libK", "libJ", "libG", "libH", "libL", "libF", "libI", "libC", "libD", "libE", "libA", "libB" ], dep_cpp_info.libs) deps_cpp_info.add("dep2", dep_cpp_info) self.assertEqual([ "lib6", "lib5", "lib4", "lib3", "lib1", "lib2", "libK", "libJ", "libG", "libH", "libL", "libF", "libI", "libC", "libD", "libE", "libA", "libB" ], list(deps_cpp_info.libs))
def test_configs(self): deps_cpp_info = DepsCppInfo() deps_cpp_info.filter_empty = False child = CppInfo("Boost", "F:/") child.filter_empty = False child.version = "<version>" child.includedirs.append("ChildrenPath") child.debug.includedirs.append("ChildrenDebugPath") child.cxxflags.append("cxxmyflag") child.debug.cxxflags.append("cxxmydebugflag") child.libs.extend(["math"]) child.debug.libs.extend(["debug_Lib"]) deps_cpp_info.add("Boost", DepCppInfo(child)) deps_env_info = DepsEnvInfo() env_info_lib1 = EnvInfo() env_info_lib1.var = "32" env_info_lib1.othervar.append("somevalue") deps_env_info.update(env_info_lib1, "LIB1") deps_user_info = DepsUserInfo() deps_user_info["LIB2"].myuservar = "23" fakeconan = namedtuple( "Conanfile", "deps_cpp_info cpp_info deps_env_info env_info user_info deps_user_info" ) output = TXTGenerator( fakeconan(deps_cpp_info, None, deps_env_info, deps_user_info, {}, defaultdict(dict))).content deps_cpp_info2, _, deps_env_info2, _ = TXTGenerator.loads( output, filter_empty=False) self.assertEqual(deps_cpp_info.includedirs, deps_cpp_info2.includedirs) self.assertEqual(deps_cpp_info.libdirs, deps_cpp_info2.libdirs) self.assertEqual(deps_cpp_info.bindirs, deps_cpp_info2.bindirs) self.assertEqual(deps_cpp_info.libs, deps_cpp_info2.libs) self.assertEqual(len(deps_cpp_info._dependencies), len(deps_cpp_info2._dependencies)) self.assertEqual(deps_cpp_info["Boost"].includedirs, deps_cpp_info2["Boost"].includedirs) self.assertEqual(deps_cpp_info["Boost"].cxxflags, deps_cpp_info2["Boost"].cxxflags) self.assertEqual(deps_cpp_info["Boost"].cxxflags, ["cxxmyflag"]) self.assertEqual(deps_cpp_info.debug.includedirs, deps_cpp_info2.debug.includedirs) self.assertEqual(deps_cpp_info.debug.includedirs, ['F:/include', 'F:/ChildrenDebugPath']) self.assertEqual(deps_cpp_info.debug.libs, deps_cpp_info2.debug.libs) self.assertEqual(deps_cpp_info.debug.libs, ["debug_Lib"]) self.assertEqual(deps_cpp_info["Boost"].debug.includedirs, deps_cpp_info2["Boost"].debug.includedirs) self.assertEqual(deps_cpp_info["Boost"].debug.includedirs, ['include', 'ChildrenDebugPath']) self.assertEqual(deps_cpp_info["Boost"].debug.cxxflags, deps_cpp_info2["Boost"].debug.cxxflags) self.assertEqual(deps_cpp_info["Boost"].debug.cxxflags, ["cxxmydebugflag"]) self.assertEqual(deps_env_info["LIB1"].var, "32") self.assertEqual(deps_env_info["LIB1"].othervar, ["somevalue"]) self.assertEqual(deps_user_info["LIB2"].myuservar, "23")
def test_deps_cpp_info_libs_defines_flags(self): deps_cpp_info = DepsCppInfo() dep1 = CppInfo("dep1", "root") dep1.components["liba"].libs.append("liba") dep1.components["liba"].defines.append("DEFINEA") dep1.components["liba"].system_libs.append("sysa") dep1.components["liba"].cxxflags.append("cxxflaga") dep1.components["liba"].cflags.append("cflaga") dep1.components["liba"].sharedlinkflags.append("slinka") dep1.components["liba"].frameworks.append("frameworka") dep1.components["liba"].exelinkflags.append("elinka") dep1.components["libb"].libs.append("libb") dep1.components["libb"].defines.append("DEFINEB") dep1.components["libb"].system_libs.append("sysb") dep1.components["libb"].cxxflags.append("cxxflagb") dep1.components["libb"].cflags.append("cflagb") dep1.components["libb"].sharedlinkflags.append("slinkb") dep1.components["libb"].frameworks.append("frameworkb") dep1.components["libb"].exelinkflags.append("elinkb") deps_cpp_info.add("dep1", DepCppInfo(dep1)) dep2 = CppInfo("dep2", "root") dep2.components["libc"].libs.append("libc") dep2.components["libd"].libs.append("libd") dep2.components["systemlib"].system_libs = ["systemlib"] dep2.components["libc"].cxxflags = ["cxxflagc"] dep2.components["libd"].cflags = ["cflagd"] dep2.components["libc"].sharedlinkflags = ["slinkc"] dep2.components["libd"].sharedlinkflags = ["slinkd"] deps_cpp_info.add("dep2", DepCppInfo(dep2)) self.assertListEqual(["liba", "libb"], deps_cpp_info["dep1"].libs) self.assertListEqual(["libc", "libd"], deps_cpp_info["dep2"].libs) self.assertListEqual(["liba", "libb", "libc", "libd"], list(deps_cpp_info.libs)) self.assertListEqual(["DEFINEA", "DEFINEB"], deps_cpp_info["dep1"].defines) self.assertListEqual(["DEFINEA", "DEFINEB"], list(deps_cpp_info.defines)) self.assertListEqual(["sysa", "sysb"], deps_cpp_info["dep1"].system_libs) self.assertListEqual(["systemlib"], deps_cpp_info["dep2"].system_libs) self.assertListEqual(["sysa", "sysb", "systemlib"], list(deps_cpp_info.system_libs)) self.assertListEqual(["cxxflaga", "cxxflagb"], deps_cpp_info["dep1"].cxxflags) self.assertListEqual(["cxxflagc"], deps_cpp_info["dep2"].cxxflags) self.assertListEqual(["cxxflagc", "cxxflaga", "cxxflagb"], list(deps_cpp_info.cxxflags)) self.assertListEqual(["cflaga", "cflagb"], deps_cpp_info["dep1"].cflags) self.assertListEqual(["cflagd"], deps_cpp_info["dep2"].cflags) self.assertListEqual(["cflagd", "cflaga", "cflagb"], list(deps_cpp_info.cflags)) self.assertListEqual(["slinka", "slinkb"], deps_cpp_info["dep1"].sharedlinkflags) self.assertListEqual(["slinkc", "slinkd"], deps_cpp_info["dep2"].sharedlinkflags) self.assertListEqual(["slinkc", "slinkd", "slinka", "slinkb"], list(deps_cpp_info.sharedlinkflags)) self.assertListEqual(["frameworka", "frameworkb"], deps_cpp_info["dep1"].frameworks) self.assertListEqual(["frameworka", "frameworkb"], list(deps_cpp_info.frameworks)) self.assertListEqual(["elinka", "elinkb"], deps_cpp_info["dep1"].exelinkflags) self.assertListEqual([], deps_cpp_info["dep2"].exelinkflags) self.assertListEqual(["elinka", "elinkb"], list(deps_cpp_info.exelinkflags))
def _loads_cpp_info(text, filter_empty): pattern = re.compile(r"^\[([a-zA-Z0-9._:-]+)\]([^\[]+)", re.MULTILINE) try: # Parse the text data = OrderedDict() for m in pattern.finditer(text): var_name = m.group(1) lines = [] for line in m.group(2).splitlines(): line = line.strip() if not line or line[0] == "#": continue lines.append(line) if not lines: continue tokens = var_name.split(":") if len(tokens) == 2: # has config var_name, config = tokens else: config = None if 'system_libs' in var_name: tokens = var_name.split("system_libs_", 1) field = 'system_libs' else: tokens = var_name.split("_", 1) field = tokens[0] dep = tokens[1] if len(tokens) == 2 else None if field == "cppflags": field = "cxxflags" data.setdefault(dep, defaultdict(dict)) data[dep][config][field] = lines # Build the data structures def _populate_cpp_info(_cpp_info, _data, _rootpath): for key, value in _data.items(): if key.endswith('dirs'): value = [ os.path.relpath(it, _rootpath) for it in value ] value = ['' if it == '.' else it for it in value] setattr(_cpp_info, key, value) if None in data: del data[None] deps_cpp_info = DepsCppInfo() for dep, configs_cpp_info in data.items(): # Data for the 'cpp_info' object (no configs) no_config_data = configs_cpp_info.pop(None) rootpath = no_config_data.pop('rootpath')[0] dep_cpp_info = CppInfo(dep, rootpath) dep_cpp_info.filter_empty = filter_empty dep_cpp_info.names[TXTGenerator.name] = no_config_data.pop( 'name')[0] dep_cpp_info.sysroot = no_config_data.pop('sysroot', [""])[0] _populate_cpp_info(dep_cpp_info, no_config_data, rootpath) # Now the configs for config, config_data in configs_cpp_info.items(): cpp_info_config = getattr(dep_cpp_info, config) _populate_cpp_info(cpp_info_config, config_data, rootpath) # Add to the dependecy list version = no_config_data.pop('version', [""])[0] dep_cpp_info.version = version deps_cpp_info.add(dep, DepCppInfo(dep_cpp_info)) return deps_cpp_info except Exception as e: logger.error(traceback.format_exc()) raise ConanException( "There was an error parsing conanbuildinfo.txt: %s" % str(e))