summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-artifact.cpp103
-rw-r--r--source/compiler-core/slang-artifact.h52
-rw-r--r--source/compiler-core/slang-dxc-compiler.cpp92
-rw-r--r--source/compiler-core/slang-gcc-compiler-util.cpp71
-rw-r--r--source/compiler-core/slang-visual-studio-compiler-util.cpp29
-rw-r--r--source/slang/slang-compiler.cpp6
-rw-r--r--source/slang/slang-options.cpp5
-rw-r--r--source/slang/slang.cpp6
8 files changed, 225 insertions, 139 deletions
diff --git a/source/compiler-core/slang-artifact.cpp b/source/compiler-core/slang-artifact.cpp
index 5d9f8692c..1f11c31df 100644
--- a/source/compiler-core/slang-artifact.cpp
+++ b/source/compiler-core/slang-artifact.cpp
@@ -364,11 +364,88 @@ ISlangUnknown* Artifact::findInterfaceInstance(const Guid& guid)
return nullptr;
}
-SlangResult Artifact::requireFilePath(Keep keep, String& outFilePath)
+/* static */String Artifact::getBaseNameFromPath(Desc& desc, const UnownedStringSlice& path)
+{
+ String name = Path::getFileName(path);
+
+ const bool isSharedLibraryPrefixPlatform = SLANG_LINUX_FAMILY || SLANG_APPLE_FAMILY;
+ if (isSharedLibraryPrefixPlatform)
+ {
+ // Strip lib prefix
+ if (desc.isCpuBinary() &&
+ (desc.kind == ArtifactKind::Library ||
+ desc.kind == ArtifactKind::SharedLibrary))
+ {
+ // If it starts with lib strip it
+ if (name.startsWith("lib"))
+ {
+ const String stripLib = name.getUnownedSlice().tail(3);
+ name = stripLib;
+ }
+ }
+ }
+
+ // Strip any extension
+ {
+ auto descExt = desc.getDefaultExtension();
+ // Strip the extension if it's a match
+ if (descExt.getLength() &&
+ Path::getPathExt(name) == descExt)
+ {
+ name = Path::getFileNameWithoutExt(name);
+ }
+ }
+
+ return name;
+}
+
+String Artifact::getBaseName()
+{
+ if (m_pathType != PathType::None)
+ {
+ return getBaseNameFromPath(m_desc, m_path.getUnownedSlice());
+ }
+ return m_name;
+}
+
+String Artifact::getParentPath()
+{
+ if (m_pathType != PathType::None && m_path.getLength())
+ {
+ return Path::getParentDirectory(m_path);
+ }
+ return String();
+}
+
+SlangResult Artifact::requireFileLike(Keep keep)
+{
+ // If there is no path set and no blob we still need a name.
+ // If the artifact is a library we can assume it's a system level library,
+ // or it can be found by appropriate search paths.
+ if (m_pathType == PathType::None &&
+ m_blob == nullptr &&
+ (m_desc.kind == ArtifactKind::Library ||
+ m_desc.kind == ArtifactKind::SharedLibrary))
+ {
+ if (m_name.getLength() > 0)
+ {
+ return SLANG_OK;
+ }
+
+ // TODO(JS): If we could serialize, we could turn some other representation into a file, and therefore
+ // a name, but currently that's not supported
+ return SLANG_E_NOT_FOUND;
+ }
+
+ // Will turn into a file if necessary
+ SLANG_RETURN_ON_FAIL(requireFile(keep));
+ return SLANG_OK;
+}
+
+SlangResult Artifact::requireFile(Keep keep)
{
if (m_pathType != PathType::None)
{
- outFilePath = m_path;
return SLANG_OK;
}
@@ -377,15 +454,28 @@ SlangResult Artifact::requireFilePath(Keep keep, String& outFilePath)
// Get the contents as a blob. If we can't do that, then we can't write anything...
SLANG_RETURN_ON_FAIL(loadBlob(getIntermediateKeep(keep), blob));
- const UnownedStringSlice ext = m_desc.getDefaultExtension();
+ // If we have a name, make the generated name based on that name
+ // Else just use 'slang-generated' the basis
+
+ UnownedStringSlice nameBase;
+ if (m_name.getLength() > 0)
+ {
+ nameBase = m_name.getUnownedSlice();
+ }
+ else
+ {
+ nameBase = UnownedStringSlice::fromLiteral("slang-generated");
+ }
// TODO(JS): NOTE! This isn't strictly correct, as the generated filename is not guarenteed to be unique
// if we change it with an extension (or prefix).
// This doesn't change the previous behavior though.
String path;
- SLANG_RETURN_ON_FAIL(File::generateTemporary(UnownedStringSlice::fromLiteral("slang-generated"), path));
+ SLANG_RETURN_ON_FAIL(File::generateTemporary(nameBase, path));
- if (m_desc.isCpuBinary() && m_desc.kind == ArtifactKind::SharedLibrary)
+ if (m_desc.isCpuBinary() &&
+ (m_desc.kind == ArtifactKind::SharedLibrary ||
+ m_desc.kind == ArtifactKind::Library))
{
const bool isSharedLibraryPrefixPlatform = SLANG_LINUX_FAMILY || SLANG_APPLE_FAMILY;
if (isSharedLibraryPrefixPlatform)
@@ -409,6 +499,9 @@ SlangResult Artifact::requireFilePath(Keep keep, String& outFilePath)
}
// If there is an extension append it
+
+ const UnownedStringSlice ext = m_desc.getDefaultExtension();
+
if (ext.getLength())
{
path.appendChar('.');
diff --git a/source/compiler-core/slang-artifact.h b/source/compiler-core/slang-artifact.h
index 232e9a8eb..651e0ad3b 100644
--- a/source/compiler-core/slang-artifact.h
+++ b/source/compiler-core/slang-artifact.h
@@ -157,7 +157,7 @@ public:
static This makeFromCompileTarget(SlangCompileTarget target);
/// Construct from the elements
- static This make(Kind inKind, Payload inPayload, Style inStyle = Style::Kernel, Flags flags = 0)
+ static This make(Kind inKind, Payload inPayload, Style inStyle = Style::Unknown, Flags flags = 0)
{
return This{ inKind, inPayload, inStyle, flags };
}
@@ -202,6 +202,7 @@ An abstraction is desirable here, because depending on the compiler the artifact
* A blob
* Multiple files
* Some other (perhaps multiple) in memory representations
+* A name
The artifact uses the Blob as the standard representation of in memory data.
@@ -223,14 +224,6 @@ A more long term goal would be to
* Make Artifact an interface (such that it can work long term over binary boundaries)
* Make Diagnostics into an interface (such it can be added to a Artifact result)
* Use Artifact and related types for downstream compiler
-
-TODO(JS): There is an issue here around libraries in that downstream compilers can use
-named libraries, but the name doesn't directly relate to a file. If it is a file it may
-not be easily possible to determine it's location. So there is a desire to indicate the
-`name` as opposed to the path.
-
-As a second related issue. Lets say we have a blob (and not a file).
-
*/
class Artifact : public RefObject
{
@@ -296,9 +289,30 @@ public:
/// Load as a blob
SlangResult loadBlob(Keep keep, ComPtr<ISlangBlob>& outBlob);
- /// Get as a file. May need to serialize and write as a temporary file.
- SlangResult requireFilePath(Keep keep, String& outPath);
-
+ /// Require artifact is available as a file.
+ /// NOTE! May need to serialize and write as a temporary file.
+ SlangResult requireFile(Keep keep);
+
+ /// Require artifact is available in file-like scenarion.
+ ///
+ /// This is similar to requireFile, but for some special cases doesn't actually require a
+ /// *explicit* path/file.
+ ///
+ /// For example when system libraries are specified - the library paths may be known to
+ /// a downstream compiler (or the path is passed in explicitly), in that case only the
+ /// artifact name needs to be correct.
+ SlangResult requireFileLike(Keep keep);
+
+ /// Get the base name of this artifact.
+ /// If there is a path set, will extract the name from that (stripping prefix, extension as necessary).
+ /// Else if there is an explicit name set, this is returned.
+ /// Else returns the empty string
+ String getBaseName();
+
+ /// Get the parent path (empty if there isn't one)
+ String getParentPath();
+
+ /// Get the Desc defining the contents of the artifact
SLANG_FORCE_INLINE const Desc& getDesc() { return m_desc; }
/// Returns the index of the entry
@@ -306,6 +320,8 @@ public:
/// Add items
void setPath(PathType pathType, const String& filePath) { m_pathType = pathType; m_path = filePath; }
+
+ /// Set the blob representing the contents of the asset
void setBlob(ISlangBlob* blob) { m_blob = blob; }
void add(Entry::Style style, RefObject* obj);
@@ -314,15 +330,25 @@ public:
PathType getPathType() const { return m_pathType; }
const String& getPath() const { return m_path; }
+ /// Get the name of the artifact. This can be empty.
+ const String& getName() const { return m_name; }
+
const List<Entry>& getEntries() const { return m_entries; }
+ /// Given a desc and a path returns the base name from the path (stripped of prefix and extension)
+ static String getBaseNameFromPath(Desc& desc, const UnownedStringSlice& path);
+
/// Ctor
- Artifact(const Desc& desc) :m_desc(desc) {}
+ Artifact(const Desc& desc, const String& name):
+ m_desc(desc),
+ m_name(name)
+ {}
/// Dtor
~Artifact();
protected:
Desc m_desc;
+ String m_name;
PathType m_pathType = PathType::None; ///< What the path indicates
String m_path; ///< The path
diff --git a/source/compiler-core/slang-dxc-compiler.cpp b/source/compiler-core/slang-dxc-compiler.cpp
index eb26dd3cc..0d05bf724 100644
--- a/source/compiler-core/slang-dxc-compiler.cpp
+++ b/source/compiler-core/slang-dxc-compiler.cpp
@@ -50,51 +50,39 @@ static UnownedStringSlice _getSlice(IDxcBlob* blob) { return StringUtil::getSlic
// 7f61fc7d-950d-467f-b3e3-3c02fb49187c
static const Guid IID_IDxcIncludeHandler = { 0x7f61fc7d, 0x950d, 0x467f, { 0x3c, 0x02, 0xfb, 0x49, 0x18, 0x7c } };
-namespace { // anonymous
-
-class LibraryNameList
+static UnownedStringSlice _addName(const UnownedStringSlice& inSlice, StringSlicePool& pool)
{
-public:
- void addName(Artifact* library)
+ UnownedStringSlice slice = inSlice;
+ if (slice.getLength() == 0)
{
- String name;
- if (library->getPathType() == Artifact::Existing)
- {
- name = Path::getFileNameWithoutExt(library->getPath());
- }
- addName(name);
+ slice = UnownedStringSlice::fromLiteral("unnamed");
}
- void addName(const String& inName)
+
+ StringBuilder buf;
+ const Index length = slice.getLength();
+ buf << slice;
+
+ for (Index i = 0; ; ++i)
{
- String name(inName);
- if (name.getLength() == 0)
+ buf.reduceLength(length);
+
+ if (i > 0)
{
- name = "unnamed";
+ buf << "_" << i;
}
- if (m_names.indexOf(name) >= 0)
+ StringSlicePool::Handle handle;
+ if (!pool.findOrAdd(buf.getUnownedSlice(), handle))
{
- StringBuilder buf;
- for (Index i = 1; ; ++i)
- {
- buf.Clear();
- buf << name << "_" << i;
-
- if (m_names.indexOf(buf) < 0)
- {
- name = buf;
- break;
- }
- }
+ return pool.getSlice(handle);
}
-
- m_names.add(name);
}
+}
- List<String> m_names;
-};
-
-} // anonymous
+static UnownedStringSlice _addName(Artifact* artifact, StringSlicePool& pool)
+{
+ return _addName(artifact->getBaseName().getUnownedSlice(), pool);
+}
class DxcIncludeHandler : public IDxcIncludeHandler
{
@@ -469,9 +457,10 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr
ComPtr<IDxcLinker> linker;
SLANG_RETURN_ON_FAIL(m_createInstance(CLSID_DxcLinker, __uuidof(linker), (void**)linker.writeRef()));
- List<ComPtr<ISlangBlob>> libraryBlobs;
+ StringSlicePool pool(StringSlicePool::Style::Default);
- LibraryNameList libraryNames;
+ List<ComPtr<ISlangBlob>> libraryBlobs;
+ List<OSString> libraryNames;
for (Artifact* library : libraries)
{
@@ -479,42 +468,37 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& options, RefPtr
SLANG_RETURN_ON_FAIL(library->loadBlob(ArtifactKeep::Yes, blob));
libraryBlobs.add(blob);
- libraryNames.addName(library);
+ libraryNames.add(String(_addName(library, pool)).toWString());
}
// Add the compiled blob name
-
- {
- auto blob = (ISlangBlob*)dxcResultBlob.get();
- libraryBlobs.add(ComPtr<ISlangBlob>(blob));
- }
-
+ String name;
if (options.modulePath.getLength())
{
- libraryNames.addName(Path::getFileNameWithoutExt(options.modulePath));
+ name = Path::getFileNameWithoutExt(options.modulePath);
}
else if (options.sourceContentsPath.getLength())
{
- libraryNames.addName(Path::getFileNameWithoutExt(options.sourceContentsPath));
+ name = Path::getFileNameWithoutExt(options.sourceContentsPath);
}
- else
+
+ // Add the blob with name
{
- libraryNames.addName("");
+ auto blob = (ISlangBlob*)dxcResultBlob.get();
+ libraryBlobs.add(ComPtr<ISlangBlob>(blob));
+ libraryNames.add(String(_addName(name.getUnownedSlice(), pool)).toWString());
}
- const Index librariesCount = libraryNames.m_names.getCount();
+ const Index librariesCount = libraryNames.getCount();
SLANG_ASSERT(libraryBlobs.getCount() == librariesCount);
List<const wchar_t*> linkLibraryNames;
- List<OSString> wideLibraryNames;
-
+
linkLibraryNames.setCount(librariesCount);
- wideLibraryNames.setCount(librariesCount);
-
+
for (Index i = 0; i < librariesCount; ++i)
{
- wideLibraryNames[i] = libraryNames.m_names[i].toWString();
- linkLibraryNames[i] = wideLibraryNames[i].begin();
+ linkLibraryNames[i] = libraryNames[i].begin();
// Register the library
SLANG_RETURN_ON_FAIL(linker->RegisterLibrary(linkLibraryNames[i], (IDxcBlob*)libraryBlobs[i].get()));
diff --git a/source/compiler-core/slang-gcc-compiler-util.cpp b/source/compiler-core/slang-gcc-compiler-util.cpp
index 7d1b7b86a..2d1ad2555 100644
--- a/source/compiler-core/slang-gcc-compiler-util.cpp
+++ b/source/compiler-core/slang-gcc-compiler-util.cpp
@@ -8,6 +8,7 @@
#include "../core/slang-io.h"
#include "../core/slang-shared-library.h"
#include "../core/slang-char-util.h"
+#include "../core/slang-string-slice-pool.h"
namespace Slang
{
@@ -620,65 +621,28 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
}
// Add the library paths
- List<String> libraryPaths;
- libraryPaths.addRange(options.libraryPaths.getBuffer(), options.libraryPaths.getCount());
+ StringSlicePool libPathPool(StringSlicePool::Style::Default);
+
+ for (const auto& libPath : options.libraryPaths)
+ {
+ libPathPool.add(libPath);
+ }
// Artifacts might add library paths
for (Artifact* artifact : options.libraries)
{
const auto desc = artifact->getDesc();
// If it's a library for CPU types, try and use it
- if (desc.isCpuBinary())
- {
- if (desc.kind == ArtifactKind::Library)
- {
- String path;
- SLANG_RETURN_ON_FAIL(artifact->requireFilePath(ArtifactKeep::No, path));
-
- String parentDir = Path::getParentDirectory(parentDir);
- if (parentDir.getLength())
- {
- // Check if we already have the library path, only add it if it's not found
- if (libraryPaths.indexOf(parentDir) < 0)
- {
- libraryPaths.add(parentDir);
- }
- path = Path::getFileName(path);
- }
-
- // If it starts with lib strip it
- if (path.startsWith("lib"))
- {
- const String stripLib = path.getUnownedSlice().tail(3);
- path = stripLib;
- }
-
- // Strip the extension if it's a match
- auto extension = Path::getPathExt(path);
- if (extension.getLength())
- {
- auto libExt = ArtifactDesc::make(ArtifactKind::Library, ArtifactPayload::HostCPU).getDefaultExtension();
- if (extension == libExt)
- {
- path = Path::getFileNameWithoutExt(path);
- }
- }
+ if (desc.isCpuBinary() && desc.kind == ArtifactKind::Library)
+ {
+ // Get the name and path (can be empty) to the library
+ SLANG_RETURN_ON_FAIL(artifact->requireFileLike(ArtifactKeep::No));
- cmdLine.addPrefixPathArg("-l", path);
- }
+ libPathPool.add(artifact->getParentPath());
+ cmdLine.addPrefixPathArg("-l", artifact->getBaseName());
}
}
- for (const auto& libPath : options.libraryPaths)
- {
- // Note that any escaping of the path is handled in the ProcessUtil::
- cmdLine.addArg("-L");
- cmdLine.addArg(libPath);
- cmdLine.addArg("-F");
- cmdLine.addArg(libPath);
- }
-
-
if (options.sourceLanguage == SLANG_SOURCE_LANGUAGE_CPP && !PlatformUtil::isFamily(PlatformFamily::Windows, platformKind))
{
// Make STD libs available
@@ -687,6 +651,15 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
cmdLine.addArg("-lm");
}
+ for (const auto& libPath : libPathPool.getAdded())
+ {
+ // Note that any escaping of the path is handled in the ProcessUtil::
+ cmdLine.addArg("-L");
+ cmdLine.addArg(libPath);
+ cmdLine.addArg("-F");
+ cmdLine.addArg(libPath);
+ }
+
return SLANG_OK;
}
diff --git a/source/compiler-core/slang-visual-studio-compiler-util.cpp b/source/compiler-core/slang-visual-studio-compiler-util.cpp
index df64ed821..0552657f8 100644
--- a/source/compiler-core/slang-visual-studio-compiler-util.cpp
+++ b/source/compiler-core/slang-visual-studio-compiler-util.cpp
@@ -4,6 +4,7 @@
#include "../core/slang-common.h"
#include "../../slang-com-helper.h"
#include "../core/slang-string-util.h"
+#include "../core/slang-string-slice-pool.h"
// if Visual Studio import the visual studio platform specific header
#if SLANG_VC
@@ -250,28 +251,36 @@ namespace Slang
// Link options (parameters past /link go to linker)
cmdLine.addArg("/link");
+ StringSlicePool libPathPool(StringSlicePool::Style::Default);
+
for (const auto& libPath : options.libraryPaths)
{
- // Note that any escaping of the path is handled in the ProcessUtil::
- cmdLine.addPrefixPathArg("/LIBPATH:", libPath);
+ libPathPool.add(libPath);
}
// Link libraries.
for (Artifact* artifact : options.libraries)
{
- if (artifact->getDesc().isCpuBinary())
+ auto desc = artifact->getDesc();
+
+ if (desc.isCpuBinary() && desc.kind == ArtifactKind::Library)
{
- String path;
- SLANG_RETURN_ON_FAIL(artifact->requireFilePath(ArtifactKeep::No, path));
+ // Get the libray name and path
+ SLANG_RETURN_ON_FAIL(artifact->requireFileLike(ArtifactKeep::No));
- if (Path::getPathExt(path).getLength() == 0)
- {
- path.append(".lib");
- }
- cmdLine.addArg(path);
+ libPathPool.add(artifact->getParentPath());
+ // We need the extension for windows
+ cmdLine.addArg(artifact->getBaseName() + ".lib");
}
}
+ // Add all the library paths
+ for (const auto& libPath : libPathPool.getAdded())
+ {
+ // Note that any escaping of the path is handled in the ProcessUtil::
+ cmdLine.addPrefixPathArg("/LIBPATH:", libPath);
+ }
+
return SLANG_OK;
}
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 789103ff8..edcb6e2d4 100644
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -1285,12 +1285,8 @@ void printDiagnosticArg(StringBuilder& sb, CodeGenTarget val)
if (_isCPUHostTarget(target))
{
options.libraryPaths.add(Path::getParentDirectory(Path::getExecutablePath()));
-
// Set up the library artifact
- const ArtifactDesc desc = ArtifactDesc::make(ArtifactKind::Library, Artifact::Payload::HostCPU, ArtifactStyle::Unknown);
- RefPtr<Artifact> artifact = new Artifact(desc);
- artifact->setPath(Artifact::PathType::Existing, "slang-rt");
-
+ RefPtr<Artifact> artifact = new Artifact(ArtifactDesc::make(ArtifactKind::Library, Artifact::Payload::HostCPU), "slang-rt");
options.libraries.add(artifact);
}
}
diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp
index 4c7234753..b02c25549 100644
--- a/source/slang/slang-options.cpp
+++ b/source/slang/slang-options.cpp
@@ -1422,8 +1422,11 @@ struct OptionsParser
return SLANG_FAIL;
}
+ const String name = Artifact::getBaseNameFromPath(desc, referenceModuleName.value.getUnownedSlice());
+
// Create the artifact
- RefPtr<Artifact> artifact = new Artifact(desc);
+ RefPtr<Artifact> artifact = new Artifact(desc, name);
+
// Set the path
artifact->setPath(Artifact::PathType::Existing, referenceModuleName.value);
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 5b65cd15a..83c52c660 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -4361,8 +4361,10 @@ SlangResult EndToEndCompileRequest::addLibraryReference(const void* libData, siz
RefPtr<ModuleLibrary> library;
SLANG_RETURN_ON_FAIL(loadModuleLibrary((const Byte*)libData, libDataSize, this, library));
- const auto desc = ArtifactDesc::make(ArtifactKind::Library, ArtifactPayload::SlangIR, ArtifactStyle::Unknown);
- RefPtr<Artifact> artifact = new Artifact(desc);
+ const auto desc = ArtifactDesc::make(ArtifactKind::Library, ArtifactPayload::SlangIR);
+
+ // Create an artifact without any name (as one is not provided)
+ RefPtr<Artifact> artifact = new Artifact(desc, String());
artifact->add(Artifact::Entry::Style::Artifact, library);