镜像自地址
https://github.com/JGZYES/ParlzPackageManger.git
已同步 2026-09-11 08:52:45 +08:00
feat(pdm): pdm-control LibraryPath + InstallDir
Two optional pdm-control fields: - LibraryPath: true/false — when true, pmm writes the package's lib dir to ~/.bashrc LD_LIBRARY_PATH so shared libs installed by PMM are found at runtime (per-package opt-in; default false so plain tools don't pollute the env). - InstallDir: <subdir> — install the package to ~/.pmm/root/<subdir> (its bin goes to <subdir>/bin and is added to PATH; <subdir>/lib is what LibraryPath points at). Also ensure the target dir exists before tar -C. Updated ppdm.md tutorial.
这个提交包含在:
@@ -540,6 +540,23 @@ int pdm_install_file(const char *pdmfile) {
|
||||
chdir_restore(); remove(tmpname); return -1;
|
||||
}
|
||||
|
||||
/* pdm-control knobs: LibraryPath (auto-add lib dir to LD_LIBRARY_PATH) and
|
||||
* InstallDir (optional install subdir under the PMM root). */
|
||||
pmm_libpath_wanted = 0;
|
||||
pmm_install_subdir[0] = 0;
|
||||
char *libp = control_get(ctl, "LibraryPath");
|
||||
if (libp && libp[0]) { pmm_libpath_wanted = (strcmp(libp, "true") == 0 || strcmp(libp, "1") == 0); free(libp); }
|
||||
char *inst = control_get(ctl, "InstallDir");
|
||||
if (inst && *inst) {
|
||||
/* keep it relative & safe (no .., no leading /) */
|
||||
size_t il = strlen(inst);
|
||||
if (il >= sizeof(pmm_install_subdir)) il = sizeof(pmm_install_subdir) - 1;
|
||||
memcpy(pmm_install_subdir, inst, il); pmm_install_subdir[il] = 0;
|
||||
for (char *q = pmm_install_subdir; *q; q++) if (*q == '\\') *q = '/';
|
||||
if (pmm_install_subdir[0] == '/' || strstr(pmm_install_subdir, "..")) pmm_install_subdir[0] = 0;
|
||||
free(inst);
|
||||
}
|
||||
|
||||
/* reject an install that would conflict with a package already present */
|
||||
char *confl = control_get(ctl, "Conflicts");
|
||||
if (confl && *confl && any_installed_conflict(confl)) {
|
||||
@@ -551,6 +568,12 @@ int pdm_install_file(const char *pdmfile) {
|
||||
|
||||
/* extract data into root (relative target: cwd is already the pm dir) */
|
||||
const char *tgt = flat ? "." : "root";
|
||||
char tgtbuf[1400];
|
||||
if (!flat && pmm_install_subdir[0]) {
|
||||
snprintf(tgtbuf, sizeof(tgtbuf), "root/%s", pmm_install_subdir);
|
||||
tgt = tgtbuf;
|
||||
}
|
||||
mkdir_p(tgt); /* ensure the target dir exists before -C */
|
||||
/* If the package is pmm itself, its exe is the currently running binary and
|
||||
* Windows/locked images can't be overwritten by tar. Move it aside first so
|
||||
* the new binary can be written; restore on failure. */
|
||||
@@ -622,6 +645,8 @@ int pdm_install_file(const char *pdmfile) {
|
||||
}
|
||||
|
||||
pmm_add_to_path(); /* auto-put PMM dirs (e.g. root/nodejs) on PATH */
|
||||
pmm_libpath_wanted = 0; /* don't leak the LibraryPath/InstallDir to later installs */
|
||||
pmm_install_subdir[0] = 0;
|
||||
|
||||
#ifndef _WIN32
|
||||
/* On Linux/macOS, mark anything in <root>/bin executable. Windows doesn't
|
||||
|
||||
@@ -113,6 +113,10 @@ static const char *home_dir(void) {
|
||||
static char g_drive[4] = ""; /* "D", or "" = use home */
|
||||
static char g_base_path[1024] = ""; /* exact install base, or "" */
|
||||
|
||||
/* Set by pdm_install_file from pdm-control (LibraryPath / InstallDir). */
|
||||
int pmm_libpath_wanted = 0;
|
||||
char pmm_install_subdir[256] = "";
|
||||
|
||||
static const char *drive_state_path(char *buf, size_t size) {
|
||||
snprintf(buf, size, "%s/.pmm/install-drive", home_dir());
|
||||
return buf;
|
||||
@@ -366,6 +370,17 @@ void pmm_add_to_path(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/* A package may declare an install subdir (pdm-control InstallDir): also put
|
||||
* its <subdir>/bin on PATH if it holds executables. */
|
||||
if (pmm_install_subdir[0]) {
|
||||
char subbin[1400];
|
||||
snprintf(subbin, sizeof(subbin), "%s/%s/bin", base, pmm_install_subdir);
|
||||
if (dir_has_exec(subbin)) add_path_candidate(list, &n, 160, subbin);
|
||||
char subcmd[1400];
|
||||
snprintf(subcmd, sizeof(subcmd), "%s/%s/cmd", base, pmm_install_subdir);
|
||||
if (dir_has_exec(subcmd)) add_path_candidate(list, &n, 160, subcmd);
|
||||
}
|
||||
|
||||
/* read current user PATH */
|
||||
char cur[16384] = "";
|
||||
#ifdef _WIN32
|
||||
@@ -435,14 +450,18 @@ void pmm_add_to_path(void) {
|
||||
if (f) {
|
||||
fprintf(f, "\n# PMM PATH\n");
|
||||
for (int i = 0; i < n; i++) if (list[i][0]) fprintf(f, "export PATH=\"%s:$PATH\"\n", list[i]);
|
||||
/* Shared libraries installed by PMM live under <home>/root/lib;
|
||||
* make them findable by dynamically-linked tools automatically. */
|
||||
fprintf(f, "\n# PMM shared library path\n");
|
||||
if (pmm_flat_mode())
|
||||
fprintf(f, "export LD_LIBRARY_PATH=\"%s/lib:%LD_LIBRARY_PATH\"\n", home);
|
||||
/* If the package opted in (pdm-control: LibraryPath=true), make its
|
||||
* lib dir findable by dynamically-linked tools automatically. */
|
||||
if (pmm_libpath_wanted) {
|
||||
char libdir[1400];
|
||||
if (pmm_install_subdir[0])
|
||||
snprintf(libdir, sizeof(libdir), "%s/%s/lib", base, pmm_install_subdir);
|
||||
else
|
||||
fprintf(f, "export LD_LIBRARY_PATH=\"%s/root/lib:%s/root/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH\"\n",
|
||||
home, home);
|
||||
snprintf(libdir, sizeof(libdir), "%s/lib", base);
|
||||
fprintf(f, "\n# PMM shared library path\n");
|
||||
fprintf(f, "export LD_LIBRARY_PATH=\"%s:%s/x86_64-linux-gnu:$LD_LIBRARY_PATH\"\n",
|
||||
libdir, libdir);
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
(void)she;
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
* On Windows persists via the user registry PATH; on Unix appends to shell rc. */
|
||||
void pmm_add_to_path(void);
|
||||
|
||||
/* Set by the .pdm installer from pdm-control (LibraryPath/InstallDir) before
|
||||
* calling pmm_add_to_path: whether to export the package's lib dir on
|
||||
* LD_LIBRARY_PATH, and an optional install subdir under the PMM root. */
|
||||
extern int pmm_libpath_wanted;
|
||||
extern char pmm_install_subdir[256];
|
||||
|
||||
/* Set the install location by drive letter ("D" -> D:\.pmm). An empty string
|
||||
* clears back to the user-home default. Persisted across runs. */
|
||||
void pmm_set_install_drive(const char *letter);
|
||||
|
||||
@@ -78,8 +78,14 @@ Version: 1.0.0
|
||||
Architecture: linux
|
||||
Description: My app
|
||||
Maintainer: you@mail.com
|
||||
# 可选:
|
||||
# LibraryPath: true # 装到 ~/.pmm/root 后,自动把本包 lib/ 加入 LD_LIBRARY_PATH(新 shell 生效)
|
||||
# InstallDir: tools/myapp # 把本包装到 ~/.pmm/root/tools/myapp (bin -> .../bin, lib -> .../lib)
|
||||
```
|
||||
|
||||
> `LibraryPath` 默认 `false`(不加);`true` 时 pmm 会在 `~/.bashrc` 写入本包 lib 目录的
|
||||
> `LD_LIBRARY_PATH`。`InstallDir` 可把包装到 `~/.pmm/root/<子目录>`,该目录下的 `bin` 也会进 PATH。
|
||||
|
||||
打包:
|
||||
|
||||
```bash
|
||||
|
||||
在新工单中引用
屏蔽一个用户