noloader / cryptopp-cmake

CMake files for Crypto++ project
BSD 3-Clause "New" or "Revised" License
92 stars 68 forks source link

How To Use? #3

Closed CoryGH closed 5 years ago

CoryGH commented 6 years ago

This appears to be actively maintained, but what do I need to include in my project's CMakeLists.txt to make it work? I'm attempting this on CentOS with the lines:

find_package(CryptoPP REQUIRED)
target_link_libraries(libbiocoin cryptopp-static)

But receive the error:

CMake Error at 3rdparty/src/cryptopp/cryptopp-config.cmake:1 (include):
  include could not find load file:

    /var/www/apps/TeamCity/buildAgent/work/36bdf8bfb90be80c/src/libbiocoin/3rdparty/src/cryptopp/cryptopp-targets.cmake
Call Stack (most recent call first):
  CMakeLists.txt:58 (find_package)

-- Configuring incomplete, errors occurred!

When running cmake -DCMAKE_BUILD_TYPE=Debug in my project directory. The Crypto++ package is installed via the instructions in the readme for cryptopp-cmake in the subdirectory 3rdparty/src/cryptopp/

Any help would be appreciated (and might be worth adding to the readme itself.)

noloader commented 6 years ago

We have a wiki page at Cmake.

If you are a Cmake person and can help move Cmake into a stable state, then please make the pull requests.

CoryGH commented 6 years ago

Sadly I'm a complete novice with CMake, I just started using it because I switched to CLion as an IDE and there's no other option. I'm actually amazed it's this difficult to statically reference a library in it, even when I compile it separately.

noloader commented 6 years ago

Sorry, I have no idea.

Maybe someone on the mailing list can help. The mailing list is located at Crypto++ Users. Otherwise, maybe Stack Overflow can help. There have been several Crypto++ and CLion questions.

CoryGH commented 6 years ago

This was stupidity on my part, I have it linking statically now but the solution is unlikely to ever be relevant to anyone else and it wasn't strictly a CMake issue. I had my CMakeLists.txt set to do some probably very non standard stuff like replicating the source tree and moving/renaming files around to produce the source for the build in some higher-level directories relative to the working directory for different build types and one line in the PRE_BUILD custom commands was causing it to delete the build artifacts, it didn't actually fail to build or link, just threw errors and deleted the build artifact. I still can't get the cmake version of crypto++ to build, but since I can build that manually and include it statically I'm not concerned with it. Sorry for the issue spam and thanks for taking the time to look at it.

mouse07410 commented 6 years ago

In general, once your Crypto+ library has been built and installed, you want to have a file FindCryptoPP.cmake placed somewhere where CMake can find it. Usually it's where other such files (called Modules) live. On my Macports-installed CMake it's /opt/local/share/cmake-3.10/Modules/ directory.

Here are a few excerpts from the file FindOpenSSL.cmake in that directory:

$ cat /opt/local/share/cmake-3.10/Modules/FindOpenSSL.cmake 
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#.rst:
# FindOpenSSL
# -----------
#
# Find the OpenSSL encryption library.
#
# Imported Targets
# ^^^^^^^^^^^^^^^^
#
# This module defines the following :prop_tgt:`IMPORTED` targets:
#
# ``OpenSSL::SSL``
#   The OpenSSL ``ssl`` library, if found.
# ``OpenSSL::Crypto``
#   The OpenSSL ``crypto`` library, if found.
#
# Result Variables
# ^^^^^^^^^^^^^^^^
#
# This module will set the following variables in your project:
#
# ``OPENSSL_FOUND``
#   System has the OpenSSL library.
# ``OPENSSL_INCLUDE_DIR``
#   The OpenSSL include directory.
# ``OPENSSL_CRYPTO_LIBRARY``
#   The OpenSSL crypto library.
# ``OPENSSL_SSL_LIBRARY``
#   The OpenSSL SSL library.
# ``OPENSSL_LIBRARIES``
#   All OpenSSL libraries.
# ``OPENSSL_VERSION``
#   This is set to ``$major.$minor.$revision$patch`` (e.g. ``0.9.8s``).
#
# Hints
# ^^^^^
#
# Set ``OPENSSL_ROOT_DIR`` to the root directory of an OpenSSL installation.
# Set ``OPENSSL_USE_STATIC_LIBS`` to ``TRUE`` to look for static libraries.
# Set ``OPENSSL_MSVC_STATIC_RT`` set ``TRUE`` to choose the MT version of the lib.

if (UNIX)
  find_package(PkgConfig QUIET)
  pkg_check_modules(_OPENSSL QUIET openssl)
endif ()

# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES
if(OPENSSL_USE_STATIC_LIBS)
  set(_openssl_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
  if(WIN32)
    set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
  else()
    set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
  endif()
endif()

f (WIN32)
  # http://www.slproweb.com/products/Win32OpenSSL.html
  set(_OPENSSL_ROOT_HINTS
    ${OPENSSL_ROOT_DIR}
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
    ENV OPENSSL_ROOT_DIR
    )
  file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
  set(_OPENSSL_ROOT_PATHS
    "${_programfiles}/OpenSSL"
    "${_programfiles}/OpenSSL-Win32"
    "${_programfiles}/OpenSSL-Win64"
    "C:/OpenSSL/"
    "C:/OpenSSL-Win32/"
    "C:/OpenSSL-Win64/"
    )
  unset(_programfiles)
else ()
  set(_OPENSSL_ROOT_HINTS
    ${OPENSSL_ROOT_DIR}
    ENV OPENSSL_ROOT_DIR
    )
endif ()

set(_OPENSSL_ROOT_HINTS_AND_PATHS
    HINTS ${_OPENSSL_ROOT_HINTS}
    PATHS ${_OPENSSL_ROOT_PATHS}
    )

find_path(OPENSSL_INCLUDE_DIR
  NAMES
    openssl/ssl.h
  ${_OPENSSL_ROOT_HINTS_AND_PATHS}
  HINTS
    ${_OPENSSL_INCLUDEDIR}
  PATH_SUFFIXES
    include
)
. . . . .
  find_library(OPENSSL_SSL_LIBRARY
    NAMES
      ssl
      ssleay32
      ssleay32MD
    NAMES_PER_DIR
    ${_OPENSSL_ROOT_HINTS_AND_PATHS}
    HINTS
      ${_OPENSSL_LIBDIR}
    PATH_SUFFIXES
      lib
  )

  find_library(OPENSSL_CRYPTO_LIBRARY
    NAMES
      crypto
    NAMES_PER_DIR
    ${_OPENSSL_ROOT_HINTS_AND_PATHS}
    HINTS
      ${_OPENSSL_LIBDIR}
    PATH_SUFFIXES
      lib
  )

  mark_as_advanced(OPENSSL_CRYPTO_LIBRARY OPENSSL_SSL_LIBRARY)
  # compat defines
  set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY})
  set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
. . . . .

We need a similar file for Crypto++ in order for CMake to be able to automatically find and include/use it in other CMake projects.

CoryGH commented 6 years ago

Is there a proper FindCryptoPP.cmake file kicking around somewhere or is that on the to-do list? I tried making one in the course of this progress but ran into lots of errors with it, I ended up just compiling crypto++ as a static library and manually copying the archive produced into my /src/lib/ directory to be linked in.

mouse07410 commented 6 years ago

Right now - no, at least I'm not aware of one. But it is crucial for CMake support to write it, otherwise one could build Crypto++ using CMake, but would not be able to use the result smoothly in other CMake projects.

I know too little of CMake to just write one, but might start the experiment.

I'm re-opening this issue, because it is important to get it actually resolved - aka to add FindCryptoPP.cmake file to this repo.

One caveat: since one can install Crypto++ anywhere, somehow the installation process has to adjust the FindCryptoPP.cmake to make sure it looks in the right places...

CoryGH commented 6 years ago

What are the installation parameters derived from? I think the Find*.cmake can be just stuck alongside the source - at least from fiddling around with it a little while trying to resolve this earlier. I might be able to put some more time into this issue over the weekend but can't guarantee anything, it would be nice to have it just work with CMake without having to recompile crypto++ separately on version changes or for every different platform and manually include them in your source tree then select the appropriate one per platform (which is more of less my "solution" at the moment.)

noloader commented 6 years ago

It looks like we took a stab at this issue back in August 2016 with Issue 249, How to find Crypto++ package using CMake? The notes indicate there is no CMake documentation and the CMake mailing list was closed so we could not join and ask questions.

CoryGH commented 6 years ago

@noloader I opened a stackexchange question in the hopes of getting some guidance on this.

CoryGH commented 6 years ago

One question of note that I have just related to this project (without the FindCryptoPP.cmake aspect,) how would I go about building Crypto++ with CLion? It relies on the CMakeLists.txt to be in the root project directory, so if I follow the install instructions in the readme and add it as a submodule then it ends up in /cryptopp-cmake/ off of the project directory. Is there a way to force it into the project root while still adding it as a module?

noloader commented 6 years ago

Is there a way to force it into the project root while still adding it as a module?

No. Its a Git problem. Also see Setting up a Submodule with the files in PWD? on Stack Overflow.

CMake and Git are two of the worse tools I have ever had the misfortune of working with. The tools have a penchant for making simple tasks difficult to impossible. Its almost like they try to find the hardest way to accomplish a task or workflow.

