I am trying to add some custom build commands to my vc2010 project by using ADD_CUSTOM_COMMAND. But:
[1] I just find that CMAKE will automatically insert much more code than I hvae expected.
For example, I want the command exactly to be:
"c:\Some Folder\MyTool.exe" -arg0 -arg1
The corresponding code in CMakeLists.txt is like:
add_custom_command( OUTPUT ${outfile}
COMMAND "c:\Some Folder\MyTool.exe" ARGS "-arg0 -arg1"
# COMMAND "\"c:\Some Folder\MyTool.exe\"" will FAIL to be parsed!
MAIN_DEPENDENCY ${infile}
VERBATIM)
but actually I got:
setlocal
c:\Some Folder\MyTool.exe "-arg0 -arg1"
if %errorlevel% neq 0 goto :cmEnd
:cmEnd
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
:cmErrorLevel
exit /b %1
:cmDone
if %errorlevel% neq 0 goto :VCEnd
This is not what I want. I have also tried the string: COMMAND "\"${MYTOOL_PATH}\" -arg0 -arg1", but CMake just failed to parse it because there is a quote in front of the string.
So it's bad I can't quote the command string because the path c:\Some Folder\MyTool.exe contains spaces.
[2] I also notice CMake will automatically expand my dependency pathes.
If I add to the command DEPENS "$(PATH_MACRO)", I will eventually get the dependency path automatically expanded by CMake: C:\MySolutionDir\$(PATH_MACRO); But I only want $(PATH_MACRO), because I will make sure visual studio understands what $(PATH_MACRO) refers to.
So here is my question:
How can CMake only accept my raw inputs, without auto expanding the path or inserting code I don't expect? I will make sure my inputs will be valid for visual studio. Thanks!
PS. My CMake version: 2.8.10.2. VS version: visual studio 2010 Ultimate
In case this helps someone. I was trying to get binary signing to work as a post-build step using signtool.exe but ONLY for Release builds. Only the uncommented syntax works, none of the others do. I'm kinda at a loss as to why some of the others do not work, but at least I found one that does. There seems to be some strange rules about when literal quotes are generated and when they are not, depending on what is inside the quoted expression. Perhaps someone can explain.
function(my_sign_binary TARGET)
#SET(COMMAND_LINE signtool sign $<TARGET_FILE:${TARGET}>)
add_custom_command(
TARGET ${TARGET}
POST_BUILD
COMMENT "Signing: ${TARGET}"
COMMAND "$<$<CONFIG:Release>:signtool>" "$<$<CONFIG:Release>:sign>" "$<$<CONFIG:Release>:$<TARGET_FILE:${TARGET}>>"
#COMMAND $<$<CONFIG:Release>:signtool.exe sign $<TARGET_FILE:${TARGET}>>
#COMMAND echo 1. signtool sign $<TARGET_FILE:${TARGET}>
#COMMAND echo 2. "$<$<CONFIG:Release>:signtool sign $<TARGET_FILE:${TARGET}>>"
#COMMAND "$<$<CONFIG:Release>:signtool sign $<TARGET_FILE:${TARGET}>>"
#COMMAND "$<$<CONFIG:Release>:signtool>" "$<$<CONFIG:Release>:\ sign\ $<TARGET_FILE:${TARGET}>>"
#COMMAND echo 3. $<$<CONFIG:Release>:"signtool sign $<TARGET_FILE:${TARGET}>">
#COMMAND "echo 4. $<$<CONFIG:Release>:signtool sign $<TARGET_FILE:${TARGET}>>"
#COMMAND echo 5. [$<$<CONFIG:Release>:signtool sign $<TARGET_FILE:${TARGET}>>]
#COMMAND $<$<CONFIG:Release>:signtool sign $<TARGET_FILE:${TARGET}>>
#COMMAND $<$<CONFIG:Release>:${COMMAND_LINE}>
#COMMAND $<$<CONFIG:Release>:COMMAND_LINE>
#COMMAND $<$<CONFIG:Release>:"${COMMAND_LINE}">
#COMMAND $<CONFIG:Release>:signtool sign $<TARGET_FILE:${TARGET}>
#COMMAND echo 8. "${$<$<CONFIG:Release>:COMMAND_LINE>}"
#COMMAND ${"$<$<CONFIG:Release>:COMMAND_LINE>"}
)
endfunction()
For issue 1, try "c:\\Some Folder\\MyTool.exe" -arg0 -arg1. The ARGS parameter isn't required, but the point is to omit the quotes around the -arg0 -arg1.
For issue 2, since $(PATH_MACRO) is not an absolute path, CMake sees it as a path relative to your source directory. The best way to resolve this is probably to use "generator expressions", but without further info on your exact case, I can't provide a better answer.
For info on generator expressions, see the docs for add_custom_command.
Related
I have a CMake script that creates a command string and runs it with execute_process. But, some of the parameters are not getting filled in properly. Is there a way to print the actual command string that is getting executed?
There is a message call just above it which shows what the command should be but when I run that string on the command line, it works fine while the CMake execute_process fails.
Starting from CMake 3.15, execute_process has a COMMAND_ECHO <where> parameter, and there is also the CMAKE_EXECUTE_PROCESS_COMMAND_ECHO variable to set a default behaviour:
COMMAND_ECHO <where>
New in version 3.15.
The command being run will be echo'ed to <where> with <where> being set to one of STDERR, STDOUT or NONE. See the CMAKE_EXECUTE_PROCESS_COMMAND_ECHO variable for a way to control the default behavior when this option is not present.
I have RAR SFX with some programs. Depending on some conditions (command line parameter is something i can do), SFX should either extract to TEMP folder, or the current folder.
It's basicaly new version of the software.
If downloaded from the web, extraction should go into temp folder, and then installation searches for the map where SW is located.
If downloaded from inside the program, then i know the program location relative to download path and extraction should go into current folder...
Any way I can achieve this using RAR SFX?
TNX.
Inside your program you can skip SFX header of file and extract it as regular RAR file in folder yo want.
It need few lints of code or embding Winrar or 7zip liraries.
This batch code show you how we can create an SFX (SelF-eXtracting) protected with a password and with a custom icon too if you want to add them of course
#echo off
Set SFX_Name=TestSFX.exe
Set SfxOptions=SfxOptions.txt
Set AddFile=MyBatchFile.bat
Set Icon=HackooIcon.ico
Set Winrar="%ProgramFiles%\WinRAR\WinRar.exe"
Set ExtractedPath=%tmp%\hackoo
Set Setup=%ExtractedPath%\MyBatchFile.bat
Set Password=hackoo123
(
echo ;The comment below contains SFX script commands
echo Path="%ExtractedPath%"
echo Silent=1
echo OverWrite=1
echo Setup="%Setup%"
)> "%SfxOptions%"
%Winrar% a -c -cfg- -ep1 -idq -m5 -mdg -r -s -sfx -y -iicon"%Icon%" -hp"%Password%" "-z%SfxOptions%" "%SFX_Name%" "%AddFile%"
if errorlevel 1 goto Failure
::del "%~dp0SfxOptions.txt"
goto :EOF
:Failure
::del "%~dp0SfxOptions.txt"
echo.
echo Error on creation of "%~dp0%SFX_Name%"
echo.
pause
For others switchs and commands you can execute this batch to open the help file of Winrar :
#echo off
Set WinrarHelp=%ProgramFiles%\WinRAR\WinRAR.chm
Start "" "%WinrarHelp%"
I want to manage (Upload\Download\Delete) a file on an FTP Server with WinSCP command line.
It says I can use environment variables! I have some text files that have the date in their name.
I just created the variable I want:
Test_%DATE:~10,4%%DATE:~4,2%%DATE:~7,2%.txt
and tested it with Windows echo command. It becomes Test_20140916.txt and that is exactly what I have now.
But when I try to upload that file in WinSCP, I get this error:
winscp> put D:\FTP\Test_%DATE:~10,4%%DATE:~4,2%%DATE:~7,2%.txt
File or folder 'D:\FTP\Test_%DATE:~10,4%%DATE:~4,2%%DATE:~7,2%.txt' does not exist.
System Error. Code: 123.
The filename, directory name, or volume label syntax is incorrect
(A)bort, (R)etry, (S)kip, Ski(p) all:
Any idea how to resolve this issue?
WinSCP supports a timestamp formatting natively:
put D:\FTP\Test_%TIMESTAMP#yyyymmdd%
To explain why your syntax does not work: while WinSCP supports the environment variables in scripting commands, it does support only a basic syntax %NAME%, as documented:
https://winscp.net/eng/docs/scripting#syntax
To achieve, what you need, you have to resolve the value to another variable and refer to that in the WinSCP command:
set STAMP=%DATE:~10,4%%DATE:~4,2%%DATE:~7,2%
winscp.com /script=script.txt
where script.txt can use %STAMP%:
put D:\FTP\Test_%STAMP%
Also note that a value of the %DATE% is locale-specific, so make sure you test your code on the same locale on which you gonna use it. Or even better, use a locale independent wmic os get LocalDateTime:
for /F "usebackq tokens=1,2 delims==" %%i in (`wmic os get LocalDateTime /VALUE 2^>NUL`) do if '.%%i.'=='.LocalDateTime.' set LDT=%%j
set STAMP=%LDT:~0,4%%LDT:~4,2%%LDT:~6,2%
I am trying to write tests for some of my scripts. I am redirecting input from a file that contains input for a specific test case. A few of my scripts use xcopy. What I have noticed is that xcopy drains the redirected input even though I use the /Y option that suppresses prompting for confirmation.
Here's a script to produce this:
#ECHO OFF
SETLOCAL
SET some_info=
SET /p some_info=Please provide info:
ECHO.
ECHO Your input was:%some_info%
xcopy /Y some_existing_file.txt some_other_existing_file.txt
SET some_info=
SET /p some_info=Please provide info:
ECHO.
ECHO Your input was:%some_info%
SET some_info=
SET /p some_info=Please provide info:
ECHO.
ECHO Your input was:%some_info%
ENDLOCAL
and here's the input:
info 1
info 2
info 3
Note that files some_existing_file.txt and some_other_existing_file.txt both exist as their name suggests.
I noticed that copy does not drain redirected input but unfortunately I am using the /EXCLUDE option of xcopy a lot and replacing it with copy will cause many changes to my scripts.
Have you noticed this behaviour of xcopy? Is there a way to avoid it without making significant changes to my scripts? If you have an alternative suggestion on how to automatically test batch scripts please let me know.
This works here:
<nul xcopy /Y some_existing_file.txt some_other_existing_file.txt
I'm running a command using the msbuild "Exec" task. However I do not want the stdio output generated from the command to appear in the console, is there anyway to suppress it?
Maybe something along the lines of using the Exec task to call "cmd.exe" with my command exe is a target , and then using ">" to redirect the output somewhere else. (However I'm unable to get this solution to work).
i.e.
<Exec Command="cmd.exe sqlplus.exe $(someCommandSpecificSettings) < test.txt"/>
Any suggestions to get my example to work or alternatives?
The best way to suppress Standard Output and Standard Error Output from Exec tasks or any task that inherits from ToolTask is to lower the importance of the output. That way if you're debugging your build, these output won't be completely hidden because you're redirecting them to nul.
<Exec Command="sqlplus.exe" StandardOutputImportance="low" StandardErrorImportance="low"/>
Just for your information :
( >) redirect the output to the file you specified after (overwritten if needed)
append the output to the file you specified after (not overwritten)
< redirect the standard INPUT to your command (basically pass the content of the file after to your command)
With your code, you create (once) and replace each time a test.txt file. Instead of using a filename, you can use NUL that means redirect to nowhere. This will not create the file (which could be huge in some case) :
<Exec Command="cmd.exe /c sqlplus.exe $(someCommandSpecificSettings) > NUL"/>
If you want to redirect the errors as well, you use 2> like :
<Exec Command="cmd.exe /c sqlplus.exe $(someCommandSpecificSettings) > NUL 2>errors.txt"/>
Also note that you can redirect the stderr to stdout using 2>&1, thus
> NUL 2>&1
will redirect everything to nowhere.
Hope this clarifies your mind ^^
Ok, figured it out ... cmd.exe required a /c argument to work for what I wanted i.e.:
Also, it should be > instead of <
<Exec Command="cmd.exe /c sqlplus.exe $(someCommandSpecificSettings) > test.txt"/>
Try this:
<Exec Command="cmd.exe sqlplus.exe $(someCommandSpecificSettings) < test.txt >nul"/>