summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/building.md18
-rw-r--r--premake5.lua39
-rw-r--r--source/core/platform.cpp5
-rw-r--r--source/core/slang-io.cpp68
-rw-r--r--source/core/slang-io.h15
-rw-r--r--source/slang/slang-file-system.cpp2
-rw-r--r--tools/slang-test/unit-test-path.cpp20
7 files changed, 142 insertions, 25 deletions
diff --git a/docs/building.md b/docs/building.md
index 32e4a1156..c4b8fc521 100644
--- a/docs/building.md
+++ b/docs/building.md
@@ -15,9 +15,11 @@ If you are on Windows, then open `slang.sln` and build your desired platform/con
The Visual Studio solution in the project is actually just generated using [`premake5`](https://premake.github.io/). See instructions in premake section below for further explanation.
-## Linux
+## Other Targets
-For building on Linux it is first necessary to generate the `Makefile` for the project - we use [`premake5`](https://premake.github.io/) as the tool used for generating projects from the premake5.lua script found in the root of the project. The section below describes how to use premake on Linux.
+Slang uses [`premake5`](https://premake.github.io/) to generate projects (such as `Makefile`s) that can then be used to build Slang binaries from source.
+
+For Linux and other targets the section below on `premake` describes the process.
## Premake
@@ -70,6 +72,18 @@ To actually build using make use one of the following
% make config=debug_aarch64
```
+### CygWin
+
+Note that Cygwin isn't an official target.
+
+One issue with building on CygWin, is that there isn't a binary version of `premake` currently available. It may be possible to make this work by building `premake` from source, and then just doing `premake5 gmake`. Here we use another approach - using the windows `premake` to create a cygwin project. To do this use the command line...
+
+```
+% premake5 --target-detail=cygwin gmake
+```
+
+If you want to specify the toolset use `--cc=gcc` or `--cc=clang` on the command line. To check what compiler is being used/command line options you can add `verbose=1` to `make` command line.
+
## Testing
When slang is built from source it also builds tools to be able to test the Slang compiler. Testing is achieved using the `slang-test` tool. The binaries are placed in the appropriate directory underneath `bin`. To run the tests on a release x64 build from the command line, in the root directory of slang source tree you can use...
diff --git a/premake5.lua b/premake5.lua
index dc3faa392..d939400d0 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -48,6 +48,7 @@
-- From in the build directory you can use
-- % premake5 --file=../premake5.lua --os=linux gmake
+
newoption {
trigger = "override-module",
description = "(Optional) Specify a lua file that can override functions",
@@ -68,8 +69,19 @@ newoption {
allowed = { { "true", "True"}, { "false", "False" } }
}
+newoption {
+ trigger = "target-detail",
+ description = "(Optional) More specific target information",
+ value = "string",
+ allowed = { {"cygwin"}, {"mingw"} }
+}
+
buildLocation = _OPTIONS["build-location"]
executeBinary = (_OPTIONS["execute-binary"] == "true")
+targetDetail = _OPTIONS["target-detail"]
+
+-- Is true when the target is really windows (ie not something on top of windows like cygwin)
+local isTargetWindows = (os.target() == "windows") and not (targetDetail == "mingw" or targetDetail == "cygwin")
overrideModule = {}
local overrideModulePath = _OPTIONS["override-module"]
@@ -79,6 +91,18 @@ end
targetName = "%{cfg.system}-%{cfg.platform:lower()}"
+if not (targetDetail == nil) then
+ targetName = targetDetail .. "-%{cfg.platform:lower()}"
+end
+
+-- This is needed for gcc, for the 'fileno' functions on cygwin
+-- _GNU_SOURCE makes realpath available in gcc
+if targetDetail == "cygwin" then
+ buildoptions { "-D_POSIX_SOURCE" }
+ filter { "toolset:gcc*" }
+ buildoptions { "-D_GNU_SOURCE" }
+end
+
workspace "slang"
-- We will support debug/release configuration and x86/x64 builds.
configurations { "Debug", "Release" }
@@ -379,7 +403,7 @@ function example(name)
links { "slang", "core", "gfx" }
end
-if os.target() == "windows" then
+if isTargetWindows then
--
-- With all of these helper routines defined, we can now define the
-- actual projects quite simply. For example, here is the entire
@@ -471,7 +495,7 @@ toolSharedLibrary "slang-reflection-test"
-- TODO: Fix that requirement.
--
-if os.target() == "windows" then
+if isTargetWindows then
toolSharedLibrary "render-test"
uuid "61F7EB00-7281-4BF3-9470-7C2EA92620C3"
@@ -501,17 +525,18 @@ tool "gfx"
includedirs { ".", "external", "source", "external/imgui" }
- filter { "system:windows" }
-
+ -- To special case that we may be building using cygwin on windows. If 'true windows' we build for dx12/vk and run the script
+ -- If not we assume it's a cygwin/mingw type situation and remove files that aren't appropriate
+ if isTargetWindows then
systemversion "10.0.14393.0"
-- For Windows targets, we want to copy d3dcompiler_47.dll,
-- dxcompiler.dll, and dxil.dll from the Windows SDK redistributable
-- directory into the output directory.
postbuildcommands { '"$(SolutionDir)tools\\copy-hlsl-libs.bat" "$(WindowsSdkDir)Redist/D3D/%{cfg.platform:lower()}/" "%{cfg.targetdir}/"'}
-
- filter { "system:not windows" }
- removefiles { "tools/gfx/circular-resource-heap-d3d12.cpp", "tools/gfx/d3d-util.cpp", "tools/gfx/descriptor-heap-d3d12.cpp", "tools/gfx/render-d3d11.cpp", "tools/gfx/render-d3d12.cpp", "tools/gfx/render-gl.cpp", "tools/gfx/resource-d3d12.cpp", "tools/gfx/render-vk.cpp", "tools/gfx/vk-swap-chain.cpp", "tools/gfx/window.cpp" }
+ else
+ removefiles { "tools/gfx/circular-resource-heap-d3d12.cpp", "tools/gfx/d3d-util.cpp", "tools/gfx/descriptor-heap-d3d12.cpp", "tools/gfx/render-d3d11.cpp", "tools/gfx/render-d3d12.cpp", "tools/gfx/render-gl.cpp", "tools/gfx/resource-d3d12.cpp", "tools/gfx/render-vk.cpp", "tools/gfx/vk-swap-chain.cpp", "tools/gfx/window.cpp" }
+ end
--
-- The `slangc` command-line application is just a very thin wrapper
diff --git a/source/core/platform.cpp b/source/core/platform.cpp
index ff7d8e231..e7575d21e 100644
--- a/source/core/platform.cpp
+++ b/source/core/platform.cpp
@@ -150,9 +150,14 @@ SLANG_COMPILE_TIME_ASSERT(E_OUTOFMEMORY == SLANG_E_OUT_OF_MEMORY);
/* static */void SharedLibrary::appendPlatformFileName(const UnownedStringSlice& name, StringBuilder& dst)
{
+#if __CYGWIN__
+ dst.Append(name);
+ dst.Append(".dll");
+#else
dst.Append("lib");
dst.Append(name);
dst.Append(".so");
+#endif
}
#endif // _WIN32
diff --git a/source/core/slang-io.cpp b/source/core/slang-io.cpp
index 7385934c3..332718cea 100644
--- a/source/core/slang-io.cpp
+++ b/source/core/slang-io.cpp
@@ -1,6 +1,8 @@
#include "slang-io.h"
#include "exception.h"
+#include "../../slang-com-helper.h"
+
#ifndef __STDC__
# define __STDC__ 1
#endif
@@ -152,7 +154,39 @@ namespace Slang
}
default: return false;
}
-
+ }
+
+ UnownedStringSlice Path::getFirstElement(const UnownedStringSlice& in)
+ {
+ const char* end = in.end();
+ const char* cur = in.begin();
+ // Find delimiter or the end
+ while (cur < end && !Path::isDelimiter(*cur)) ++cur;
+ return UnownedStringSlice(in.begin(), cur);
+ }
+
+ /* static */bool Path::isAbsolute(const UnownedStringSlice& path)
+ {
+ if (path.size() > 0 && isDelimiter(path[0]))
+ {
+ return true;
+ }
+
+#if SLANG_WINDOWS_FAMILY
+ // Check for the \\ network drive style
+ if (path.size() >= 2 && path[0] == '\\' && path[1] == '\\')
+ {
+ return true;
+ }
+
+ // Check for drive
+ if (isDriveSpecification(getFirstElement(path)))
+ {
+ return true;
+ }
+#endif
+
+ return false;
}
/* static */void Path::split(const UnownedStringSlice& path, List<UnownedStringSlice>& splitOut)
@@ -186,7 +220,7 @@ namespace Slang
}
}
- /* static */bool Path::isRelative(const UnownedStringSlice& path)
+ /* static */bool Path::hasRelativeElement(const UnownedStringSlice& path)
{
List<UnownedStringSlice> splitPath;
split(path, splitPath);
@@ -316,6 +350,8 @@ namespace Slang
::free(absPath);
return SLANG_OK;
#else
+# if 1
+
// http://man7.org/linux/man-pages/man3/realpath.3.html
char* canonicalPath = ::realpath(path.begin(), nullptr);
if (canonicalPath)
@@ -325,6 +361,34 @@ namespace Slang
return SLANG_OK;
}
return SLANG_FAIL;
+# else
+ // This is a mechanism to get an approximation of canonical path if we don't have 'realpath'
+ // We only can get if the file exists. This checks that the ../. etc are really valid
+ SlangPathType pathType;
+ SLANG_RETURN_ON_FAIL(getPathType(path, &pathType));
+ if (isAbsolute(path))
+ {
+ // If it's absolute, we can just simplify as is
+ canonicalPathOut = Path::simplify(path);
+ return SLANG_OK;
+ }
+ else
+ {
+ char buffer[PATH_MAX];
+ // https://linux.die.net/man/3/getcwd
+ const char* getCwdPath = getcwd(buffer, SLANG_COUNT_OF(buffer));
+ if (!getCwdPath)
+ {
+ return SLANG_FAIL;
+ }
+
+ // Okay combine the paths
+ String combinedPaths = Path::combine(String(getCwdPath), path);
+ // Simplify
+ canonicalPathOut = Path::simplify(combinedPaths);
+ return SLANG_OK;
+ }
+# endif
#endif
}
diff --git a/source/core/slang-io.h b/source/core/slang-io.h
index a982b7adc..9df8d8d57 100644
--- a/source/core/slang-io.h
+++ b/source/core/slang-io.h
@@ -45,9 +45,13 @@ namespace Slang
static String simplify(const UnownedStringSlice& path);
static String simplify(const String& path) { return simplify(path.getUnownedSlice()); }
- /// Returns true if a path contains a . or ..
- static bool isRelative(const UnownedStringSlice& path);
- static bool isRelative(const String& path) { return isRelative(path.getUnownedSlice()); }
+ /// Returns true if the path is absolute
+ static bool isAbsolute(const UnownedStringSlice& path);
+ static bool isAbsolute(const String& path) { return isAbsolute(path.getUnownedSlice()); }
+
+ /// Returns true if path contains contains an element of . or ..
+ static bool hasRelativeElement(const UnownedStringSlice& path);
+ static bool hasRelativeElement(const String& path) { return hasRelativeElement(path.getUnownedSlice()); }
/// Determines the type of file at the path
/// @param path The path to test
@@ -66,6 +70,11 @@ namespace Slang
/// @return The path in platform native format. Returns empty string if failed.
static String getExecutablePath();
+ /// Returns the first element of the path or an empty slice if there is none
+ /// This broadly equivalent to returning the first element of split
+ /// @param path Path to extract first element from
+ /// @return The first element of the path, or empty
+ static UnownedStringSlice getFirstElement(const UnownedStringSlice& path);
};
}
diff --git a/source/slang/slang-file-system.cpp b/source/slang/slang-file-system.cpp
index 2583a7562..58cda679d 100644
--- a/source/slang/slang-file-system.cpp
+++ b/source/slang/slang-file-system.cpp
@@ -249,7 +249,7 @@ SlangResult CacheFileSystem::_calcUniqueIdentity(const String& path, String& out
{
outUniqueIdentity = Path::simplify(path);
// If it still has relative elements can't uniquely identify, so give up
- return Path::isRelative(outUniqueIdentity) ? SLANG_FAIL : SLANG_OK;
+ return Path::hasRelativeElement(outUniqueIdentity) ? SLANG_FAIL : SLANG_OK;
}
case UniqueIdentityMode::SimplifyPathAndHash:
case UniqueIdentityMode::Hash:
diff --git a/tools/slang-test/unit-test-path.cpp b/tools/slang-test/unit-test-path.cpp
index 2ad66792f..35462f703 100644
--- a/tools/slang-test/unit-test-path.cpp
+++ b/tools/slang-test/unit-test-path.cpp
@@ -38,21 +38,21 @@ static void pathUnitTest()
SLANG_CHECK(Path::simplify("tests/preprocessor/.\\pragma-once-a.h") == "tests/preprocessor/pragma-once-a.h");
- SLANG_CHECK(Path::isRelative("."));
- SLANG_CHECK(Path::isRelative(".."));
- SLANG_CHECK(Path::isRelative("blah/.."));
+ SLANG_CHECK(Path::hasRelativeElement("."));
+ SLANG_CHECK(Path::hasRelativeElement(".."));
+ SLANG_CHECK(Path::hasRelativeElement("blah/.."));
- SLANG_CHECK(Path::isRelative("blah/.././a"));
- SLANG_CHECK(Path::isRelative("a") == false);
- SLANG_CHECK(Path::isRelative("blah/a") == false);
- SLANG_CHECK(Path::isRelative("a:\\blah/a") == false);
+ SLANG_CHECK(Path::hasRelativeElement("blah/.././a"));
+ SLANG_CHECK(Path::hasRelativeElement("a") == false);
+ SLANG_CHECK(Path::hasRelativeElement("blah/a") == false);
+ SLANG_CHECK(Path::hasRelativeElement("a:\\blah/a") == false);
- SLANG_CHECK(Path::isRelative("a:/what/.././../is/./../this/."));
+ SLANG_CHECK(Path::hasRelativeElement("a:/what/.././../is/./../this/."));
- SLANG_CHECK(Path::isRelative("a:/what/.././../is/./../this/./"));
+ SLANG_CHECK(Path::hasRelativeElement("a:/what/.././../is/./../this/./"));
- SLANG_CHECK(Path::isRelative("a:\\what\\..\\.\\..\\is\\.\\..\\this\\.\\"));
+ SLANG_CHECK(Path::hasRelativeElement("a:\\what\\..\\.\\..\\is\\.\\..\\this\\.\\"));
}