Issues with DESTDIR support

Hello,

I'm encountering some issues with DESTDIR support.

I'm trying to create an updated Gentoo .ebuild for bro 2.0. Gentoo's
packaging process basically compiles and installs into a sandbox
directory under /var/tmp/portage/blahblahblah, using 'make
DESTDIR=/var/tmp/portage/blahblahblah/image/ install', and then merges
the contents of the sandbox into the real filesystem.

Most of bro's build system supports DESTDIR correctly; lib/, share/, and
bin/ all get populated properly under the sandbox directory. But, it
seems that all config-file-writing code does not. For instance, any
time a cmake_install.cmake file contains a section like:

  if (EXISTS /opt/bro/etc/something.cfg)
      ...
      ... cmake -E compare_files new_file /opt/bro/etc/something.cfg
      if not equal
          configure_file(new_file /opt/bro/etc/something.cfg.example)
  else
      ...
      configure_file(new_file /opt/bro/etc/something.cfg)

I believe the right thing to do there is to leave the 'compare_files'
call alone (looking in the real FS for something.cfg), but then the
configure_file calls ought to write to $ENV{DESTDIR}/...

I've tried manually tweaking CMakeLists.txt, cmake_install.cmake etc
files to make that change, and I get... closer, but not quite. I'm a
cmake n00b.

Any advice, or patches that people have done to package for other
distros with similar requirements would be much appreciated!

Thanks,

Most of bro's build system supports DESTDIR correctly; lib/, share/, and
bin/ all get populated properly under the sandbox directory. But, it
seems that all config-file-writing code does not.

You're right, the InstallPackageConfigFile.cmake script does extra precautionary checks so that user-modified config files don't get clobbered at install time, but, in doing that, it worked around the normal file install process and ends up not respecting DESTDIR.

If you can work from our git repository, I made a change on the "topic/jsiwek/destdir-fix" branch of our "cmake" repository that looks like it fixes the problem. To test it out, you'd do something like:

    git clone --recursive git://bro-ids.org/bro
    cd bro
    for repo in `find -d . -name cmake`; do (cd $repo && git fetch && git checkout topic/jsiwek/destdir-fix); done

And then the usual configure, make, install stuff. Let me know if it works for you and I'll get it merged into the master branch.

+Jon

Sweet! This looks like it's about 99% there: install completes without
error. The main broctl.cfg, broccoli.conf, etc config files are
installed in /etc/.

However, it looks like scripts/site/local*.bro files are installed into
/share/bro/site/

The other scripts/ dir (base/, policy/) contents are installed under
/opt/bro/share/bro/, which makes sense. I'm not sure where the site/
files are supposed to go -- I guess any of /etc/bro/site/,
/var/opt/bro/site/, or even /opt/bro/share/bro/site/ would work.

Thanks,

Sweet! This looks like it's about 99% there: install completes without
error. The main broctl.cfg, broccoli.conf, etc config files are
installed in /etc/.

However, it looks like scripts/site/local*.bro files are installed into
/share/bro/site/

Seems in that change I did yesterday I was mistakenly replacing the install prefix with DESTDIR instead of just prepending to it. I fixed that in the same branch which you can try out by doing this command in your bro repository (assuming it's the same one from yesterday with the branch already checked out):

    for repo in `find . -type d -name cmake`; do (cd $repo && git pull); done

And then try your build/install and let me know if looks alright to you now?

+Jon

I think this is getting closer. But it throws an error at:

  [snip]
  -- Installing: /var/tmp/portage/net-analyzer/bro-2.0.20120309/image/var/opt/bro/spool/scripts
  -- Installing: /var/tmp/portage/net-analyzer/bro-2.0.20120309/image/var/opt/bro/logs
  ACCESS DENIED symlink: /opt/bro/share/broctl/scripts/broctl-config.sh
  -- Installing: /var/tmp/portage/net-analyzer/bro-2.0.20120309/image///opt/bro/etc/broctl.cfg
  -- Installing: /var/tmp/portage/net-analyzer/bro-2.0.20120309/image///opt/bro/etc/networks.cfg
  [snip]

It looks like the command that's failing is:

  /usr/bin/cmake -E create_symlink /var/opt/bro/spool/broctl-config.sh /opt/bro/share/broctl/scripts/broctl-config.sh

That's in ./build/aux/broctl/cmake_install.cmake. When I manually add
$ENV{DESTDIR} as a prefix for the destination and re-merge, it works
cleanly, and I end up with a sane-looking install--except that
/var/opt/bro/spool/broctl-config.sh does not exist, so the symlink at
/opt/bro/share/broctl/scripts/broctl-config.sh is dangling (could be a
side effect of my manual hack?)

Thanks,

Hank

It looks like the command that's failing is:

   /usr/bin/cmake -E create_symlink /var/opt/bro/spool/broctl-config.sh /opt/bro/share/broctl/scripts/broctl-config.sh

Yeah, sorry, there was another place in InstallSymlink.cmake that does that at install-time. I changed that to prepend DESTDIR if it's set. Can you pull from "topic/jsiwek/destdir-fix" again like you did before:

     for repo in `find . -type d -name cmake`; do (cd $repo&& git pull); done

And let me know how it works out for you?

so the symlink at
/opt/bro/share/broctl/scripts/broctl-config.sh is dangling (could be a
side effect of my manual hack?)

That's fine, the file is generated later by `broctl install`.

+Jon

This new version looks perfect. Ship it! =)

Thanks,

Hank