Skip to content

Comments

autodetect Visual Studio and linker options#7393

Merged
WalterBright merged 3 commits intodlang:masterfrom
rainers:detect_vs
Dec 5, 2017
Merged

autodetect Visual Studio and linker options#7393
WalterBright merged 3 commits intodlang:masterfrom
rainers:detect_vs

Conversation

@rainers
Copy link
Member

@rainers rainers commented Dec 3, 2017

This combines detection of latest VS and Windows SDK from Visual D and the DMD installer. All that is needed specific for -m64/-m32mscoff in sc.ini is

[Environment64]
LIB=%@P%\..\lib64;%LIB%
DFLAGS=%DFLAGS% -L/OPT:NOICF

[Environment32mscoff]
LIB=%@P%\..\lib32mscoff;%LIB%

Releated bugzilla issues:

https://issues.dlang.org/show_bug.cgi?id=16688
https://issues.dlang.org/show_bug.cgi?id=17999
https://issues.dlang.org/show_bug.cgi?id=14849

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @rainers!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

src/ddmd/link.d Outdated
if(!key)
return def;

char[260] buf;
Copy link
Member

Choose a reason for hiding this comment

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

append = void

src/ddmd/link.d Outdated
}
}

void Create(HKEY root, wstring keyname, bool x64hive = false)
Copy link
Member

Choose a reason for hiding this comment

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

I generally dislike using default arguments unless doing it for backwards compatibility. Since this is new code, please use explicit arguments.

src/ddmd/link.d Outdated
HRESULT hr;
}

const(char)* GetString(const(char)* szName, const(char)* def = null)
Copy link
Member

@WalterBright WalterBright Dec 4, 2017

Choose a reason for hiding this comment

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

no default args

src/ddmd/link.d Outdated
return def;

char[260] buf;
DWORD cnt = 260 * char.sizeof;
Copy link
Member

Choose a reason for hiding this comment

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

replace 260 with buf.length

src/ddmd/link.d Outdated
if (fileinfo.cFileName[0] >= '1' && fileinfo.cFileName[0] <= '9')
if (res is null || strcmp(res, fileinfo.cFileName.ptr) < 0)
if (FileName.exists(FileName.combine(FileName.combine(baseDir, fileinfo.cFileName.ptr), testfile)))
res = strdup(fileinfo.cFileName.ptr);
Copy link
Member

Choose a reason for hiding this comment

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

being in a loop, the res seems to be leaking memory upon reassignment

while(FindNextFileA(h, &fileinfo));
FindClose(h);

return res;
Copy link
Member

Choose a reason for hiding this comment

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

returning malloced memory should be documented

src/ddmd/link.d Outdated
res = strdup(fileinfo.cFileName.ptr);
}
while(FindNextFileA(h, &fileinfo));
FindClose(h);
Copy link
Member

Choose a reason for hiding this comment

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

Return value is ignored - should check it for error

Copy link
Member Author

Choose a reason for hiding this comment

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

Pretty unlikely to fail, and even if it does, should it abort a build?

src/ddmd/link.d Outdated

