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.