# Packaging external projects

**URL:** <https://discourse.slicer.org/t/packaging-external-projects/17664>\
**Category:** Development\
**Tags:** package\
**Created:** [May 17, 2021, 8:39pm UTC](https://discourse.slicer.org/t/packaging-external-projects/17664 "2021-05-17T20:39:33Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [May 17, 2021, 8:39pm UTC](https://discourse.slicer.org/t/packaging-external-projects/17664/1 "2021-05-17T20:39:33Z")

</div>

Hi,

Setup: Ubuntu 20.04, SlicerCAT

I have external projects in SuperBuild subfolder that I can successively compile. After compilation I want to copy their content to SlicerCAT archive (package them or install - I guess it is almost the same)

For example I want to simply copy folder `${CMAKE_BINARY_DIR}/h5geo-install` to `${Slicer_INSTALL_BIN_DIR}` when packaging SlicerCAT. As you noticed I install `h5geo` while building SlicerCAT (this simplifies some things for me now, probably later I will change it so h5geo will be only built but not installed while SlicerCAT build step).

**My attempts were:**  
_1 attempt:_

```auto
install(
  DIRECTORY ${h5geo_ROOT} # h5geo_ROOT points to ${CMAKE_BINARY_DIR}/h5geo-install
  DESTINATION ${Slicer_INSTALL_BIN_DIR}
  )

```

Packaging is done via command:

```auto
cd d/Slicer-build
cpack -B ../../

```

this doesn’t add `h5geo` to `.tar.gz` archive.

_2 attempt:_  
[From here](https://www.slicer.org/wiki/Documentation/Nightly/Developers/FAQ/Extensions#How_to_package_third_party_libraries_.3F) I tried:

```auto
set(CPACK_INSTALL_CMAKE_PROJECTS "${h5geo_ROOT};h5geo;ALL;/") # don't completely understand the syntaxis: 1- parameter is the path to folder; 2- name of project??; 3- copy all components? If I copy directory what should be this 3rd param?

# Add Slicer sources
add_subdirectory(${slicersources_SOURCE_DIR} ${slicersources_BINARY_DIR})

```

This code snippet doesn’t give the result neither.

I see that most of Slicer’s packaging “magic” can be uncovered in `SlicerCPack.cmake`, `SlicerBlockInstall...` and in other SlicerCAT projects like SlicerAstro, AevaSlicer or SlicerSALT but still I have no understanding how it works.

Probably someone could give a little more hints on that.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 18, 2021, 12:41am UTC](https://discourse.slicer.org/t/packaging-external-projects/17664/2 "2021-05-18T00:41:38Z")

</div>

Each library is responsible for installing itself. If your set install directory when you configure h5geo then it will be included in the installation package.

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [May 18, 2021, 8:27pm UTC](https://discourse.slicer.org/t/packaging-external-projects/17664/3 "2021-05-18T20:27:14Z")

</div>

Thank you.

I think I have found a solution how it works with files:

```auto
# Install libraries
include(${Slicer_SOURCE_DIR}/CMake/SlicerFunctionInstallLibrary.cmake)
slicerInstallLibrary( # I think this is somehow similar to CMake `install` function
  FILE ${h5geo_ROOT}/lib/libh5geo.so
  DESTINATION ${Slicer_INSTALL_BIN_DIR}
  COMPONENT RuntimeLibraries
  )

set(CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${h5geo_ROOT};h5geo;ALL;/")

include(${Slicer_SOURCE_DIR}/CMake/SlicerExtensionGenerateConfig.cmake)
include(${Slicer_SOURCE_DIR}/CMake/SlicerExtensionCPack.cmake)

```

Probably some lines are excessive but now I can see that `libh5geo.so` is copied to the bin folder of SlicerCAT archive.

Now I’m looking for a way to copy/install folder because I need to copy Julia to SlicerCAT install dir.

P.S. `slicerInstallLibrary` doesnt accept DIRECTORY (instead of FILE) as a parameter

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [May 19, 2021, 1:41am UTC](https://discourse.slicer.org/t/packaging-external-projects/17664/4 "2021-05-19T01:41:18Z")

</div>

This looks about right.

> [@keri](#):
>
> ```auto
> slicerInstallLibrary( # I think this is somehow similar to CMake `install` function
> FILE ${h5geo_ROOT}/lib/libh5geo.so
> DESTINATION ${Slicer_INSTALL_BIN_DIR}
> COMPONENT RuntimeLibraries
> )
> 
> ```

This will only work on linux. If you don’t add the `.so` then it may work on all platforms.

> [@keri](#):
>
> Now I’m looking for a way to copy/install folder because I need to copy Julia to SlicerCAT install dir.

If your Julia build (or SDK) is set up correctly then all you need is to do is something like `find_package(Julia)` and then install the appropriate Julia target (the target knows where all the libraries, including different build modes, what files to install and where, etc.). If it is not set up correctly then you can either fix it or create the targets manually. If this does not work out (or you don’t want to learn these CMake techniques) then an an easy hack is to just get the file list using CMake file glob command and use that for file copy commands (for the built tree) and file install commands (for the install tree). There are differences in how this works on linux, macos, and windows, so it is quite a learning curve, but CMake is such an important and widely used build system that it is worth the effort.

---

<div class="post-metadata">

**Author:** ![keri](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/keri/32/11618_2.png) [@keri](https://discourse.slicer.org/u/keri)\
**Post date:** [May 19, 2021, 3:27pm UTC](https://discourse.slicer.org/t/packaging-external-projects/17664/5 "2021-05-19T15:27:50Z")

</div>

I’m completely agree with you. Step by step I have some success with cmake. For now I simply copy folder `Julia` to Slicer Install tree. Probably later I will improve that.

I’ve figured out (or almost) how to install folder `Julia` to Slicer install tree:

```auto
install(
  DIRECTORY ${julia_ROOT}/ # '/' in the end is necessary
  DESTINATION ${Slicer_INSTALL_ROOT}/julia
  COMPONENT RuntimeLibraries # 'ALL' instead of `RuntimeLibraries` doesn't work
  )

set(CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_INSTALL_CMAKE_PROJECTS};${julia_ROOT};julia;ALL;/")

```

My main mistake was I didn’t use `COMPONENT` with `RuntimeLibraries` value (I used to keep it empty).

Now my `Julia` folder is copied to Slicer install tree (package) but probably this is not the most correct way to do that as `RuntimeLibraries` should not be applied to a folder with subfolders and different types of files I think.
