diff --git a/GNUmakefile b/GNUmakefile
new file mode 100644
index 0000000..ef8aa21
--- /dev/null
+++ b/GNUmakefile
@@ -0,0 +1,23 @@
+#* Makefile to build premake-core for tests on windows
+PREMAKE_OUT := vendor/premake-core/bin/release/premake5
+
+#* Runs the tests.
+all: build
+ @echo Testing debug config
+ @cd test/out/bin/debug && ./ExampleProjectExe && ./ExampleProjectExeNonCUDA
+ @echo Testing release config
+ @cd test/out/bin/release && ./ExampleProjectExe && ./ExampleProjectExeNonCUDA
+
+build: premake
+ @cd test/out && $(MAKE) config=debug
+ @cd test/out && $(MAKE) config=release
+
+premake: $(PREMAKE_OUT)
+ @$(PREMAKE_OUT) --file=test/premake5.lua gmake2
+
+$(PREMAKE_OUT):
+ @cd vendor/premake-core && $(MAKE) -f Bootstrap.mak linux PLATFORM=x64
+
+clean:
+ @rm -f $(PREMAKE_OUT)
+ @rm -rf test/out
diff --git a/README.md b/README.md
index c6ea0b3..d83ba39 100644
--- a/README.md
+++ b/README.md
@@ -1,31 +1,61 @@
a premake5 extension for cuda
-
premake5CUDA
+
premake5-CUDA
-Compiles CUDA code using the Visual Studio CUDA Toolkit extension. Enabled macros (listed in `src/cuda-exported-variables.lua`):
-- `cudaFiles` (Table) -> list of files to be compiled by NVCC to binary (relative path from solution root)
-- `cudaPTXFiles` (Table) -> list of files to be compiled by NVCC to PTX (relative path from solution root)
-- `cudaRelocatableCode` (Bool) -> triggers -rdc=true
-- `cudaExtensibleWholeProgram` (Bool) -> triggers extensible whole program compilation
-- `cudaCompilerOptions` (Table) -> passed to nvcc
-- `cudaLinkerOptions` (Table) -> passed to nvlink
-- `cudaFastMath` (Bool) -> triggers fast math optimizations
-- `cudaVerbosePTXAS` (Bool) -> triggers code gen verbosity
-- `cudaMaxRegCount` (String) -> number to determine the max used registers
-- `cudaKeep` (Bool) -> keeps preprocessed output
-- `cudaPath` (String) -> custom CUDA install path to override the VS integration plugin
-- `cudaGenLineInfo` (Bool) -> generates line info
-
-Files specified by the premake5 options `files` are compiled by the MSVC and not nvcc.
+Compiles CUDA code using the Visual Studio CUDA Toolkit extension on Windows and `nvcc` on Linux. Enabled macros (listed in `src/cuda-exported-variables.lua`):
+- `cudaFiles` (Table) -> list of files to be compiled by NVCC to binary (relative path from solution root).
+- `cudaPTXFiles` (Table) -> list of files to be compiled by NVCC to PTX (relative path from solution root) - Windows only.
+- `cudaRelocatableCode` (Bool) -> triggers -rdc=true.
+- `cudaExtensibleWholeProgram` (Bool) -> triggers extensible whole program compilation.
+- `cudaCompilerOptions` (Table) -> passed to nvcc.
+- `cudaLinkerOptions` (Table) -> passed to nvlink.
+- `cudaFastMath` (Bool) -> triggers fast math optimizations.
+- `cudaVerbosePTXAS` (Bool) -> triggers code gen verbosity.
+- `cudaMaxRegCount` (String) -> number to determine the max used registers.
+- `cudaKeep` (Bool) -> keeps preprocessed output.
+- `cudaPath` (String) -> custom CUDA install path.
+- `cudaGenLineInfo` (Bool) -> generates line info.
+
+----------------
+Notes for Windows:
+----------------
+
+Files specified by `files` are compiled by `cl` and not `nvcc`.
An example is provided in the test folder where a CUDA executable project containing C++, PTX and CUDA files is linked against a CUDA shared library project. If you clone this repo recursively (i.e. with `-recursive`), it will also pull the premake5 repo, which can be used via the makefile to build premake and then the tests (e.g. via the `nmake` command). You do not need the premake5 repo unless you want to build the tests.
To use:
- Install the CUDA toolkit, along with its Visual Studio integration.
-- Copy the premake5-cuda folder to your project
+- Copy the premake5-cuda folder to your project.
- Include it in your premake5.lua file as shown in the example.
Tested with Visual Studio 2022 (toolkit v143) with CUDA toolkit 12.1 VS integration.
Note: If PTX is requested, it will be found in the output object folder, with the .obj extension, though, it can be opened with a text editor for inspection.
+
+----------------
+Notes for Linux:
+----------------
+
+This extension was primarily made for VS on Windows, with the CUDA toolkit extension. Linux is a work in progress and does not have feature parity with Windows yet. Differences are:
+- toolset must be set as `"nvcc"`.
+- rules must be set to `'cu'`.
+- `cudaPTXFiles` not supported.
+- the list of cuda files must be provided in `files` instead of `cudaFiles`.
+- unlike Windows, the whole project is compiled by `nvcc` and not just the `.cu` files.
+
+See test premake5 file for how linux config differs. The differences are summarised here:
+
+```
+ if os.target() == "windows" then
+ cudaFiles { "exe/cu/**.cu" } -- files to be compiled into binaries by VS CUDA.
+ cudaPTXFiles { "exe/ptx/**.cu" } -- files to be compiled into ptx, Windows only.
+ else
+ toolset "nvcc"
+ files { "exe/cu/**.cu" }
+ rules {"cu"}
+ end
+```
+
+Admittedly, Linux support is a bit clunky but it should get the job done.
diff --git a/premake5-cuda.lua b/premake5-cuda.lua
index bb3e763..2757070 100644
--- a/premake5-cuda.lua
+++ b/premake5-cuda.lua
@@ -2,4 +2,6 @@ require("src/cuda-exported-variables")
if os.target() == "windows" then
dofile("src/premake5-cuda-vs.lua")
+elseif os.target() == "linux" then
+ dofile("src/premake5-cuda-nvcc.lua")
end
diff --git a/src/premake5-cuda-nvcc.lua b/src/premake5-cuda-nvcc.lua
new file mode 100644
index 0000000..1d59c47
--- /dev/null
+++ b/src/premake5-cuda-nvcc.lua
@@ -0,0 +1,100 @@
+--* Creates an NVCC toolset for Linux.
+
+rule 'cu'
+ fileExtension { ".cu" }
+ buildoutputs { "$(OBJDIR)/%{file.objname}.cu.o" }
+ buildmessage '$(notdir $<)'
+ buildcommands {'$(CXX) %{premake.modules.gmake2.cpp.fileFlags(cfg, file)} $(FORCE_INCLUDE) -o "$@" -MF "$(@:%.o=%.d)" -c "$<"'}
+
+premake.tools.nvcc = {}
+
+local nvcc = premake.tools.nvcc
+local gcc = premake.tools.gcc
+
+nvcc.getcflags = gcc.getcflags
+nvcc.getcppflags = gcc.getcppflags
+nvcc.getforceincludes = gcc.getforceincludes
+nvcc.getdefines = gcc.getdefines
+nvcc.getundefines = gcc.getundefines
+nvcc.getrunpathdirs = gcc.getrunpathdirs
+nvcc.getincludedirs = gcc.getincludedirs
+nvcc.getLibraryDirectories = gcc.getLibraryDirectories
+nvcc.getlinks = gcc.getlinks
+nvcc.getmakesettings = gcc.getmakesettings
+
+nvcc.cxxflags = {
+ cudaRelocatableCode = {
+ On = "-rdc=true",
+ Off = "-rdc=false"
+ },
+ cudaExtensibleWholeProgram = {
+ On = "-ewp"
+ },
+ cudaFastMath = {
+ On = "-use_fast_math"
+ },
+ cudaVerbosePTXAS = {
+ On = "--ptxas-options=--verbose"
+ },
+ cudaKeep = {
+ On = "-keep"
+ },
+ cudaGenLineInfo = {
+ On = "-lineinfo"
+ },
+ kind = {
+ SharedLib = "-fpic"
+ }
+}
+
+function nvcc.gettoolname (cfg, tool)
+
+ local prefix = ""
+ if cfg.project.cudaPath == nil then
+ prefix = "/usr/local/cuda/bin/"
+ else
+ prefix = cfg.project.cudaPath .. "/bin/"
+ end
+
+ if tool == "cc" then
+ name = prefix .. "nvcc"
+ elseif tool == "cxx" then
+ name = prefix .. "nvcc"
+ elseif tool == "ar" then
+ name = "ar"
+ else
+ name = nil
+ end
+ return name
+end
+
+function nvcc.getcxxflags(cfg)
+ local flags = premake.config.mapFlags(cfg, nvcc.cxxflags)
+ local gccFlags = premake.config.mapFlags(cfg, gcc.cxxflags)
+ flags = table.join(flags,gccFlags)
+ flags = table.join({"-forward-unknown-to-host-compiler"}, flags)
+
+ if cfg.cudaCompilerOptions ~= nil then
+ local cudaFlags = cfg.cudaCompilerOptions
+ flags = table.join(flags, cudaFlags)
+ end
+
+ if cfg.cudaMaxRegCount ~= nil then
+ flags = table.join(flags, { "--maxrregcount " .. cfg.cudaMaxRegCount})
+ end
+
+ return flags
+end
+
+function nvcc.getldflags(cfg)
+ local flags = premake.config.mapFlags(cfg, gcc.ldflags)
+ flags = table.join({"-forward-unknown-to-host-compiler"}, flags)
+ flags = table.join({"-Xlinker=-rpath,'$$ORIGIN'"}, flags)
+
+ if cfg.cudaLinkerOptions ~= nil then
+ local cudaFlags = cfg.cudaLinkerOptions
+ flags = table.join(flags, cudaFlags)
+ end
+
+ return flags
+end
diff --git a/test/premake5.lua b/test/premake5.lua
index a4dcb5a..3cc3c38 100644
--- a/test/premake5.lua
+++ b/test/premake5.lua
@@ -51,8 +51,17 @@ project "ExampleProjectExe"
buildcustomizations "BuildCustomizations/CUDA 12.1"
externalwarnings "Off" -- thrust gives a lot of warnings
- cudaFiles { "exe/cu/**.cu" } -- files to be compiled into binaries
- cudaPTXFiles { "exe/ptx/**.cu" } -- files to be compiled into ptx
+
+ if os.target() == "windows" then
+ cudaFiles { "exe/cu/**.cu" } -- files to be compiled into binaries by VS CUDA.
+ cudaPTXFiles { "exe/ptx/**.cu" } -- files to be compiled into ptx, Windows only.
+ else
+ toolset "nvcc"
+ cudaPath "/usr/local/cuda"
+ files { "exe/cu/**.cu" }
+ rules {"cu"}
+ end
+
cudaKeep "On" -- keep temporary output files
cudaFastMath "On"
cudaRelocatableCode "On"
@@ -74,10 +83,17 @@ project "ExampleProjectDLL"
buildcustomizations "BuildCustomizations/CUDA 12.1"
- -- Just in case we want the VS CUDA extension to use a custom version of CUDA
- cudaPath "$(CUDA_PATH)"
+ if os.target() == "windows" then
+ -- Just in case we want the VS CUDA extension to use a custom version of CUDA
+ cudaPath "$(CUDA_PATH)"
+ cudaFiles { "lib/**.cu" }
+ else
+ toolset "nvcc"
+ cudaPath "/usr/local/cuda"
+ files { "lib/**.cu" }
+ rules {"cu"}
+ end
- cudaFiles { "lib/**.cu" }
cudaRelocatableCode "On"
defines { "PREMAKE_CUDA_EXPORT_API" }