intercreate / ic-cmake

CMake project tools for embedded systems projects
Apache License 2.0
2 stars 0 forks source link

Zipped files have issues opening on Windows #3

Closed swoisz closed 1 week ago

swoisz commented 3 weeks ago

An archive is made with this tool (.zip) and it opens/extracts just fine in Linux.

Windows extractor and 7zip don't like the file. Windows refuses to work with it, and 7zip never completes extraction.

Fix

Notes

Could we use gzip instead of tar? Could we ensure characters like '+' don't show up in the filename?

JPHutchins commented 3 weeks ago

Let's consider updating to https://cmake.org/cmake/help/latest/command/file.html#archiving

Would need a custom target.

The + is the symbol for git dirty. Could replace with something else - commonly it is -dirty.

But I think that the + character is fine.

JPHutchins commented 3 weeks ago

I'm not sure how to use the file command within an add_custom_command or target:

https://github.com/intercreate/ic-cmake/blob/2f90670080d9ea2b0dfd8d84608c21e1f0ff94e8/src/ic_bundle.cmake#L109-L119

JPHutchins commented 3 weeks ago

OK ChatGPT has an idea:

To use the file(ARCHIVE_CREATE) command within a custom command or target in CMake to create a ZIP file after certain dependencies are built, you need to follow these steps:

Define the Custom Command: Create a custom command to run file(ARCHIVE_CREATE) that depends on the target or files you want to archive.

Add Dependencies: Ensure that the custom command or target is executed after your dependencies are built by specifying the correct dependencies.

Here’s how you can do it:

Step-by-Step Instructions Define the Custom Command: Use the file(ARCHIVE_CREATE) command in a custom command to create the ZIP file. Since file(ARCHIVE_CREATE) is not directly executable from a command line, it should be used within a CMake script.

Create a CMake Script: Create a CMake script file (e.g., create_archive.cmake) that will use the file(ARCHIVE_CREATE) command.

cmake Copy code

create_archive.cmake

file(ARCHIVE_CREATE ${CMAKE_BINARY_DIR}/output.zip FILES ${CMAKE_BINARY_DIR}/artifact1 ${CMAKE_BINARY_DIR}/artifact2

Add more files or directories as needed

) Define a Custom Target: Define a custom target in your CMakeLists.txt that will execute the create_archive.cmake script after the required dependencies are built.

cmake Copy code

CMakeLists.txt

add_custom_target(create_zip ALL COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/create_archive.cmake DEPENDS my_target1 my_target2 COMMENT "Creating ZIP archive after building dependencies" ) COMMAND: Specifies the command to run, which is the CMake script in this case. DEPENDS: Lists the targets or files that must be built or available before this custom target runs. ALL: Makes this custom target part of the default build. Ensure Dependencies Are Built First: Make sure the custom target (create_zip in this case) has the correct dependencies so that it runs after those dependencies are complete.

cmake Copy code add_dependencies(create_zip my_target1 my_target2) This will ensure that create_zip is built only after my_target1 and my_target2 are built.

Example in Context Here’s a complete example of how it might look in your CMakeLists.txt:

cmake Copy code

Define your executable or library targets

add_executable(my_target1 src1.cpp) add_library(my_target2 src2.cpp)

Custom target to create a ZIP file

add_custom_target(create_zip ALL COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/create_archive.cmake DEPENDS my_target1 my_target2 COMMENT "Creating ZIP archive after building dependencies" )

Ensure that create_zip target is built after my_target1 and my_target2

add_dependencies(create_zip my_target1 my_target2) In this setup:

my_target1 and my_target2 are your main build targets. The create_zip target runs the create_archive.cmake script to create the ZIP file after my_target1 and my_target2 are built. Notes Script Path: Adjust the path to create_archive.cmake as necessary. Files/Directories: Modify the file(ARCHIVE_CREATE) command parameters to include the correct files or directories. This approach allows you to create ZIP archives as part of your build process, ensuring that all required artifacts are included and that the process runs at the appropriate time.

