diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-04-25 08:51:12 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-04-25 08:51:12 -0400 |
| commit | c84e7c0fa526de51f380227a6667f723af36aea2 (patch) | |
| tree | 755c034fab30a2d0dfe7f8f6027d892b46d19f87 | |
| parent | 1004f50bd7d0032411a564ad4625055e982902ea (diff) | |
Fixed building on CygWin with clang gcc (#953)
* * Make Path:: use lowerCamel method names as per coding standard
* Small improvements to make closer to standard
* GetDirectoryName -> getParentDirectory - previous method name's action was somewhat unclear, hopefully this is better
* * Can build on clang and gcc on CygWin
* Fix problem on cygwin loading shared libraries
* Renamed Path::isRelative to ::hasRelativeElement because isRelative implies the path is 'relative to the current path' and which isn't quite what it does
* Documented how to build for CygWin
* * Fix small bug creating platform shared library name.
* Small typo fixes in building.md
| -rw-r--r-- | docs/building.md | 18 | ||||
| -rw-r--r-- | premake5.lua | 39 | ||||
| -rw-r--r-- | source/core/platform.cpp | 5 | ||||
| -rw-r--r-- | source/core/slang-io.cpp | 68 | ||||
| -rw-r--r-- | source/core/slang-io.h | 15 | ||||
| -rw-r--r-- | source/slang/slang-file-system.cpp | 2 | ||||
| -rw-r--r-- | tools/slang-test/unit-test-path.cpp | 20 |
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\\.\\")); } |
