Third party libraries plugin in linux

Hello,
I’m trying to include some libraries as a (project) plugin under linux and I am facing many issues. This is the first one (this post is already way too long and I want to keep it as clean as possible)

First things first, I made my own simple libfoo, compiled as static library libfoo.a with its own header foo.h.

My directory structure is the following:

|Project

-\Plugins

-\Plugins\myplugin

-\Plugins\myplugin\ThirdParty

-\Plugins\myplugin\ThirdParty\libfoo

-\Plugins\myplugin\ThirdParty\libfoo\Include\foo.h

-\Plugins\myplugin\ThirdParty\libfoo\Lib\libfoo.a

-\Plugins\myplugin\Source

-\Plugins\myplugin\Source\myplugin.Build.cs

-\Plugins\myplugin\Source\Public\myplugin.h

-\Plugins\myplugin\Source\Private\myplugin.cpp

-\Plugins\myplugin\myplugin.uplugin

MyProject.Build.cs looks like

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class MyProject: ModuleRules {
 public MyProject(ReadOnlyTargetRules Target): base(Target) {
  PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;

  PublicDependencyModuleNames.AddRange(new string[] {
   "Core",
   "CoreUObject",
   "Engine",
   "InputCore",
   "HeadMountedDisplay",
   "myplugin"
  });
 }
}

myplugin.cpp and myplugin.h are left untouched,

while myplugin.Build.cs looks like

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
using System.IO;
using System;
public class myplugin: ModuleRules {
 private string LibraryPath {
  get {
   return Path.GetFullPath(Path.Combine(ThirdPartyPath, "libfoo", "Lib"));
  }
 }
 private string ModulePath {
  get {
   return ModuleDirectory;
  }
 }
 private string ThirdPartyPath {
  get {
   return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/"));
  }
 }
 public myplugin(ReadOnlyTargetRules Target): base(Target) {
  PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
  PublicIncludePaths.AddRange(
   new string[] {
    "myplugin/Public",
    Path.Combine(ThirdPartyPath, "libfoo", "Include"),
   }
  );

  PrivateIncludePaths.AddRange(
   new string[] {
    "myplugin/Private",
    Path.Combine(ThirdPartyPath, "libfoo", "Include"),
   }
  );

  PublicDependencyModuleNames.AddRange(
   new string[] {
    "Core",
   }
  );

  PrivateDependencyModuleNames.AddRange(
   new string[] {
    "CoreUObject",
    "Engine",
   }
  );

  PublicAdditionalLibraries.Add(Path.Combine(LibraryPath, "libfoo.a"));
 }
}

So far, so good.
I can include and “use” the foo library functionalities in my project.

At this point, I tried to include a real library, the one that I really need (liblcm).

I’ve compiled the library as static, copied the .a and the headers in the same folder structure showed before. At the end, I have the following structure

|Project

-\Plugins

-\Plugins\myplugin

-\Plugins\myplugin\ThirdParty

-\Plugins\myplugin\ThirdParty\libfoo

-\Plugins\myplugin\ThirdParty\libfoo\Include\foo.h

-\Plugins\myplugin\ThirdParty\libfoo\Lib\libfoo.a

-\Plugins\myplugin\ThirdParty\liblcm

-\Plugins\myplugin\ThirdParty\liblcm\Include\lcm

-\Plugins\myplugin\ThirdParty\liblcm\Include\lcm\header…h

-\Plugins\myplugin\ThirdParty\liblcm\Include\lcm\header…h

-\Plugins\myplugin\ThirdParty\liblcm\Include\lcm\header…hpp

-\Plugins\myplugin\ThirdParty\liblcm\Include\lcm\header…hpp

-\Plugins\myplugin\ThirdParty\liblcm\Lib\liblcm.a

-\Plugins\myplugin\Source

-\Plugins\myplugin\Source\myplugin.Build.cs

-\Plugins\myplugin\Source\Public\myplugin.h

-\Plugins\myplugin\Source\Private\myplugin.cpp

-\Plugins\myplugin\myplugin.uplugin

And I’ve modified my myplugin.Build.cs accordingly (not the most elegant solution, but it seems at least correct to me):

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
using System.IO;
using System;
public class myplugin: ModuleRules {
 private string LibraryPath {
  get {
   return Path.GetFullPath(Path.Combine(ThirdPartyPath, "libfoo", "Lib"));
  }
 }

 private string LibraryPathLCM {
  get {
   return Path.GetFullPath(Path.Combine(ThirdPartyPath, "liblcm", "Lib"));
  }
 }

 private string ModulePath {
  get {
   return ModuleDirectory;
  }
 }
 private string ThirdPartyPath {
  get {
   return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/"));
  }
 }
 public lammerda(ReadOnlyTargetRules Target): base(Target) {
  PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
  PublicIncludePaths.AddRange(
   new string[] {
    "myplugin/Public",
    Path.Combine(ThirdPartyPath, "libfoo", "Include"),
    Path.Combine(ThirdPartyPathLCM, "liblcm", "Include"),
   }
  );

  PrivateIncludePaths.AddRange(
   new string[] {
    "myplugin/Private",
    Path.Combine(ThirdPartyPath, "libfoo", "Include"),
    Path.Combine(ThirdPartyPath, "liblcm", "Include"),
   }
  );

  PublicDependencyModuleNames.AddRange(
   new string[] {
    "Core",
   }
  );

  PrivateDependencyModuleNames.AddRange(
   new string[] {
    "CoreUObject",
    "Engine",
   }
  );

  PublicAdditionalLibraries.Add(Path.Combine(LibraryPath, "libfoo.a"));
  PublicAdditionalLibraries.Add(Path.Combine(LibraryPathLCM, "liblcm.a"));
 }
}

At this point, I can still include libfoo headers as

#include "foo.h"

but there is no way I can do the same with liblcm headers.

The only way I’ve found to be able to include my headers is by doing so

#include "../../ThirdParty/liblcm/Include/lcm/lcm-cpp.hpp"

Is that normal? Am I doing something wrong?

I also invoke GenerateProjectFiles.sh MyProject.uproject -game -engine which seems to generate the right CMakeLists.txt.

Although, MyProjectIncludes.pri for QtCreator or the .kdev4/Includes.txt for KDevelop are wrong while MyProjectCodeCompletionFolders.txt seems to be right, which is kinda annoying but it is not that fundamental right now.

Thanks, sorry for the verbosity.

apparently, works, or better, apparently the includes works. It’s mostly a matter of executing the operations in the right order.

(I have another issue now related to lcm library but it’s completely different topic)