const(char)* GetString(const(char)* szName, const(char)* def = null)
{
if(!key)
Copy link
Member

Choose a reason for hiding this comment

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

Sometimes this PR uses if( and sometimes if (. Please use the latter style.

src/ddmd/link.d Outdated
{
if (!x64hive)
{
size_t len = strlen(szRegPath);
Copy link
Member

Choose a reason for hiding this comment

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

declare as const

src/ddmd/link.d Outdated
assert(len > 9 && szRegPath[0..9] == r"SOFTWARE\");
char* npath = cast(char*)mem.xmalloc(len + 13);
strcpy(npath, r"SOFTWARE\WOW6432Node\");
strcpy(npath + 21, szRegPath + 9);
Copy link
Member

Choose a reason for hiding this comment

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

Since in both calls to strcpy the lengths are known, use memcpy instead.

src/ddmd/link.d Outdated
{
pragma(lib, "advapi32.lib");

this(HKEY root, const(char)* szRegPath, bool x64hive = false)
Copy link
Member

Choose a reason for hiding this comment

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

no default arguments

src/ddmd/link.d Outdated
{
if(key)
{
RegCloseKey(key);
Copy link
Member

Choose a reason for hiding this comment

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

Check for error return

src/ddmd/link.d Outdated

void Create(HKEY root, wstring keyname, bool x64hive = false)
{
HRESULT hr;
Copy link
Member

Choose a reason for hiding this comment

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

Declaration that is unused?

src/ddmd/link.d Outdated
const(char)* p;
alias p this;

PathBuilder opDiv(const(char)* name)
Copy link
Member

Choose a reason for hiding this comment

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

Please don't do non-arithmetic operator overloading.

src/ddmd/link.d Outdated

PathBuilder opDiv(const(char)* name)
{
if (!name)
Copy link
Member

@WalterBright WalterBright Dec 4, 2017

Choose a reason for hiding this comment

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

The uses I see of PathBuilder suggest that name is never null, so this struct is kinda pointless. In fact, Filename.combine should do the right thing with a null second argument anyway. (I checked and it does not, so that should be fixed there, not adding a wrapper here.)

src/ddmd/link.d Outdated
auto sdk = PathBuilder(WindowsSdkDir) / "lib";
if(FileName.exists(sdk / WindowsSdkVersion / "um" / arch / "kernel32.lib")) // SDK 10.0
return sdk / WindowsSdkVersion / "um" / arch;
else if(FileName.exists(sdk / r"win8\um" / arch / "kernel32.lib")) // SDK 8.0
Copy link
Member

Choose a reason for hiding this comment

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

I'd rather see a / b / c added as a function to root.filename, so it can be used elsewhere. It should use variadic parameters to list them, or an array literal, or even 2,3,4 parameter overloads.

Copy link
Member Author

Choose a reason for hiding this comment

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

I introduced the PathBuilder struct because FileName.combine cannot be used with UFCS, but creates unreadable code if nesting multiple calls.
Using variadic parameters instead is almost as good, though, so I replaced PathBuilder with FileName.buildPath now.

src/ddmd/link.d Outdated
{
// debug info needs DLLs Common7\IDE for most linker versions
const char* path = getenv("PATH");
const char* npath = FileName.combine(VSInstallDir, r"Common7\IDE");
Copy link
Member

Choose a reason for hiding this comment

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

path and npath appear to never be used?

Copy link
Member Author

Choose a reason for hiding this comment

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

Ooops, missing PATH modification.

const(char)* VCInstallDir;
const(char)* VCToolsInstallDir; // used by VS 2017

void initialize()
Copy link
Member

Choose a reason for hiding this comment

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

In general, all functions need Ddoc comments.

@rainers
Copy link
Member Author

rainers commented Dec 4, 2017

@WalterBright Thanks for review, I've addressed most comments.

src/ddmd/link.d Outdated
}
}
while(FindNextFileA(h, &fileinfo));
FindClose(h);
Copy link
Member

Choose a reason for hiding this comment

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

FindClose() returns 0 on failure. Please check it. https://msdn.microsoft.com/en-us/library/windows/desktop/aa364413(v=vs.85).aspx

Copy link
Member Author

Choose a reason for hiding this comment

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

I know, but it feels a bit harsh to fail while a sensible result is already obtained. I've changed it nevertheless.

{
enum x64hive = false; // VS registry entries always in 32-bit hive

version(Win64)
Copy link
Member

Choose a reason for hiding this comment

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

Wait a minute! Why would the 64 bit build of DMD behave differently here? Shouldn't this be if the memory model of the target is set to 64?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, the target architecture is not relevant here. The VS registry/Windows SDK keys are only found in the 32-bit registry hive. KEY_WOW64_32KEY doesn't seem good enough, I had to use WOW6432Node explicitly, while a 32-bit process is automatically mapped to that hive.

src/ddmd/link.d Outdated
}

/**
* retreive options to be passed to the Micrsoft linker
Copy link
Member

Choose a reason for hiding this comment

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

"retrieve", and "Microsoft"

src/ddmd/link.d Outdated
}

/**
* retreive path to the Micrsoft linker executable
Copy link
Member

Choose a reason for hiding this comment

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

"retrieve", and "Microsoft"

@WalterBright
Copy link
Member

Much better. A couple more issues I commented on. I'm still not happy with the avoidable memory leaks, but it's not a deal breaker here. I do like how you fixed one leak by using realloc, I hadn't thought of that!

@rainers
Copy link
Member Author

rainers commented Dec 5, 2017

I'm still not happy with the avoidable memory leaks, but it's not a deal breaker here.

FileName.combine sometimes returns newly allocated memory, sometimes one of the arguments. This makes it necessary to predict what happens if you want to free the memory later. As this is done nowhere else, I opted not to do it here for a few more hundred bytes of leakage.

@WalterBright WalterBright merged commit d574724 into dlang:master Dec 5, 2017
@MartinNowak
Copy link
Member

Could you please add a changelog entry mentioning that VC is now detected at link-time instead of at install-time. Should we remove the detection from the installer?

@MartinNowak
Copy link
Member

Factoring this out into a separate dmd/windows_detect_vs module would make sense IMO.

@rainers
Copy link
Member Author

rainers commented Dec 17, 2017

Could you please add a changelog entry mentioning that VC is now detected at link-time instead of at install-time.

Will do.

Should we remove the detection from the installer?

Part of it. We might still want to allow the option of downloading VS if not found. Please note that the "light" runtime still needs the VC 2010 distributables.

@rainers
Copy link
Member Author

rainers commented Dec 22, 2017

Could you please add a changelog entry mentioning that VC is now detected at link-time instead of at install-time.

Done: #7493

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants