1 #include <msp/core/algorithm.h>
2 #include <msp/io/print.h>
3 #include <msp/strings/utils.h>
4 #include "binarypackage.h"
6 #include "filetarget.h"
7 #include "staticlibrary.h"
12 BinaryPackage::BinaryPackage(Builder &b, const string &n):
15 use_pkgconfig = false;
18 BinaryPackage *BinaryPackage::from_flags(Builder &builder, const string &name, const Flags &flags, const Flags &static_flags)
20 BinaryPackage *pkg = new BinaryPackage(builder, name);
21 pkg->use_pkgconfig = true;
23 process_flags(flags, pkg->export_binfo);
25 Flags exclusive_static_flags;
26 for(const string &f: static_flags)
27 if(!any_equals(flags, f))
28 exclusive_static_flags.push_back(f);
29 process_flags(exclusive_static_flags, pkg->static_binfo);
34 void BinaryPackage::process_flags(const Flags &flags, BuildInfo &binfo)
36 for(const string &f: flags)
38 if(!f.compare(0, 2, "-I"))
39 binfo.incpath.push_back(f.substr(2));
40 else if(!f.compare(0, 2, "-D"))
42 string::size_type equals = f.find('=');
43 if(equals!=string::npos)
44 binfo.defines[f.substr(2, equals-2)] = f.substr(equals+1);
46 binfo.defines[f.substr(2)] = string();
48 else if(!f.compare(0, 2, "-L"))
49 binfo.libpath.push_back(f.substr(2));
50 else if(!f.compare(0, 2, "-l"))
51 binfo.libs.push_back(f.substr(2));
52 else if(f=="-pthread")
57 void BinaryPackage::do_prepare()
59 auto is_relative = [](const FS::Path &p){ return !p.is_absolute(); };
60 bool has_relative_paths = any_of(export_binfo.libpath.begin(), export_binfo.libpath.end(), is_relative) ||
61 any_of(export_binfo.incpath.begin(), export_binfo.incpath.end(), is_relative);
63 vector<FS::Path> bases;
65 /* If we have any relative paths that need resolving, or we have no paths at
66 all and are not using pkg-config, look for files in prefix */
67 if(has_relative_paths || (!use_pkgconfig && export_binfo.libpath.empty() && export_binfo.incpath.empty()))
68 bases.push_back(builder.get_prefix());
70 // Always look in system locations
71 bases.push_back(FS::Path());
74 for(const FS::Path &b: bases)
77 system = prefix.empty();
81 const Architecture &arch = builder.get_current_arch();
83 prefix /= arch.get_cross_prefix();
86 VirtualFileSystem::SearchPath libpath = export_binfo.libpath;
87 if(!system && libpath.empty())
88 libpath.push_back("lib");
89 for(FS::Path &p: libpath)
92 bool all_found = true;
93 for(const string &l: export_binfo.libs)
94 all_found &= (builder.get_vfs().find_library(l, libpath, export_binfo.libmode, system)!=0);
96 VirtualFileSystem::SearchPath incpath = export_binfo.incpath;
97 if(!system && incpath.empty())
98 incpath.push_back("include");
99 for(FS::Path &p: incpath)
102 for(const string &h: headers)
103 all_found &= (builder.get_vfs().find_header(h, 0, incpath, system)!=0);
108 builder.get_logger().log("configure", format("%s found in %s", name, ((system && use_pkgconfig) ? "system" : base_path.str())));
113 if(base_path.empty())
115 // TODO report which files were not found
116 builder.get_logger().log("problems", format("Cannot locate files for %s", name));
117 problems.push_back("Cannot locate files");
121 /* Add default entries to paths if they're empty and the package was found
122 in a non-system location */
123 if(!system && export_binfo.incpath.empty())
124 export_binfo.incpath.push_back(base_path/"include");
125 if(!system && export_binfo.libpath.empty())
126 export_binfo.libpath.push_back(base_path/"lib");
128 if(has_relative_paths)
130 for(FS::Path &p: export_binfo.incpath)
132 for(FS::Path &p: export_binfo.libpath)
136 if(!static_binfo.libs.empty())
138 VirtualFileSystem::SearchPath combined_libpath = static_binfo.libpath;
139 combined_libpath.insert(combined_libpath.end(), export_binfo.libpath.begin(), export_binfo.libpath.end());
141 for(const string &l: export_binfo.libs)
142 if(Target *lib = builder.get_vfs().find_library(l, export_binfo.libpath, BuildInfo::FORCE_STATIC, system))
143 if(StaticLibrary *stlib = dynamic_cast<StaticLibrary *>(lib))
145 for(const string &s: static_binfo.libs)
146 stlib->add_required_library(s);
147 for(const FS::Path &p: combined_libpath)
148 stlib->add_library_path(p);
154 BinaryPackage::Loader::Loader(BinaryPackage &p):
155 DataFile::DerivedObjectLoader<BinaryPackage, Package::Loader>(p)
157 add("build_info", &Loader::build_info);
158 add("header", &Loader::header);
161 void BinaryPackage::Loader::build_info()
163 load_sub(obj.export_binfo);
166 void BinaryPackage::Loader::header(const string &h)
168 obj.headers.push_back(h);