CoryGH commented 6 years ago

I've actually come to like git a lot. It has some issues when it comes to getting things out of sync (especially since even with things like CLion, Webstorm, etc from JetBrains a commit still only commits to your local repo,) and you have to run secondary tools like GitLab or use GitHub if you want a central repo, but it is much faster and tends to have much smaller repos normally. The project organization is the only serious pain point I have with it, since it really dislikes when you stick a dozen+ (or even a few) projects in one central repo - with commits taking much longer than otherwise as the size of the repo grows. CMake I'm not such a fan of, but CLion uses it and it's my preferred IDE since it works on basically every platform the exact same way and I tend to switch between Windows and FreeBSD daily.

mouse07410 commented 6 years ago

What are the installation parameters derived from?

From CMake variables like CMAKE_INSTALL_BINDIR, CMAKE_INSTALL_LIBDIR, CMAKE_INSTALL_DATAROOTDIR, and (though somehow our CMakeLists.txt does not mention it, which should be corrected!) CMAKE_INSTALL_INCDIR.

The values of these parameters should be in the FindCryptoPP.cmake file, to allow CMake locate the library itself, its include files, etc.

I think the Find*.cmake can be just stuck alongside the source - at least from fiddling around with it a little while trying to resolve this earlier.

Yes, that's exactly where it belongs. For now, when somebody provides it, it will be placed into this repo, alongside with CMakeLists.txt and ilk.

I might be able to put some more time into this issue over the weekend but can't guarantee anything...

Many weekends past, @CoryGH are you still interested and willing to contribute a first cut of FindCryptoPP.cmake?

abdes commented 6 years ago

Here is what I do in my project to simplify the mess of external projects use with CMake. Hope this helps.

  1. Integrate cryptopp-cmake as git submodule
  2. Use cmake module at https://github.com/Crascit/DownloadProject to help in downloading the CryptoPP distro zip (I prefer that to integrating the source as git submodule so I can keep the process working totally offline, but you can do whatever suits you)
  3. Add the following to your root CMakeLists.txt

# CryptoPP
# Original at https://www.cryptopp.com/cryptopp700.zip
# Download googletest
download_project(
        PROJ cryptopp
        URL ${CMAKE_CURRENT_SOURCE_DIR}/third_party/cryptopp/cryptopp700.zip
        URL_HASH SHA256=a4bc939910edd3d29fb819a6fc0dfdc293f686fa62326f61c56d72d0a366ceb0
)

set(CRYPTOPP_CMAKE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/cryptopp-cmake)
set(CRYPTOPP_SRC_DIR ${CMAKE_BINARY_DIR}/cryptopp-src)

# Copy files from cryptopp-cmake to the working sources dir
configure_file(
        ${CRYPTOPP_CMAKE_DIR}/CMakeLists.txt
        ${CRYPTOPP_SRC_DIR}/CMakeLists.txt COPYONLY)
configure_file(
        ${CRYPTOPP_CMAKE_DIR}/cryptopp-config.cmake
        ${CRYPTOPP_SRC_DIR}/cryptopp-config.cmake COPYONLY)

# Let cmake do the rest using the cryptopp-cmake CMakeLists.txt
add_subdirectory(${CMAKE_BINARY_DIR}/cryptopp-src ${CMAKE_BINARY_DIR}/cryptopp-build)

# Add the include directory
include_directories(${CMAKE_BINARY_DIR}/cryptopp-src)

In any module where you need to link to cryptopp, add 'cryptopp-static' or 'cryptopp-shared' in the target_link_library(...). You can of course make this better by creating a variable that contains the proper library depending on your build configuration.

Thanks for the cryptopp-cmake and hope this helps...

noloader commented 6 years ago

@mouse07410,

Did you want to add a FindCryptoPP.cmake file to the repo? If so feel free.

I kind of feel like a FindCryptoPP.cmake should be distributed by the CMake folks and available in /usr/share for folks who want it/need it.

jcfr commented 6 years ago

Since there is already a config file, after installing cryptopp, configuring your project with -Dcryptopp_DIR:PATH=/path/to/where/cryptoconfig/is is all that is needed.

Headed for a flight, I will update the README with some examples shortly.

Jc

On Sat, Jun 30, 2018, 11:13 AM Jeffrey Walton notifications@github.com wrote:

@mouse07410 https://github.com/mouse07410,

Did you want to add a Find_cryptopp file to the repo? If so feel free.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/noloader/cryptopp-cmake/issues/3#issuecomment-401528771, or mute the thread https://github.com/notifications/unsubscribe-auth/AANXo6Wx6YVpz1s0e5Lug_Etj-lmyVlqks5uB0FIgaJpZM4RBdHG .