MSBuild: Exec command through files in each directory - msbuild

I have a CLI tool to read a text file and generate an output text file.
MyTool.exe inputFile1.txt inputFile2.txt inputFileN.txt -o outputFile.txt
Then I have a directory hierarchy as below
MainDir
SubDir1
File1
File2
SubDir2
File3
File4
SubDirN
FileN
I would like to create a MSBuild project file for another project. Inside this msbuildproj file, I need to execute MyTool.exe for all files in each sub directory and create one output file for each sub directory.
MyTool.exe MainDir\SubDir1\File1 MainDir\SubDir1\File2 -o outputFile1.txt
MyTool.exe MainDir\SubDir2\File3 MainDir\SubDir1\File4 -o outputFile2.txt
MyTool.exe MainDir\SubDirN\FileN -o outputFileN.txt
How to make a loop in MSBuild script to do it?

Related

Create a zip archive with Cmake without parent directory?

When I do this:
add_custom_target(
mystuff
COMMAND ${CMAKE_COMMAND} -E tar "cvf" "${CMAKE_CURRENT_BINARY_DIR}/mystuff.zip" --format=zip -- ${CMAKE_CURRENT_SOURCE_DIR}/stuff/
)
against a directory organized like this:
stuff/
file1.txt
file2.txt
file3.txt
The resulting zip file contains:
stuff/
file1.txt
file2.txt
file3.txt
but I want: (no parent directory)
file1.txt
file2.txt
file3.txt
If I were doing this outside of cmake, I would use the -C argument (change directory)
How to do this with cmake?
You could change the working directory of the tar command, something like this:
add_custom_target(
mystuff
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/stuff"
COMMAND ${CMAKE_COMMAND} -E tar "cvf" "${CMAKE_CURRENT_BINARY_DIR}/mystuff.zip" --format=zip .
)
You could make the whole thing simpler by removing the nested call to CMake, and calling zip directly:
add_custom_target(
mystuff
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/stuff"
COMMAND zip -r "${CMAKE_CURRENT_BINARY_DIR}/mystuff.zip" .
)
(Note: original didn't work, see comment below)
Tell tar to include only the contents of the directory (it will do so recursively, but will leave off the top level).
tar "cvf" "${CMAKE_CURRENT_BINARY_DIR}/mystuff.zip" --format=zip \
-- ${CMAKE_CURRENT_SOURCE_DIR}/stuff/*

Zip creation using CMake with no relative path

I want to bundle the build artifacts into a zip to deliver them on the delivery server. That for I integrated the zip creation into the CMake routine.
# zip the final release files into the build artifact
# call the zipping with 'cmake --build . --target zip' or 'make zip'
string(TIMESTAMP DATE_STRING %Y%m%d)
add_custom_target(zip
COMMAND ${CMAKE_COMMAND} -E tar "cfv" "${PROJECT_NAME}-${PROJECT_VERSION}-${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}-${DATE_STRING}.zip" "--format=zip" "--"
"${PROJECT_SOURCE_DIR}/bin/release/*")
The artifacts are bundeld into the bin/release folder in the ProjectSourceDir.
My problem is, that the zip file has the relative path to the files from my build directory. So all files are located under ../bin/release/ which is not what I want. I want to have the files in the "home folder" of the zip file.
I've found the solution to prepare the zip folder in my build folder, but thats something I think is very unpractical or looks dirty to me.
A WORKING_DIRECTORY can be specified to the add_custom command.
add_custom_target(zip
COMMAND ${CMAKE_COMMAND} -E tar cvf ${PROJECT_SOURCE_DIR}/${PROJECT_NAME}-${PROJECT_VERSION}-${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}-${DATE_STRING}.zip --format=zip .
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/bin/release
)
You don't need all that extra quoting as given in the example.

During build, how to create a directory for a file which is generated by some COMMAND?

I'm writing a custom command in CMake to convert a file to binary format at build time. However, the tool I'm using requires directory for a file to be pre-existed; it doesn't create a directory automatically.
Currently my CMake macro looks like this:
MACRO(ConvertToBinary _name)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_BINARY_DIR}/${_name}.bin
COMMAND ${EXE_DIR}/toBinary -i ${CMAKE_CURRENT_SOURCE_DIR}/${_name} -o ${CMAKE_BINARY_DIR}/${_name}.bin
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_name}
)
ENDMACRO(ConvertToBinary)
This macro doesn't work for _name parameter equal, e.g., to "test/sample.txt", because the tool is run with test/ folder under ${CMAKE_BINARY_DIR} being not existed.
How to create the directory before the tool, generating the file, is run?
I have tried to overcome the problem by pre-creating the file (and directory) with the help of CMake. So the tool will be run with the directory created, and can override the output file. I have tried the following:
MACRO(ConvertToBinary _name)
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_BINARY_DIR}/${_name}.bin
FILE(WRITE ${CMAKE_BINARY_DIR}/${_name}.bin "Dummy")
COMMAND ${EXE_DIR}/toBinary -i ${CMAKE_CURRENT_SOURCE_DIR}/${_name} -o ${CMAKE_BINARY_DIR}/${_name}.bin
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_name}
)
ENDMACRO(ConvertToBinary)
But it did not work. I can't find information on how to create file at build time with CMake, so any help is appreciated.
In CMake you may extract directory component of the file and create this directory.
Below code can be used for a tool, which generates a file but doesn't create directory for it.
# Assume some tool generates file '${file}', but don't create directory for it.
#
# Extract directory component for a file
get_filename_component(_dir ${file} DIRECTORY)
add_custom_command(OUTPUT ${file}
COMMAND ${CMAKE_COMMAND} -E make_directory ${_dir} # Create output directory
COMMAND <tool-which-generates-file> ... ${file}
)
See also that question about ways for create a directory in CMake.

Cannot copy folder in source dir to output dir

I want to copy a folder "obj_files" in my source dir to its output dir with the following code:
ADD_EXECUTABLE(projExec ${files_proj})
add_custom_command(TARGET projExec POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/obj_files $<TARGET_FILE_DIR:projExec>)
but it doesn't work. The "CMakeLists.txt" with above commands lies in a subdirectory to another project, hence the output dir is a subdir to that project's output dir. Is this something to consider when attempting to do what I am trying to? Anyways, the problem is that the directory simply is nowhere to be found in the output dirs of the projects. No error messages when configurating/generating, the folder simply isn't copied.

SSH unzip AND change the filename (or get the filename contained therein)

/usr/bin/curl http://somewebsite.com/foo.zip -o 4232.zip
unzip -o -q -L 4232.zip
chown 508 /home/me/www/inbound/data/??????.xml
rm -f 4232.zip
I am using this SSH script to download a zip file called foo.zip, rename the file to 4232.zip, the extract the contents.
My problem is that the zip file contains a single file whose name is constantly changing. I cannot see a flag for unzip that lets me rename the file(s) inside the zip.
How can I rename the mystery file inside. There is really only ever one file in my immediate project.
-or-
How can I get that filename so I can change ownership and use it in a PHP script that will process it later on...
Any help would be appreciated.
This will tell you the name of the .xml file in the zip
unzip -l z.zip | grep -o '[^/]*\.xml'
If you want to extract and rename the xml file
unzip -p z.zip \*.xml | cat > NEWFILE.xml