Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.
Open
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
# premake-vscode
An extension for premake that adds project and workspace generation for Visual Studio Code.

I got inspired to write this extension when I found these already existing extensions: [https://github.com/Enhex/premake-vscode](https://github.com/Enhex/premake-vscode) and [https://github.com/paullackner/premake-vscode](https://github.com/paullackner/premake-vscode), however they're a bit out-dated at the moment, and neither of them supports the premake features that I require, so I decided to write my own extension based on theirs.
This project was originally created [by peter](https://github.com/peter1745)

This was initially inspired by these repositories:
* [https://github.com/Enhex/premake-vscode](https://github.com/Enhex/premake-vscode)
* [https://github.com/paullackner/premake-vscode](https://github.com/paullackner/premake-vscode)

The goal of this project was to create a more up to date extension with more feature support!

Namely,
* Most of the C++ configuration properties that premake offers
* Might also support C and C# in the future, but for now C++ is the main focus.


## Supported Languages

### C++
Supported Premake `"CppDialect"` options:
* `C++98`, `C++11`, `C++14`, `C++17`, `C++20`, `C++2a`, `gnu++98`, `gnu++11`, `gnu++14`, `gnu++17`, `gnu++20`

C++ Compilers for Windows:
* `msvc`, `clang`

C++ Compilers for Linux:
* `gcc`, `clang`

My goal with this extension is to support most of the C++ configuration properties that premake offers, I might also support C and C# in the future, but for now C++ is the main focus.

## Usage
To use this extension add this repository to one of the Premake [search paths](https://premake.github.io/docs/Locating-Scripts/), and then add the following inside `premake-system.lua`:
Expand All @@ -15,3 +37,8 @@ Or add the following to your `premake5.lua` script if you added this repository
```lua
require("path/to/this/repo/vscode")
```

Then, you can invoke generation like so:
```bash
$ premake vscode
```
6 changes: 4 additions & 2 deletions _manifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@ return {
"_preload.lua",
"vscode.lua",
"vscode_workspace.lua",
"vscode_project.lua"
}
"vscode_project.lua",
"vscode_tasks.lua",
"vscode_launch.lua"
}
3 changes: 2 additions & 1 deletion _preload.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ newaction {
valid_languages = { "C", "C++", "C#" },
valid_tools = { "gcc", "clang", "msc" },

-- Generate appropriate build files
onStart = function()
if _TARGET_OS == "windows" then
os.execute(_PREMAKE_COMMAND .. " vs2022")
Expand All @@ -39,4 +40,4 @@ newaction {

return function(cfg)
return _ACTION == "vscode"
end
end
48 changes: 24 additions & 24 deletions vscode.lua
Original file line number Diff line number Diff line change
@@ -1,38 +1,41 @@
local p = premake
-- VSCODE MODULE

p.modules.vscode = { _VERSION = "1.0.0" }

local vscode = p.modules.vscode
-- Include workspace and project files

include("vscode_workspace.lua")
include("vscode_project.lua")

-- preload
include("_preload.lua")


-- Aliases
local p = premake
local project = p.project
local vscode = p.modules.vscode

vscode = { _VERSION = "1.0.0" }

-- Workspace Generation
function vscode.generateWorkspace(wks)
p.eol("\r\n")
p.indent("\t")
-- NOTE: the .code-workspace file contains the tasks and launch configurations.
p.generate(wks, ".code-workspace", vscode.workspace.generate)
p.generate(wks, wks.location .. "/Tasks/.vscode/tasks.json", vscode.workspace.tasks.generate)
end

-- Project Generation
function vscode.generateProject(prj)
p.eol("\r\n")
p.indent("\t")

-- C/C++ Support
-- * This is where support for other languages will eventually be specified
if (project.isc(prj) or project.iscpp(prj)) then
p.generate(prj, prj.location .. "/.vscode/c_cpp_properties.json", vscode.project.cCppProperties.generate)
end

local isLaunchable = false

for cfg in project.eachconfig(prj) do
isLaunchable = cfg.kind == "ConsoleApp" or cfg.kind == "WindowedApp"

if isLaunchable then
break
end
end

if isLaunchable then
p.generate(prj, prj.location .. "/.vscode/launch.json", vscode.project.launch.generate)
end

end

function vscode.configName(config, includePlatform)
Expand All @@ -44,11 +47,13 @@ function vscode.configName(config, includePlatform)
end

function vscode.getToolsetName(cfg)
-- MSC for windows, CLANG for everything else
local default = iif(cfg.system == p.WINDOWS, "msc", "clang")
return _OPTIONS.cc or cfg.toolset or default
end

function vscode.getCompiler(cfg)
-- MSC for windows, CLANG for everything else
local default = iif(cfg.system == p.WINDOWS, "msc", "clang")
local toolset = p.tools[_OPTIONS.cc or cfg.toolset or default]
if not toolset then
Expand All @@ -63,9 +68,4 @@ function vscode.esc(value)
return value
end

include("vscode_workspace.lua")
include("vscode_project.lua")

include("_preload.lua")

return vscode
return vscode
102 changes: 102 additions & 0 deletions vscode_launch.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
-- LAUNCH CONFIG GENERATION

-- aliases (for nicer code and less writing)
local p = premake
local project = p.project
local vscode = p.modules.vscode

-- Initialize premake module object
vscode.launch = {}
local launch = vscode.launch

-- Function reflection
launch.configProps = function(prj, cfg)
-- Returns an array of the generation functions for each property (if any new are created, they should be added here).
return {
launch.type,
launch.request,
launch.program,
launch.args,
launch.stopAtEntry,
launch.cwd,
launch.environment,
launch.preLaunchTask
}
end


-- GENERATION --

function launch.type(prj, cfg)
if cfg.system == "windows" then
p.w('"type": "cppvsdbg",')
else
p.w('"type": "cppdbg",')
end
end

function launch.request(prj, cfg)
p.w('"request": "launch",')
end

-- build target
function launch.program(prj, cfg)
local targetdir = project.getrelative(prj, cfg.buildtarget.directory)
local targetname = cfg.buildtarget.name
p.w('"program": "%s/%s",', prj.location, path.join(targetdir, targetname))
end

function launch.args(prj, cfg)
p.w('"args": [],')
end

function launch.stopAtEntry(prj, cfg)
p.w('"stopAtEntry": false,')
end

function launch.cwd(prj, cfg)
-- I think this currently launches from the workspace directory since launch configs now generate in the ".code-workspace" file
-- TODO: Make sure that these are running from proper project directories. Otherwise programs that depend on files relative to the program in some resource file won't be able to find the files.'
p.w('"cwd": "./",')
end

function launch.environment(prj, cfg)
p.w('"environment": [],')
end

-- Pre-launch task
function launch.preLaunchTask(prj, cfg)
-- Calls the relevant build task before launching.
local configName = vscode.configName(cfg, #prj.workspace.platforms > 1)
p.w('"preLaunchTask": "BUILD-%s",', cfg.name)
end

function launch.generate(prj)
-- Generates ".json" formatted launch configs to generate in the ".code-workspace" file.
-- * NOTE: This doesn't need to return anything since the scope that it's called in should have an open file that it's writing to through premake's API

-- Start launch options block
p.push('"launch": {')
p.w('"version": "0.2.0",')

-- Start configurations array
p.push('"configurations": [')

-- Loop through each project's configs
for cfg in project.eachconfig(prj) do
p.push('{')

-- Set Launch name (name that shows in launch menu in vscode)
local configName = vscode.configName(cfg, #prj.workspace.platforms > 1)
p.w('"name": "Launch %s",', configName)

-- Call each of the config generation functions for this project configuration
-- * TODO: Find a way to get rid of the extra comma after the last property (avoiding hard-coding). I think vscode still parses it just fine, but it does show some scary errors in the generated files if you open them (not ideal).
p.callArray(launch.configProps, prj, cfg)

p.pop('},')
end
-- Done
p.pop(']')
p.pop('}')
end
Loading