How to force msbuild to ignore warning MSB8012 - msbuild

I know this question was discussed hundreds of times, but I still cannot find solution. Maybe something was changed in msbuild and I am not aware. The problem is that I get the following warning
warning MSB8012: TargetPath(d:\src\output\Techd.dll) does not match the Linker's OutputFile
property value (d:\src\output\Debug32\bin\Techd.dll). This may cause your project to build
incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and
$(TargetExt) property values match the value specified in %(Link.OutputFile).
I change the outdir by property
msbuild.wxw /p:OutDir="my_out_dir"
I cannot change projects properties and I am not allowed to modify msbuild target files (Microsoft.CppBuild.targets). So don't have any idea hot to force msbuild to ignore this warning or to ignore the $OutDir variable's change.

You should be able to silence MSBuild warnings using a command line parameter:
msbuild.exe /nowarn:MSB8012
In an upcoming update to MSBuild/VS2017 (15.3), you can specify properties to control MSBuild warnings in project files as a property, so that it also affects builds in VS:
<MSBuildWarningsAsMessages>MSB8012</MSBuildWarningsAsMessages>

Related

How to override csproj.user for msbuild invocation?

My colleagues and I have user specific settings in csproj.user files. They are not checked into the repository. I would like for the build server to use its own set of csproj.user files, overriding certain properties, leaving the "base" project configuration at a decent developer default. But from the looks of it there is no such option in the msbuild command-line for doing that.
Is there really no way, other than copy csproj.user-files to where it'll be picked up by subsequent msbuild invocations?
While writing I realize I'm too much of a prude about these things and should just copy as a step prior build. Still posting in case someone knows a better way, for instance a way that does not modify the source tree.
Passing properties to the MSBuild command line overrides properties in the solution, including dependent projects. Here omitting debug information in build server, otherwise generated for release build to improve profiling:
msbuild MySolution.sln /p:DebugType=none ...
This does not work should I want different properties for different projects. Building projects individually should work nicely though.
Finally, passing arguments on command line can get messy, so to get a more "settings file"-like experience one may instead use #file arguments and MSBuild response files.

How to set CMAKE_FIND_LIBRARY_SUFFIXES to nothing

I have run into an issue when writing find scripts. For some reason, automatic appending of suffixes did not work: only library files with .dylib extension were found, however files with .a extension or no extension at all were not.
Practical experimentation lead me to setting CMAKE_FIND_LIBRARY_SUFFIXES to an empty value and restoring the value afterwards. However, this has following effect:
When cmake is run for the first time, generation fails with "CMake Error: Error required internal CMake variable not set, cmake may not be built correctly. Missing variable is CMAKE_FIND_LIBRARY_SUFFIXES".
When I run cmake second time the same way, generation succeeds.
My guess is, things that were found are saved in cache, and the script for finding them is not run the second time.
My question is, how can I work around that issue and ensure that both my framework (that does not have suffixes) is found and cmake does not stop generation?
I am generating on MacOS, for Xcode.
Not sure what is an "official" way for assign a list of a single empty extension, but you may assign a list of two empty extensions:
set(CMAKE_FIND_LIBRARY_SUFFIXES ";")
Unlike to empty value, this assignment would pass possible sanity checks like if(CMAKE_FIND_LIBRARY_SUFFIXES), which probably exists in CMake code as it reports about "Error required internal CMake variable not set".

How to ingest property value to cpack-wix without need for running cmake again?

I am using cmake and cpack and wix to build and deploy my project. The installer has some properties that user can enter via GUI or MSI-command-line options.
I set default property values in my CMakeLists.txt using:
set(CPACK_WIX_PROPERTY_<PROPERTY> <value>)
The problem is that if I change these values, I should rerun cmake command before cpack command.
I am looking for a way to change default value of these properties without need for rerunning cmake.
I tried adding additional wxs files using CPACK_WIX_EXTRA_SOURCES or patching generated files with additional xml files using CPACK_WIX_PATCH_FILE, but couldn't find the right code to put in wxs or xml files to accomplish my goal.
I tried The SetProperty command and found out its behavior is not easy to control, I gave up when I saw the user provided values don't replace the initial values and suggested solution at https://web.archive.org/web/20180205001358/http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Unable-to-override-SetProperty-value-with-Edit-Control-value-td7591569.html didn't work. I hope there is a simple way, but even a complex answer using SetProperty is allright.
I am looking for a way to change default value of these properties without need for rerunning cmake.
A script specified in CPACK_PROJECT_CONFIG_FILE variable is the one, which affects on CPack, but which changing doesn't require cmake to re-run. So you may place setting of CPACK_WIX_PROPERTY_<PROPERTY> here: Changing this setting would require only to re-run CPack without re-run cmake on the main project.
Also, when the script specified in CPACK_PROJECT_CONFIG_FILE variable is parsed, CPACK_GENERATOR variable contains the exact CPack generator which is currently processed. This opposites to behavior of the variable inside CMakeLists.txt, when it contains a list of generators.

