Use pkg tool for determining a build strategy

Signed-off-by: David Oberhollenzer <goliath@infraroot.at>
This commit is contained in:
David Oberhollenzer 2019-03-09 17:26:07 +01:00
parent 509d1fdd4d
commit 7496023d5f
2 changed files with 2 additions and 172 deletions

5
mk.sh
View File

@ -70,8 +70,6 @@ done
echo "--- resolving package dependencies ---"
g++ "$SCRIPTDIR/util/depgraph.cpp" -o "$TCDIR/bin/depgraph"
truncate -s 0 $DEPENDSLIST $PROVIDESLIST
for pkg in $SCRIPTDIR/pkg/*; do
@ -85,7 +83,8 @@ for pkg in $SCRIPTDIR/pkg/*; do
done
done
depgraph "$PROVIDESLIST" "$DEPENDSLIST" "$RELEASEPKG" > "$PACKAGELIST"
pkg buildstrategy -p "$PROVIDESLIST" -d "$DEPENDSLIST" "$RELEASEPKG" \
> "$PACKAGELIST"
cat "$PACKAGELIST"
echo "--- downloading package files ---"

View File

@ -1,169 +0,0 @@
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unordered_set>
#include <iostream>
#include <map>
struct meta_pkg_t {
meta_pkg_t(const char *pkgname) : name(pkgname), marked(false) {
}
void markPackage() {
if (!marked) {
marked = true;
for (auto &dep : depends)
dep->markPackage();
}
}
std::string name;
bool marked;
std::unordered_set<meta_pkg_t *> depends;
};
static std::map<std::string, meta_pkg_t *> package_by_name;
static std::map<std::string, meta_pkg_t *> package_provides;
static void handle_provides(const char *meta, const char *subpkg)
{
meta_pkg_t *pkg;
if (package_by_name.find(meta) == package_by_name.end())
package_by_name[meta] = new meta_pkg_t(meta);
package_provides[subpkg] = package_by_name[meta];
}
static void handle_depends(const char *meta, const char *dependency)
{
auto it = package_provides.find(dependency);
if (it == package_provides.end()) {
std::cerr << "nothing provides '" << dependency;
std::cerr << "', required by '" << meta << "'" << std::endl;
exit(EXIT_FAILURE);
}
package_by_name[meta]->depends.insert(it->second);
}
typedef void (*line_handler_t)(const char *lhs, const char *rhs);
static int foreach_line(const char *filename, line_handler_t cb)
{
FILE *f = fopen(filename, "r");
for (;;) {
char *line = NULL;
size_t n = 0;
ssize_t ret;
errno = 0;
ret = getline(&line, &n, f);
if (ret < 0) {
if (errno == 0) {
free(line);
break;
}
perror(filename);
free(line);
fclose(f);
return -1;
}
char *rhs = strchr(line, ',');
if (rhs == NULL) {
free(line);
continue;
}
*(rhs++) = '\0';
char *ptr = rhs;
while (*ptr != '\0' && !isspace(*ptr))
++ptr;
*ptr = '\0';
cb(line, rhs);
free(line);
}
fclose(f);
return 0;
}
int main(int argc, char **argv)
{
if (argc < 4) {
std::cerr << "usage: depgraph <providerlist> <dependencylist>";
std::cerr << " PACKAGES..." << std::endl;
return EXIT_FAILURE;
}
foreach_line(argv[1], handle_provides);
foreach_line(argv[2], handle_depends);
// recursively mark packages that we actually need to build
for (int i = 3; i < argc; ++i) {
auto it = package_provides.find(argv[i]);
if (it == package_provides.end()) {
std::cerr << "nothing provides '" << argv[i] << "'";
std::cerr << std::endl;
return EXIT_FAILURE;
}
it->second->markPackage();
}
// assemble a set of only those packages
std::unordered_set<meta_pkg_t *> pkglist;
for (auto &it : package_by_name) {
if (it.second->marked) {
pkglist.insert(it.second);
} else {
delete it.second;
}
}
package_provides.clear();
package_by_name.clear();
// output set in topological order
while (pkglist.size() > 0) {
meta_pkg_t *pkg = NULL;
for (auto &it : pkglist) {
if (it->depends.size() == 0) {
pkg = it;
break;
}
}
if (pkg == NULL) {
std::cerr << "dependency graph is cyclic!";
std::cerr << std::endl;
return EXIT_FAILURE;
}
for (auto &it : pkglist)
it->depends.erase(pkg);
pkglist.erase(pkg);
std::cout << pkg->name << std::endl;
delete pkg;
}
return EXIT_SUCCESS;
}