@@ -126,14 +126,22 @@ struct GitDependency {
126126 DepMetadata install () const ;
127127};
128128
129+ struct LocalDependency {
130+ std::string name;
131+ std::string path;
132+
133+ DepMetadata install () const ;
134+ };
135+
129136struct SystemDependency {
130137 std::string name;
131138 VersionReq versionReq;
132139
133140 DepMetadata install () const ;
134141};
135142
136- using Dependency = std::variant<GitDependency, SystemDependency>;
143+ using Dependency =
144+ std::variant<GitDependency, LocalDependency, SystemDependency>;
137145
138146void
139147Profile::merge (const Profile& other) {
@@ -536,6 +544,16 @@ parseGitDep(const std::string& name, const toml::table& info) {
536544 return { .name = name, .url = gitUrlStr, .target = target };
537545}
538546
547+ static LocalDependency
548+ parseLocalDep (const std::string& name, const toml::table& info) {
549+ validateDepName (name);
550+ const auto & path = info.at (" local" );
551+ if (!path.is_string ()) {
552+ throw PoacError (" local dependency must be a path string" );
553+ }
554+ return { .name = name, .path = path.as_string () };
555+ }
556+
539557static SystemDependency
540558parseSystemDep (const std::string& name, const toml::table& info) {
541559 validateDepName (name);
@@ -568,11 +586,15 @@ parseDependencies(const char* key) {
568586 } else if (info.contains (" system" ) && info.at (" system" ).as_boolean ()) {
569587 deps.emplace_back (parseSystemDep (dep.first , info));
570588 continue ;
589+ } else if (info.contains (" local" )) {
590+ deps.emplace_back (parseLocalDep (dep.first , info));
591+ continue ;
571592 }
572593 }
573594
574595 throw PoacError (
575- " Only Git dependency and system dependency are supported for now: " ,
596+ " Only Git dependency, local dependency, and system dependency are "
597+ " supported for now: " ,
576598 dep.first
577599 );
578600 }
@@ -619,6 +641,29 @@ GitDependency::install() const {
619641 return { .includes = includes, .libs = " " };
620642}
621643
644+ DepMetadata
645+ LocalDependency::install () const {
646+ const fs::path installDir = fs::weakly_canonical (path);
647+ if (fs::exists (installDir) && !fs::is_empty (installDir)) {
648+ logger::debug (" {} is already installed" , name);
649+ } else {
650+ throw PoacError (installDir.string () + " can't be accessible as directory" );
651+ }
652+
653+ const fs::path includeDir = installDir / " include" ;
654+ std::string includes = " -isystem" ;
655+
656+ if (fs::exists (includeDir) && fs::is_directory (includeDir)
657+ && !fs::is_empty (includeDir)) {
658+ includes += includeDir.string ();
659+ } else {
660+ includes += installDir.string ();
661+ }
662+
663+ // Currently, no libs are supported.
664+ return { .includes = includes, .libs = " " };
665+ }
666+
622667DepMetadata
623668SystemDependency::install () const {
624669 const std::string pkgConfigVer = versionReq.toPkgConfigString (name);
0 commit comments