JPHutchins commented 3 weeks ago

But it will need args:

To pass arguments to a CMake script (like create_archive.cmake) from within a custom_command or custom_target, you can use -D options to define CMake variables that are accessible within the script. Here’s how you can do it:

Steps to Pass Arguments Modify Your CMake Script to Accept Arguments: Update create_archive.cmake to accept arguments passed from the command line. You’ll use the CMAKE_CACHE_MAJOR_VERSION or CMAKE_CACHE_MINOR_VERSION approach to read the arguments.

cmake Copy code

create_archive.cmake

Arguments: ${SOURCE_DIR} ${ARCHIVE_NAME}

set(SOURCE_DIR ${SOURCE_DIR} CACHE STRING "Source directory for archiving") set(ARCHIVE_NAME ${ARCHIVE_NAME} CACHE STRING "Name of the archive file")

file(ARCHIVE_CREATE ${ARCHIVE_NAME} DIRECTORY ${SOURCE_DIR} ) Define Your Custom Command or Target with Arguments: Use add_custom_target or add_custom_command and pass the arguments using -D options.

cmake Copy code

CMakeLists.txt

Define your executable or library targets

add_executable(my_target1 src1.cpp) add_library(my_target2 src2.cpp)

Custom target to create a ZIP file with arguments

add_custom_target(create_zip ALL COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/create_archive.cmake -D SOURCE_DIR=${CMAKE_BINARY_DIR}/my_artifacts -D ARCHIVE_NAME=${CMAKE_BINARY_DIR}/output.zip DEPENDS my_target1 my_target2 COMMENT "Creating ZIP archive after building dependencies" )

Ensure that create_zip target is built after my_target1 and my_target2

add_dependencies(create_zip my_target1 my_target2) Explanation -D Option: The -D option is used to pass arguments to the script. These are set as CMake cache variables, which are accessible within your create_archive.cmake script. COMMAND: Specifies the command to run, including any options or arguments. DEPENDS: Ensures that the custom target will only run after the specified targets have been built. Full Example Here’s a complete example incorporating the steps mentioned:

create_archive.cmake:

cmake Copy code

create_archive.cmake

Variables from command line

set(SOURCE_DIR ${SOURCE_DIR} CACHE STRING "Source directory for archiving") set(ARCHIVE_NAME ${ARCHIVE_NAME} CACHE STRING "Name of the archive file")

message(STATUS "Creating archive from ${SOURCE_DIR} into ${ARCHIVE_NAME}")

file(ARCHIVE_CREATE ${ARCHIVE_NAME} DIRECTORY ${SOURCE_DIR} ) CMakeLists.txt:

cmake Copy code

Define your executable or library targets

add_executable(my_target1 src1.cpp) add_library(my_target2 src2.cpp)

Custom target to create a ZIP file with arguments

add_custom_target(create_zip ALL COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/create_archive.cmake -D SOURCE_DIR=${CMAKE_BINARY_DIR}/my_artifacts -D ARCHIVE_NAME=${CMAKE_BINARY_DIR}/output.zip DEPENDS my_target1 my_target2 COMMENT "Creating ZIP archive after building dependencies" )

Ensure that create_zip target is built after my_target1 and my_target2

add_dependencies(create_zip my_target1 my_target2) Notes Cache Variables: Using CACHE STRING in create_archive.cmake allows you to set default values and check if arguments are passed correctly. Variable Expansion: Ensure that the variables are properly expanded and used in the script. By following these steps, you can effectively pass arguments to your CMake script and control the behavior of custom commands or targets within your build process.

JPHutchins commented 1 week ago

This appears to be resolved by adding the --format=zip option:

    add_custom_command(
        OUTPUT "${_FULL_NAME}.zip"
        COMMAND ${CMAKE_COMMAND} -E tar cf "${_FULL_NAME}.zip" --format=zip "${_FULL_NAME}"
        DEPENDS ${artifact_list}
    )