add_custom_target(NSISTest_Preprocess SOURCES precompress.nsi)
add_custom_command(TARGET NSISTest_Preprocess POST_BUILD
COMMAND "${NSIS_PATH}" "...\\precompress.nsi")
The output name of the installer is defined in the nsi script. Now I'd like to simply run the installer. How do I specify what is supposed to happen when I use 'Debug->Start Debugging' or 'Debug->Start Without Debugging' in Visual Studio 2010?
I tried the CreateLaunchers.cmake script, which generates .user files, but I think it only works with add_executable.
I also tried target properties ARCHIVE_OUTPUT_NAME, LIBRARY_OUTPUT_NAME, RUNTIME_OUTPUT_NAME, but none of them have any effect.
The .user settings approach also works for custom targets. You could just add - if the path is known - the installer's .exe as a command the debugger should call with 'Debug->Start Debugging'.
VS2010Test-Debug.vcxproj.user.in
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommand>${_my_installer_path}</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
CMakeLists.txt
...
if (MSVC_VERSION GREATER 1599 AND
NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/NSISTest_Preprocess.vcxproj.user")
file(TO_NATIVE_PATH "[your installer's path goes here]" _my_installer_path)
configure_file(
"VS2010Test-Debug.vcxproj.user.in"
"${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/NSISTest_Preprocess.vcxproj.user"
)
file(
COPY "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/NSISTest_Preprocess.vcxproj.user"
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}"
FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
endif()
Background
I only copy/configure the file when it's not present, because VS does not handle outside changes to .user files very well
I have to make sure all file access rights are set properly, because your SCM may set a read-only flag (which is maintained by configure_file())
References
Setting the Visual Studio Debugger path using CMake
Related
If I run the code analysis in Visual Studio 2022 (on a c++ project) I get a XML and a SARIF file for every code file.
No I try to run the code analysis with MSBuild 2022:
MSBuild.exe solution.sln -p:Configuration=Release /p:RunCodeAnalysis=true
But with this call I only get the code analysis XML files and no SARIF files.
Any idea how to force MSBuild to create the SARIF files?
Try to use following command line:
cl.exe <file/project path> /analyze:autolog:ext .nativecodeanalysis.sarif
Or
cl.exe <file/project path> /analyze:autolog:ext .sarif
Though MSBuild.exe invokes cl.exe to compile, it seems creating a .sarif file is only available for directly using cl.exe and its command.
Here’s the related document: Analysis log options
/analyze:autolog:ext extension
Overrides the default extension of the analysis log files, and uses extension instead. If you use the .sarif extension, the log file uses the SARIF format instead of the default XML format.
https://docs.microsoft.com/en-us/answers/questions/512275/what-to-do-with-static-code-analysis-result-xml-fi.html describes a solution:
Add a Directory.build.props file to your Visual Studio solution:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemDefinitionGroup>
<ClCompile>
<AdditionalOptions>$(ClOptions) %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
</ItemDefinitionGroup>
</Project>
Now I can extend my MSBuild Command line on my CI-Server (TeamCity):
/p:RunCodeAnalysis=true /p:ClOptions="/analyze:log%20MyApp.nativecodeanalysis.combined.sarif" (I had to replace the whitespace with %20).
And one SARIF file is generated, or if you want one SARIF file for every code file:
/p:RunCodeAnalysis=true /p:CaOptions="/analyze:log:format:sarif"
If you want to add additional command line switches you have to separate it with %20:
/p:CaOptions=/analyze:log:format:sarif%20/analyze:log:compilerwarnings
BUT: If I activate Clang-Tidy in my Visual Studio project I get the error CLANGTIDY : error : no such file or directory: '/analyze:log' [clang-diagnostic-error] and CLANGTIDY : error : unable to handle compilation, expected exactly one compiler job in ... - Does someone has an idea about that (except disabling Clang-Tidy)?
So I have a solution with 70ish projects that I updated to use a Directory.build.props file to use a single bin folder to make our CI process cleaner. Works great and now everything is in 1 locaction
BUT the problem now is when I open Visual Studio 2017 it creates a bunch of extra project folders now that NEVER get used. Anyway to disable this? It's just confusing to people and clutters up everyone's dev repo.
Example:
%sourceroot%\bin\release\ (this is where all the projects get happily binplaced)
%sourceroot%\bin\project1Neverused\ (unwanted folders that just clutter my dev box up)
%sourceroot%\bin\project2neverUsed\
%sourceroot%\bin\project1Neverused\
%sourceroot%\bin\project2neverUsed\
Here's my Directory.build.props file:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
<OutputPath>$(SolutionDir)bin\$(Configuration)\$(MSBuildProjectName)</OutputPath>
<OutDir>$(OutputPath)</OutDir>
</PropertyGroup>
</Project>
Now open the sln file in Visual studio and if you look VS will have auto generated those folders even though you haven't built anything yet. I want that to be disabled because it's just generating junk folders that aren't used. Since we use a props file for msbuild to binplace we didn't update each project file from the default of "bin\debug"
Yes, Visual Studio will create those bin/obj folder by default when you create a new project/solution. It seems that there is no direct setting to prevent Visual Studio from generating these folders.
As a workaround, you can try to add a delete task in Directory.build.props file to delete the those folder:
<Target Name="CleanFolder" AfterTargets="Build">
<RemoveDir Directories="$(BaseIntermediateOutputPath)" />
<RemoveDir Directories="$(ProjectDir)bin" />
</Target>
Hope this helps.
I am trying to create a msbuild/VS2010 .targets file for flex, so that I can use .l files in Visual Studio 2010. So far, I have produced this:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<LFiles Include="$(MSBuildProjectDirectory)\**\*.l"/>
</ItemGroup>
<Target Name="Flex"
BeforeTargets="ClCompile"
Inputs="#(LFiles)"
Outputs="#(LFiles->'%(RootDir)%(Directory)%(Filename).c')"
Returns="#(LFiles->'%(RootDir)%(Directory)%(Filename).c')">
<Exec Command="flex.exe "-o%(LFiles.RootDir)%(LFiles.Directory)%(LFiles.Filename).c" "%(LFiles.FullPath)" 2>&1 | sed -e "s/. line \([0-9]\+\)/(\1)/" | sed -e s/\"//g"/>
</Target>
</Project>
I added this file to my project, using the Build Customizations... dialog. I then added my .l file, scan.l, and built the project - scan.l was created in the expected place, suggesting that the file name transformations are working. Next, I added scan.c to the project, and built the project again. The generated .c file compiled correctly, and the project linked. So it seems that things are basically working.
My expectation was that Visual Studio would then invoke flex if the .l file changes. The target's Inputs attribute includes the .l file, and its Outputs attribute includes the .c file, and Visual Studio can check whether the input is newer than the output. But in fact, this doesn't happen. If I just change the .l file and rebuild, Visual Studio tells me everything is up to date.
If I delete the .c file and build the project, the .c file is regenerated, just as I'd expect. But if I just change the .l file and build the project, nothing happens. In fact, in this case, msbuild doesn't even seem to run! If I delete the build log before building, Visual Studio tells me that everything is up to date, and no new build log is produced. This makes it rather hard for me to work out what might be going on.
This is my first go with msbuild, so I am probably doing something wrong. But what?
(N.B. my targets file might fall over with multiple .l files, or suffer from some other flaw(s) unrelated to the dependency checking issue - I am not bothered about any of this at this stage.)
To figure out the fix, I realised I could create a Visual Studio 2008 project with a .rules file, load it into Visual Studio 2010, let Visual Studio 2010 convert it automatically, and examine the result. So I did that.
To fix the problem, add an XML file with the same base name as the targets file. This one will do for this example:
<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:transformCallback="Microsoft.Cpp.Dev10.ConvertPropertyCallback">
<ItemType
Name="Flex"
DisplayName="Flex" />
<FileExtension
Name="*.l"
ContentType="Flex" />
<ContentType
Name="Flex"
DisplayName="Flex"
ItemType="Flex" />
</ProjectSchemaDefinitions>
Next, refer to this file in the ItemGroup section. The .targets file is pretty small so here's the new version in its entirety:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PropertyPageSchema Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml"></PropertyPageSchema>
<LFiles Include="$(MSBuildProjectDirectory)\**\*.l"/>
</ItemGroup>
<Target Name="Flex"
BeforeTargets="ClCompile"
Inputs="#(LFiles)"
Outputs="#(LFiles->'%(RootDir)%(Directory)%(Filename).c')"
Returns="#(LFiles->'%(RootDir)%(Directory)%(Filename).c')">
<Exec Command="flex.exe "-o%(LFiles.RootDir)%(LFiles.Directory)%(LFiles.Filename).c" "%(LFiles.FullPath)" 2>&1 | sed -e "s/. line \([0-9]\+\)/(\1)/" | sed -e s/\"//g"/>
</Target>
</Project>
Now reload the project, and visit the properties for the .l file. Select the new Flex option from the Item Type dropdown. This seems to prod Visual Studio into taking a little more care over the file.
If I have properties defined in my project file like so
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<foo>bar</foo>
</PropertyGroup>
</Project>
I can easily set these properties on the MSBuild command line using /p:foo=newValue.
Is there a way of specifying the property value within the Visual studio (2010) GUI? I have had a look but could not find anything within the project properties pages.
Are you looking for conditional compilation symbols?
In VS2010:
Go to the project properties
Go to the Build tab
Under General you will see a place to define "Conditional compilation symbols".
You can enter "foo=bar" there, and you will get this in your .csproj file:
<Project ...>
<PropertyGroup ...>
<DefineConstants>Foo=bar</DefineConstants>
</PropertyGroup>
</Project>
I found this question when looking for an answer to the same thing: I can easily use /p or environment variables to control things when calling MSBuild on the command line, but how do you do similar in the IDE?
My solution was to add a “user” properties file. That is
<!-- Running from the IDE, you can't simply set properties via /p or environment variables.
So, this local file is read if it exists. It is not checked in to version control; but can contain
settings to be used for your immediate work.
If you make a settings.props.user file, remember DO NOT check it in!
-->
<ImportGroup>
<Import
Condition="exists('$(MSBuildThisFileDirectory)settings.props.user')"
Project="$(MSBuildThisFileDirectory)settings.props.user" />
</ImportGroup>
I can now edit some properties in the file settings.props.user conveniently located in the same directory, and not worry about accidentally checking in funny settings. Even when building in the IDE, it reads the text file anew when building. So, just keep the props.user file open in a text editor and it's handy enough to change on the fly, without an IDE extension.
I am using CMake to generate Visual Studio project files. I want to run the test executable after setting the PATH environment variable so that it is able to load the required dll. I tried as per the discussion at http://www.mail-archive.com/cmake#cmake.org/msg21493.html but it does not work.
Have you used CMake with Visual Studio for this purpose? Please share your experiences.
Also, I find no easy way to debug my CMake script, for example to see what value it assigns to the PATH variable. Setting CMake verbose with CMAKE_VERBOSE_MAKEFILE does not help. How would I go about debugging it myself?
For setting custom project setting in Visual Studio from CMake you can use a XML file as a template which can be configured from CMake to work as the .user file.
At my work we use this to set custom debug parameters.
Check the directory containing the generated .vcxproj files for the user settings in the .user files. Here is a snippet of an example UserTemplate.vcxproj.user file we use.
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioUserFile
ProjectType="Visual C++"
Version="9.00"
ShowAllFiles="false"
>
<Configurations>
<Configuration
Name="Debug|#USERFILE_PLATFORM#"
>
<DebugSettings
Command="#USERFILE_COMMAND_DEBUG#"
WorkingDirectory="#USERFILE_WORKING_DIRECTORY_DEBUG#"
CommandArguments="#USERFILE_COMMAND_ARGUMENTS_DEBUG#"
Attach="false"
DebuggerType="3"
Remote="1"
RemoteMachine="#USERFILE_REMOTE_MACHINE_DEBUG#"
<!-- More settings removed for snippet -->
/>
</Configuration>
<!-- Rest of Configurations -->
Another example of a UserTemplate.vcxproj.user to set the PATH variable, would be:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerEnvironment>PATH=..\Your_path;%PATH%".</LocalDebuggerEnvironment>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
Setting the UserTemplate.vcxproj.user file next to your CMakeLists.txt file, you can inject any needed variables from CMake into the .vcxproj.user file of your builded project.
In CMake you can set the appropiate CMake variables (and add more in the template file if you need them). Next you can do something like this to configure the file.
# Find user and system name
SET(SYSTEM_NAME $ENV{USERDOMAIN} CACHE STRING SystemName)
SET(USER_NAME $ENV{USERNAME} CACHE STRING UserName)
# Configure the template file
SET(USER_FILE ${_projectName}.vcxproj.${SYSTEM_NAME}.${USER_NAME}.user)
SET(OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${USER_FILE})
CONFIGURE_FILE(UserTemplate.vcxproj.user${USER_FILE} #ONLY)
If you don't care about the system and the user name, the following configuration would be enough.
# Configure the template file
SET(USER_FILE ${_projectName}.vcxproj.user)
SET(OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${USER_FILE})
CONFIGURE_FILE(UserTemplate.vcxproj.user ${USER_FILE} #ONLY)
Just spotted this question now. To debug cmake files I use
MESSAGE( STATUS "static text ${variable}" )
I have never had to set the path get my tests to run. Are you using CTest? It looks like the link you are following is used with ctest.
If I was trying to get this to work I would use set_tests_properties explicitly first.
set_tests_properties(SomeTest PROPERTIES ENVIRONMENT "PATH=c:\somedir;c:\otherdir")
Then make it more general.
Cmake has a VS_DEBUGGER_ENVIRONMENT property which can be used to set the custom PATH
https://cmake.org/cmake/help/v3.13/prop_tgt/VS_DEBUGGER_ENVIRONMENT.html
set(MY_PATH "PATH=%PATH%" ${MY_CUSTOM_PATH})
set_target_properties(MyTarget PROPERTIES VS_DEBUGGER_ENVIRONMENT "{MY_PATH}")
Some other useful properties are VS_DEBUGGER_COMMAND_ARGUMENTS, VS_DEBUGGER_WORKING_DIRECTORY.
You can give any options globally with the new VS_USER_PROPS target property (version >= 3.8).
Here is a working example:
CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(SetEnvPathTest)
file(WRITE main.cpp [=[
// http://en.cppreference.com/w/cpp/utility/program/getenv
#include <iostream>
#include <cstdlib>
int main()
{
if(const char* env_p = std::getenv("PATH"))
std::cout << "Your PATH is: " << env_p << '\n';
}
]=])
add_executable(${PROJECT_NAME} main.cpp)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.Cpp.user.props" [=[
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerEnvironment>PATH=C:\Test</LocalDebuggerEnvironment>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerEnvironment>PATH=C:\Test</LocalDebuggerEnvironment>
</PropertyGroup>
</Project>
]=])
set_target_properties(
${PROJECT_NAME}
PROPERTIES
VS_USER_PROPS "${PROJECT_NAME}.Cpp.user.props"
)
References
CMake Issue #8884: Set Visual Studio project "custom environment variables" setting with CMake
set diagnostics:caret from CMakeLists.txt
Here is related CMake feature request report:
http://www.kwwidgets.org/Bug/view.php?id=8884
UPDATE: Solved as per Set Visual Studio project "custom environment variables" setting with CMake - thanks to Florian for the comment below.
Just wanted to point out that a very useful addition
that allows you to set up multiple environment variables as opposed to only one (e.g., only PATH)
is given in this link https://stackoverflow.com/a/40531167/9253113
For example, if in addition to setting PATH you wanted to set another variable OTHERVAR
one would have to modify the line
<LocalDebuggerEnvironment>PATH=C:\Test</LocalDebuggerEnvironment>
to
<LocalDebuggerEnvironment>PATH=C:\Test
OTHERVAR="value of OTHERVAR"</LocalDebuggerEnvironment>
Where the symbol "
" tells the xml parser to introduce the LF character. So multiple variable definitions
are possible if separated by the LF character (also the CR character works but NOT the combination CRLF)
Also notice that there CANNOT be any space between
and the next variable.