I have an executable C++ project that used to contain embedded unit tests. I've moved the tests to another (.dll) project, to use them with the VS Test Runner, and all is well except for a bunch of unresolved external symbol errors.
Things seem to work if I link all of the .obj files from the .exe into the .dll, but there are a lot of them and it's very "dirty" to hardcode them since the list can always change.
I've tried adding the .exe project as a reference and setting "use Library Dependency Inputs" to True, but it doesn't seem to do anything.
Upon inspection of Microsoft.CppBuild.targets, I found that .obj files for projects with UseLibraryDependencyInputs
set to true, which corresponds to checking 'use Library Dependency Inputs' in VS, are included only if the project is a StaticLibrary.
A quick and dirty way around this then is to override the Task ResolvedLinkObjs
inside the .vcxproj, with slight modifications.
Testing this out, I was able to link all the .obj files from the projects I referenced.
I changed the ItemName
of the TargetOutputs
MSBuild task output to "ProjectReferenceToLink"
and added ConfigurationType=StaticLibrary
to the passed Propertie
s. The side-effects of treating the .exe project as a StaticLibrary
while calling this target aren't immediately obvious, but I haven't noticed anything bad.
<Target Name="ResolvedLinkObjs" DependsOnTargets="$(CommonBuildOnlyTargets)">
<MSBuild Projects="@(_MSBuildProjectReferenceExistent)"
Targets="GetResolvedLinkObjs"
BuildInParallel="$(BuildInParallel)"
Properties="%(_MSBuildProjectReferenceExistent.SetConfiguration); %(_MSBuildProjectReferenceExistent.SetPlatform); ConfigurationType=StaticLibrary"
Condition="'%(_MSBuildProjectReferenceExistent.Extension)' == '.vcxproj' and '@(ProjectReferenceWithConfiguration)' != '' and '@(_MSBuildProjectReferenceExistent)' != ''"
ContinueOnError="!$(BuildingProject)"
RemoveProperties="%(_MSBuildProjectReferenceExistent.GlobalPropertiesToRemove)">
<Output TaskParameter="TargetOutputs" ItemName="ProjectReferenceToLink" />
</MSBuild>
</Target>
This can easily be modified to just grab the .objs from one project. A cleaner method would also probably involve not overriding a built-in Target like this but instead inserting it into to the chain.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With