Setting an MSBuild property to a file version

I'm installing a toolset and I use the $(Registry:Path#Value) syntax to read the path to the compiler executable and set a property containing this value. However, in order to properly set up the search paths that the executable needs, I need to read the file version of this executable. I've seen examples of using a Target to do this and putting a Task in the target that invokes GetAssemblyVersion, but I want something more like a property function, because I want to initialize this before a build has even been run. The user should be able to go into the Project Settings and see the value I've determined as part of their include path. So what I'd really like is something like this:
<Project>
<PropertyGroup>
<CompilerExe>$(Registry:Path#Value)</CompilerExe>
<CompilerVersion>$(GetFileVersion:$(CompilerExe))</CompilerVersion>
</PropertyGroup>
</Project>
Obviously the syntax above doesn't work, but is there any way I can do something like this?

Can I get the GUID generated by CMake for a specific vcproj at cmake time?

Preamble: I am trying to integrate my C# csproj with the rest of our C++ and C++/CLI code-base cmake build. I have received advise against trying to do this, because CMake doesn't co-operate well with .NET in Visual Studio, but after implementing some customizations, I feel that I am very close.
Part of my customization is using the configure_file command to edit the csproj file at CMake time, to customize it depending on the type of build (e.g. x86, x64) that is happening.
The problem is that I use some ProjectReference tags to reference the C++/CLI projects:
<ProjectReference Include="..\..\WrapperProject\WrapperProject.vcproj">
<Project>{7BD6E175-CDD1-4F8D-A3B2-0AC862E62C03}</Project>
<Name>WrapperProject</Name>
</ProjectReference>
... and the GUIDs cannot remain static, since they change for the project whenever the CMake cache is rebuilt (correct me if I'm mistaken).
So what I would like to do is find our at CMake time what GUIDs are planned for these projects and to edit the vcproj file accordingly.
Google tells me that people are able to use 'set_property' to set the GUID, like so:
set_property(CACHE ${target_name}_GUID_CMAKE PROPERTY VALUE ${MY_GUID} )
... but I can't seem to find the getter equivalent. I've tried things like this:
get_property(WRAPPER_GUID CACHE INTERNAL PROPERTY WrapperTargetName_GUID_CMAKE)
... without luck. Your help is appreciated!
After playing around with this more, I realized what Fraser pointed out - that this method wouldn't always work because I can't expect the GUIDs to be available on a fresh run of CMake. So I went the route that I had seen suggested on the CMake mailing list, which is to explicitly set the GUID values myself.
So in the CMakeLists.txt for each C++/CLI wrapper project, I have something like this:
# Set a global cache variable for this project GUID
# The TestAppNet csproj needs this GUID to properly reference this project
set_property(GLOBAL PROPERTY Wrapper_GUID "1897F4D1-E929-444E-9343-00F094113772")
get_property(projectGUID GLOBAL PROPERTY Wrapper_GUID)
MESSAGE( STATUS "Setting project GUID to: ${projectGUID}")
set(Wrapper_GUID_CMAKE "${projectGUID}" CACHE INTERNAL "Project GUID")
And in the C# project CMakeLists.txt, I have this:
get_property(CMAKE_WRAPPER_GUID GLOBAL PROPERTY Wrapper_GUID)
MESSAGE( STATUS "Setting Wrapper GUID to: ${CMAKE_WRAPPER_GUID}" )
... and then the CMAKE_WRAPPER_GUID is used as a variable in the .csproj file that is populated during the configure_file command.
I'm not sure if this is efficient, but it seems to work!
Your syntax is slightly off. You probably meant:
get_property(WRAPPER_GUID CACHE WrapperTargetName_GUID_CMAKE PROPERTY VALUE)
However, this is a relatively convoluted way to get the value. You can just do:
set(WRAPPER_GUID ${WrapperTargetName_GUID_CMAKE})
Finally, this isn't ideal since the GUID isn't available until after the first run of CMake. So for a fresh build tree, you'd have to run CMake twice before this would be usable.
Setting it doesn't seem to work for me, however it can be predicted/re-computed from yourcmake code:
https://github.com/Kitware/CMake/blob/85dc7c763a12366d49ac2dddc53f65d52d675c00/Source/cmGlobalVisualStudio7Generator.cxx#L636-L656
You can use string(UUID) for this in your cmake code:
function(get_target_uuid VARIABLE TARGET)
set(
CMAKE_MSVC_PROJECT_UUID_NAMESPACE
"ee30c4be-5192-4fb0-b335-722a2dffe760"
)
string(
UUID TARGET_UUID
NAMESPACE "${CMAKE_MSVC_PROJET_UUID_NAMESPACE}"
NAME "${CMAKE_BINARY_DIR}|${TARGET}"
TYPE MD5
UPPER
)
set("${VARIABLE}" "${TARGET_UUID}" PARENT_SCOPE)
endfunction()