Switch build system from optional package to repositories
* Build libsolv and the dependency solver part of the package kit for
the build platform.
* Add build tool get_package_dependencies. Given a list of package files
and a list of repository files it determines the additional packages
that need to be retrieved from the repositories and prints their URLs.
* Add rules to work with external repositories in the build system
(build/jam/RepositoryRules):
- PackageRepository declares an external repository with all its
packages. The URL of the repository file isn't specified. It is
computed from a given base URL and the SHA256 hash of the list of
package files.
- GeneratedRepositoryPackageList generates a file containing the file
names of all packages in a repository.
- IsPackageAvailable returns whether a package is available in any
repository.
- PackageURL returns the URL for a package.
* Declare the HaikuPorts repository for x86_gcc2
(build/jam/repositories/HaikuPorts/x86_gcc2).
* Add rule AddHaikuImagePackages to add a package to the image and rule
IsHaikuImagePackageAdded to determine whether a package has been
added.
* OptionalPackages: Remove all entries that just downloaded and
installed an external package. AddHaikuImagePackages can be used
instead and is used in the remaining entries. Also move the remaining
optional package dependency declarations from
OptionalPackageDependencies here.
* ExtractBuildFeatureArchives: Instead of the URL parameter a package
name must be specified now. This allows to simplify BuildFeatures
significantly, since there's no dealing with URLs anymore. "if" out
the entries that aren't supported yet.
* build_haiku_image: For the packages installed in system and common
resolve their dependencies and download and install them as well.
This commit is contained in:
@@ -6,3 +6,4 @@ SubInclude HAIKU_TOP src build libicon ;
|
||||
SubInclude HAIKU_TOP src build libpackage ;
|
||||
SubInclude HAIKU_TOP src build libroot ;
|
||||
SubInclude HAIKU_TOP src build libshared ;
|
||||
SubInclude HAIKU_TOP src build libsolv ;
|
||||
|
||||
@@ -5,6 +5,7 @@ UsePrivateBuildHeaders kernel package shared ;
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package hpkg ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package hpkg v1 ] ;
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package solver ] ;
|
||||
|
||||
USES_BE_API on libpackage_build.so = true ;
|
||||
|
||||
@@ -115,6 +116,18 @@ BuildPlatformSharedLibrary libpackage_build.so
|
||||
NoErrorOutput.cpp
|
||||
StandardErrorOutput.cpp
|
||||
|
||||
# solver
|
||||
Solver.cpp
|
||||
SolverPackage.cpp
|
||||
SolverPackageSpecifier.cpp
|
||||
SolverPackageSpecifierList.cpp
|
||||
SolverProblem.cpp
|
||||
SolverProblemSolution.cpp
|
||||
SolverRepository.cpp
|
||||
SolverResult.cpp
|
||||
:
|
||||
libshared_build.a $(HOST_LIBBE) z $(HOST_LIBSTDC++)
|
||||
;
|
||||
|
||||
|
||||
HaikuSubInclude solver ;
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
SubDir HAIKU_TOP src build libpackage solver ;
|
||||
|
||||
UseBuildFeatureHeaders libsolv ;
|
||||
|
||||
local libsolvHeaders = [ BuildFeatureAttribute libsolv : headers : path ] ;
|
||||
UseHeaders [ FDirName $(libsolvHeaders) solv ] ;
|
||||
|
||||
UsePrivateHeaders shared ;
|
||||
|
||||
USES_BE_API on libpackage-add-on-libsolv_build.so = true ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src kits package solver ] ;
|
||||
|
||||
|
||||
MakeLocate libpackage-add-on-libsolv_build.so
|
||||
: $(HOST_BUILD_COMPATIBILITY_LIB_DIR) ;
|
||||
|
||||
BuildPlatformSharedLibrary libpackage-add-on-libsolv_build.so
|
||||
:
|
||||
LibsolvSolver.cpp
|
||||
:
|
||||
libsolvext_build.so libsolv_build.so
|
||||
libpackage_build.so
|
||||
libbe_build.so $(HOST_LIBSTDC++)
|
||||
;
|
||||
|
||||
|
||||
Includes [ FGristFiles LibsolvSolver.cpp ]
|
||||
: [ BuildFeatureAttribute libsolv : headers ] ;
|
||||
@@ -0,0 +1,107 @@
|
||||
SubDir HAIKU_TOP src build libsolv ;
|
||||
|
||||
local libsolvSourceBaseDirectory
|
||||
= [ BuildFeatureAttribute libsolv : sources : path ] ;
|
||||
local libsolvSourceDirectory = [ FDirName $(libsolvSourceBaseDirectory) src ] ;
|
||||
local libsolvextSourceDirectory
|
||||
= [ FDirName $(libsolvSourceBaseDirectory) ext ] ;
|
||||
|
||||
UseHeaders $(libsolvSourceDirectory) ;
|
||||
|
||||
local libsolvSources = [ FGristFiles
|
||||
bitmap.c poolarch.c poolvendor.c poolid.c strpool.c dirpool.c
|
||||
solver.c solverdebug.c repo_solv.c repo_write.c evr.c pool.c
|
||||
queue.c repo.c repodata.c repopage.c util.c policy.c solvable.c
|
||||
transaction.c rules.c problems.c
|
||||
chksum.c md5.c sha1.c sha2.c solvversion.c selection.c
|
||||
] ;
|
||||
|
||||
local libsolvMajor = 0 ;
|
||||
local libsolvMinor = 3 ;
|
||||
local libsolvPatch = 0 ;
|
||||
local libsolvVersion = $(libsolvMajor).$(libsolvMinor).$(libsolvPatch) ;
|
||||
|
||||
DEFINES =
|
||||
LIBSOLV_INTERNAL
|
||||
HAIKU
|
||||
ENABLE_HAIKU
|
||||
VERSION=\\\"$(libsolvVersion)\\\"
|
||||
;
|
||||
|
||||
# One of the following must be defined:
|
||||
# * HAVE_FUNOPEN / HAVE_FOPENCOOKIE
|
||||
#
|
||||
# One of the following can be defined:
|
||||
# * HAVE_QSORT_R / HAVE___QSORT ?
|
||||
switch $(HOST_PLATFORM) {
|
||||
case linux :
|
||||
DEFINES += HAVE_STRCHRNUL HAVE_QSORT_R HAVE_FOPENCOOKIE ;
|
||||
case haiku_host :
|
||||
DEFINES += HAVE_FOPENCOOKIE ;
|
||||
}
|
||||
|
||||
SubDirCcFlags -Wno-sign-compare -Wno-missing-prototypes ;
|
||||
|
||||
|
||||
# libsolv
|
||||
|
||||
LOCATE on $(libsolvSources) = $(libsolvSourceDirectory) ;
|
||||
Depends $(libsolvSources) : [ BuildFeatureAttribute libsolv : sources ] ;
|
||||
|
||||
MakeLocate libsolv_build.so : $(HOST_BUILD_COMPATIBILITY_LIB_DIR) ;
|
||||
|
||||
BuildPlatformSharedLibrary libsolv_build.so
|
||||
:
|
||||
$(libsolvSources)
|
||||
;
|
||||
|
||||
UseHeaders $(libsolvSourceDirectory) ;
|
||||
|
||||
local libsolvextSources = [ FGristFiles
|
||||
solv_xfopen.c testcase.c
|
||||
repo_haiku.cpp
|
||||
] ;
|
||||
|
||||
|
||||
# libsolvext
|
||||
|
||||
LOCATE on $(libsolvextSources) = $(libsolvextSourceDirectory) ;
|
||||
Depends $(libsolvextSources) : [ BuildFeatureAttribute libsolv : sources ] ;
|
||||
|
||||
USES_BE_API on libsolvext_build.so = true ;
|
||||
|
||||
MakeLocate libsolvext_build.so : $(HOST_BUILD_COMPATIBILITY_LIB_DIR) ;
|
||||
|
||||
BuildPlatformSharedLibrary libsolvext_build.so
|
||||
:
|
||||
$(libsolvextSources)
|
||||
:
|
||||
libsolv_build.so
|
||||
libpackage_build.so
|
||||
;
|
||||
|
||||
|
||||
# generate solvversion.h
|
||||
|
||||
actions GenerateLibsolvVersionHeader
|
||||
{
|
||||
sed -e s,@VERSION@,$(LIBSOLV_VERSION),g \
|
||||
-e s,@LIBSOLV_MAJOR@,$(LIBSOLV_MAJOR),g \
|
||||
-e s,@LIBSOLV_MINOR@,$(LIBSOLV_MINOR),g \
|
||||
-e s,@LIBSOLV_PATCH@,$(LIBSOLV_PATCH),g \
|
||||
$(2) > $(1)
|
||||
}
|
||||
|
||||
local versionHeaderIn = solvversion.h.in ;
|
||||
SEARCH on $(versionHeaderIn) = $(libsolvSourceDirectory) ;
|
||||
|
||||
local versionHeader = [ FGristFiles solvversion.h ] ;
|
||||
MakeLocate $(versionHeader) : $(LOCATE_SOURCE) ;
|
||||
Depends $(versionHeader) : $(versionHeaderIn) ;
|
||||
LIBSOLV_VERSION on $(versionHeader) = $(libsolvVersion) ;
|
||||
LIBSOLV_MAJOR on $(versionHeader) = $(libsolvMajor) ;
|
||||
LIBSOLV_MINOR on $(versionHeader) = $(libsolvMinor) ;
|
||||
LIBSOLV_PATCH on $(versionHeader) = $(libsolvPatch) ;
|
||||
GenerateLibsolvVersionHeader $(versionHeader) : $(versionHeaderIn) ;
|
||||
|
||||
Includes $(libsolvSources) $(libsolvextSources) : $(versionHeader) ;
|
||||
@@ -38,6 +38,9 @@
|
||||
// abort()s. Obviously that isn't good behavior for a library.
|
||||
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
|
||||
|
||||
BSolver*
|
||||
BPackageKit::create_solver()
|
||||
{
|
||||
@@ -45,6 +48,19 @@ BPackageKit::create_solver()
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
extern "C" BSolver*
|
||||
__create_libsolv_solver()
|
||||
{
|
||||
return new(std::nothrow) LibsolvSolver;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
struct LibsolvSolver::SolvQueue : Queue {
|
||||
SolvQueue()
|
||||
{
|
||||
@@ -583,17 +599,21 @@ LibsolvSolver::_InitPool()
|
||||
// x86 gcc2.
|
||||
{
|
||||
const char* arch;
|
||||
#ifdef __HAIKU_ARCH_X86
|
||||
#if (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_2
|
||||
arch = "x86_gcc2";
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
#ifdef __HAIKU_ARCH_X86
|
||||
#if (B_HAIKU_ABI & B_HAIKU_ABI_MAJOR) == B_HAIKU_ABI_GCC_2
|
||||
arch = "x86_gcc2";
|
||||
#else
|
||||
arch = "x86";
|
||||
#endif
|
||||
#else
|
||||
arch = "x86";
|
||||
struct utsname info;
|
||||
if (uname(&info) != 0)
|
||||
return errno;
|
||||
arch = info.machine;
|
||||
#endif
|
||||
#else
|
||||
struct utsname info;
|
||||
if (uname(&info) != 0)
|
||||
return errno;
|
||||
arch = info.machine;
|
||||
arch = HAIKU_PACKAGING_ARCH;
|
||||
#endif
|
||||
|
||||
pool_setarchpolicy(fPool, arch);
|
||||
|
||||
@@ -9,14 +9,18 @@
|
||||
|
||||
#include <package/solver/Solver.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
# include <dlfcn.h>
|
||||
# include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
typedef BPackageKit::BSolver* CreateSolverFunction();
|
||||
|
||||
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
|
||||
|
||||
typedef BSolver* CreateSolverFunction();
|
||||
static CreateSolverFunction* sCreateSolver = NULL;
|
||||
|
||||
static pthread_once_t sLoadLibsolvSolverAddOnInitOnce = PTHREAD_ONCE_INIT;
|
||||
@@ -34,6 +38,19 @@ load_libsolv_solver_add_on()
|
||||
dlclose(imageHandle);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
static BPackageKit::BSolver* __create_libsolv_solver()
|
||||
__attribute__((weakref("__create_libsolv_solver")));
|
||||
static CreateSolverFunction* sCreateSolver = &__create_libsolv_solver;
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
namespace BPackageKit {
|
||||
|
||||
|
||||
BSolver::BSolver()
|
||||
{
|
||||
@@ -48,7 +65,9 @@ BSolver::~BSolver()
|
||||
/*static*/ status_t
|
||||
BSolver::Create(BSolver*& _solver)
|
||||
{
|
||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||
pthread_once(&sLoadLibsolvSolverAddOnInitOnce, &load_libsolv_solver_add_on);
|
||||
#endif
|
||||
if (sCreateSolver == NULL)
|
||||
return B_NOT_SUPPORTED;
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ SubInclude HAIKU_TOP src tools fixup_amiga_boot_checksum ;
|
||||
SubInclude HAIKU_TOP src tools fixup_tos_boot_checksum ;
|
||||
SubInclude HAIKU_TOP src tools fs_shell ;
|
||||
SubInclude HAIKU_TOP src tools gensyscalls ;
|
||||
SubInclude HAIKU_TOP src tools get_package_dependencies ;
|
||||
SubInclude HAIKU_TOP src tools hack_coff ;
|
||||
SubInclude HAIKU_TOP src tools keymap ;
|
||||
SubInclude HAIKU_TOP src tools locale ;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
SubDir HAIKU_TOP src tools get_package_dependencies ;
|
||||
|
||||
UsePrivateBuildHeaders shared ;
|
||||
|
||||
SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src bin pkgman ] ;
|
||||
|
||||
USES_BE_API on <build>get_package_dependencies = true ;
|
||||
|
||||
BuildPlatformMain <build>get_package_dependencies :
|
||||
get_package_dependencies.cpp
|
||||
|
||||
# pkgman sources
|
||||
PackageInfoErrorListener.cpp
|
||||
RepositoryBuilder.cpp
|
||||
:
|
||||
libpackage-add-on-libsolv_build.so
|
||||
libsolvext_build.so libsolv_build.so
|
||||
libpackage_build.so $(HOST_LIBBE) $(HOST_LIBSTDC++)
|
||||
;
|
||||
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright 2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <[email protected]>
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <package/RepositoryCache.h>
|
||||
#include <package/solver/Solver.h>
|
||||
#include <package/solver/SolverPackageSpecifier.h>
|
||||
#include <package/solver/SolverPackageSpecifierList.h>
|
||||
#include <package/solver/SolverProblem.h>
|
||||
#include <package/solver/SolverProblemSolution.h>
|
||||
#include <package/solver/SolverRepository.h>
|
||||
#include <package/solver/SolverResult.h>
|
||||
|
||||
#include "pkgman.h"
|
||||
#include "RepositoryBuilder.h"
|
||||
|
||||
|
||||
static const char* sProgramName = "get_package_dependencies";
|
||||
|
||||
|
||||
void
|
||||
print_usage_and_exit(bool error)
|
||||
{
|
||||
fprintf(error ? stderr : stdout,
|
||||
"Usage: %s <repository> ... -- <package> ...\n"
|
||||
"Resolves the dependencies of the given packages using the given\n"
|
||||
"repositories and prints the URLs of the packages that are also\n"
|
||||
"needed to satisfy all requirements. Fails, if there are conflicts\n"
|
||||
"or some requirements cannot be satisfied.\n",
|
||||
sProgramName);
|
||||
exit(error ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, const char* const* argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
print_usage_and_exit(true);
|
||||
|
||||
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)
|
||||
print_usage_and_exit(false);
|
||||
|
||||
// get lists of repositories and packages
|
||||
int argIndex = 1;
|
||||
const char* const* repositories = argv + argIndex;
|
||||
while (argIndex < argc && strcmp(argv[argIndex], "--") != 0)
|
||||
argIndex++;
|
||||
int repositoryCount = argv + argIndex - repositories;
|
||||
|
||||
if (repositoryCount == 0 || argIndex == argc)
|
||||
print_usage_and_exit(true);
|
||||
|
||||
const char* const* packages = argv + argIndex + 1;
|
||||
int packageCount = argv + argc - packages;
|
||||
|
||||
// create the solver
|
||||
BSolver* solver;
|
||||
status_t error = BSolver::Create(solver);
|
||||
if (error != B_OK)
|
||||
DIE(error, "failed to create solver");
|
||||
|
||||
// add the "installed" repository with the given packages
|
||||
BSolverRepository installedRepository;
|
||||
{
|
||||
RepositoryBuilder installedRepositoryBuilder(installedRepository,
|
||||
"installed");
|
||||
for (int i = 0; i < packageCount; i++)
|
||||
installedRepositoryBuilder.AddPackage(packages[i]);
|
||||
installedRepositoryBuilder.AddToSolver(solver, true);
|
||||
}
|
||||
|
||||
// add external repositories
|
||||
std::map<BSolverRepository*, BRepositoryInfo> repositoryInfos;
|
||||
for (int i = 0; i < repositoryCount; i++) {
|
||||
BSolverRepository* repository = new BSolverRepository;
|
||||
BRepositoryCache cache;
|
||||
error = cache.SetTo(repositories[i]);
|
||||
if (error != B_OK)
|
||||
DIE(error, "failed to read repository file '%s'", repositories[i]);
|
||||
RepositoryBuilder(*repository, cache)
|
||||
.AddToSolver(solver, false);
|
||||
repositoryInfos[repository] = cache.Info();
|
||||
}
|
||||
|
||||
// solve
|
||||
error = solver->VerifyInstallation();
|
||||
if (error != B_OK)
|
||||
DIE(error, "failed to compute packages to install");
|
||||
|
||||
// print problems (and fail), if any
|
||||
if (solver->HasProblems()) {
|
||||
fprintf(stderr, "Encountered problems:\n");
|
||||
|
||||
int32 problemCount = solver->CountProblems();
|
||||
for (int32 i = 0; i < problemCount; i++) {
|
||||
// print problem and possible solutions
|
||||
BSolverProblem* problem = solver->ProblemAt(i);
|
||||
fprintf(stderr, "problem %" B_PRId32 ": %s\n", i + 1,
|
||||
problem->ToString().String());
|
||||
|
||||
int32 solutionCount = problem->CountSolutions();
|
||||
for (int32 k = 0; k < solutionCount; k++) {
|
||||
const BSolverProblemSolution* solution = problem->SolutionAt(k);
|
||||
fprintf(stderr, " solution %" B_PRId32 ":\n", k + 1);
|
||||
int32 elementCount = solution->CountElements();
|
||||
for (int32 l = 0; l < elementCount; l++) {
|
||||
const BSolverProblemSolutionElement* element
|
||||
= solution->ElementAt(l);
|
||||
fprintf(stderr, " - %s\n", element->ToString().String());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// print URL of packages that additionally need to be installed
|
||||
BSolverResult result;
|
||||
error = solver->GetResult(result);
|
||||
if (error != B_OK)
|
||||
DIE(error, "failed to compute packages to install");
|
||||
|
||||
bool duplicatePackage = false;
|
||||
for (int32 i = 0; const BSolverResultElement* element = result.ElementAt(i);
|
||||
i++) {
|
||||
BSolverPackage* package = element->Package();
|
||||
|
||||
switch (element->Type()) {
|
||||
case BSolverResultElement::B_TYPE_INSTALL:
|
||||
if (package->Repository() != &installedRepository) {
|
||||
const BRepositoryInfo& info
|
||||
= repositoryInfos[package->Repository()];
|
||||
BString url = info.OriginalBaseURL();
|
||||
url << '/' << package->Info().CanonicalFileName();
|
||||
printf("%s\n", url.String());
|
||||
}
|
||||
break;
|
||||
|
||||
case BSolverResultElement::B_TYPE_UNINSTALL:
|
||||
fprintf(stderr, "Error: would need to uninstall package %s\n",
|
||||
package->VersionedName().String());
|
||||
duplicatePackage = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return duplicatePackage ? 1 : 0;
|
||||
}
|
||||
Reference in New Issue
Block a user