Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 18 additions & 5 deletions lib/bundlex/toolchain/visual_studio.ex
Original file line number Diff line number Diff line change
Expand Up @@ -59,30 +59,34 @@ defmodule Bundlex.Toolchain.VisualStudio do

output_path = Toolchain.output_path(native.app, native.name, interface)

deps =
native.deps
|> Enum.map(&(Toolchain.output_path(&1.app, &1.name, &1.interface) <> ".lib"))
|> paths()

commands =
case native do
%Native{type: :native, interface: :nif} ->
[
"(cl #{compile_options} #{includes_part} #{sources_part})",
~s[(link #{link_options} #{libs_part} /DLL /OUT:"#{PathHelper.fix_slashes(output_path)}.dll" *.obj)]
~s[(link #{link_options} #{libs_part} /DLL /OUT:"#{PathHelper.fix_slashes(output_path)}.dll" *.obj #{deps})]
]

%Native{type: :lib} ->
[
"(cl #{compile_options} #{includes_part} #{sources_part})",
~s[(lib /OUT:"#{PathHelper.fix_slashes(output_path)}.lib" *.obj)]
~s[(lib /OUT:"#{PathHelper.fix_slashes(output_path)}.lib" *.obj #{deps})]
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static libraries (.lib files created by the lib tool) are archives of object files and typically don't link other libraries. The lib command may not properly handle the deps parameter. In the Unix implementation (common/unix.ex, line 74-76), the ar command for :lib type natives intentionally does not include deps, as dependencies are resolved when the static library is later linked into an executable or shared library. Consider removing deps from this lib command to match the Unix behavior.

Suggested change
~s[(lib /OUT:"#{PathHelper.fix_slashes(output_path)}.lib" *.obj #{deps})]
~s[(lib /OUT:"#{PathHelper.fix_slashes(output_path)}.lib" *.obj)]

Copilot uses AI. Check for mistakes.
]

%Native{type: type, interface: :nif} when type in [:cnode, :port] ->
[
"(cl #{compile_options} #{includes_part} #{sources_part})",
~s[(link /libpath:"#{:code.root_dir() |> Path.join("lib/erl_interface-5.5.2/lib") |> PathHelper.fix_slashes()}" #{link_options} #{libs_part} /OUT:"#{PathHelper.fix_slashes(output_path)}.exe" *.obj)]
~s[(link /libpath:"#{:code.root_dir() |> Path.join("lib/erl_interface-5.5.2/lib") |> PathHelper.fix_slashes()}" #{link_options} #{libs_part} /OUT:"#{PathHelper.fix_slashes(output_path)}.exe" *.obj #{deps})]
]
end

[
"(if exist #{dir_part} rmdir /S /Q #{dir_part})",
"(mkdir #{dir_part})",
"(if not exist #{dir_part} mkdir #{dir_part})",
"(pushd #{dir_part})",
commands,
"(popd)"
Expand Down Expand Up @@ -132,4 +136,13 @@ defmodule Bundlex.Toolchain.VisualStudio do
)
end
end

defp paths(paths, flag \\ "") do
Enum.map_join(paths, " ", fn p -> "#{flag}#{path(p)}" end)
end

defp path(path) do
path = path |> String.replace(~S("), ~S(\")) |> Path.expand()
Copy link

Copilot AI Jan 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The path function uses Path.expand() and adds quotes but doesn't apply PathHelper.fix_slashes() to convert forward slashes to backslashes for Windows. This is inconsistent with how other paths are handled in this file (see lines 35, 39, 52, 72, 84) where PathHelper.fix_slashes() is used. The Unix implementation also uses Path.expand() in its path function, but that's appropriate for Unix systems. On Windows, the dependency paths may contain forward slashes that need to be converted to backslashes for MSVC tools. Consider adding PathHelper.fix_slashes() to the path function or applying it to the deps before passing them to paths().

Suggested change
path = path |> String.replace(~S("), ~S(\")) |> Path.expand()
path =
path
|> String.replace(~S("), ~S(\"))
|> Path.expand()
|> PathHelper.fix_slashes()

Copilot uses AI. Check for mistakes.
~s("#{path}")
end
end