Using find_package() portably?

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Using find_package() portably?

Carsten Fuchs
Dear group,

I'm new to CMake and read all related tutorials that I could find and
the Mastering CMake book (I didn't get very far) and watched Daniel
Pfeifer's talk. Unfortunately, I'm afraid that I still cannot figure out
a couple of apparently simple things, especially in today's "best
practices" style.

Please consider:

     find_package(JPEG REQUIRED)

At first, this didn't work for me under Ubuntu Linux, because I didn't
have the libjpeg-dev package installed. The error message was:

CMake Error at
/usr/share/cmake-3.9/Modules/FindPackageHandleStandardArgs.cmake:137
(message):
   Could NOT find JPEG (missing: JPEG_LIBRARY JPEG_INCLUDE_DIR)
Call Stack (most recent call first):
   /usr/share/cmake-3.9/Modules/FindPackageHandleStandardArgs.cmake:377
(_FPHSA_FAILURE_MESSAGE)
   /usr/share/cmake-3.9/Modules/FindJPEG.cmake:30
(FIND_PACKAGE_HANDLE_STANDARD_ARGS)
   Libs/CMakeLists.txt:5 (find_package)

Well, I provoked this intentionally for learning and testing, but if I
hadn't been prepared, from the error message alone I would not have
known how to proceed. `sudo apt install libjepg-dev` fixed the problem.

Now I'm under Windows, Visual Studio Community 2017. Same error message,
and obviously no solution as easy as `sudo apt ...`.
It's quite clear that I have to add the libjpeg source code as a
subfolder to my project and compile it as part of the main project. But,
starting with the above `find_package(JPEG REQUIRED)`, how is this
properly done?

Generalizing my question:

I started with `find_package(JPEG REQUIRED)` as shown above in order to
the find the JPEG library that comes preinstalled with the system.
How do I deal with the following scenarios?

   - libjpeg is theoretically available, but just not installed in the
system (that is, `sudo apt install libjpeg-dev` would help)?

   - libjpeg is available in the system, but the version is too new or
too old?

   - libjpeg is not available in the system at all (e.g. Windows)?

   - As a fallback, in the case that any of the above checks is
negative, it seems that there is no alternative but to ship and compile
a copy of libjpeg along with my project: How is this properly expressed
in my project's CMakeLists.txt? Daniel mentioned something about the
behavior of `find_package()` in his talk, but I'm afraid that I still
cannot come up with a proper solution.

Best regards,
Carsten

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Konstantin Tokarev


> Dear group,
>
> I'm new to CMake and read all related tutorials that I could find and
> the Mastering CMake book (I didn't get very far) and watched Daniel
> Pfeifer's talk. Unfortunately, I'm afraid that I still cannot figure out
> a couple of apparently simple things, especially in today's "best
> practices" style.
>
> Please consider:
>
> find_package(JPEG REQUIRED)
>
> At first, this didn't work for me under Ubuntu Linux, because I didn't
> have the libjpeg-dev package installed. The error message was:
>
> CMake Error at
> /usr/share/cmake-3.9/Modules/FindPackageHandleStandardArgs.cmake:137
> (message):
> Could NOT find JPEG (missing: JPEG_LIBRARY JPEG_INCLUDE_DIR)
> Call Stack (most recent call first):
> /usr/share/cmake-3.9/Modules/FindPackageHandleStandardArgs.cmake:377
> (_FPHSA_FAILURE_MESSAGE)
> /usr/share/cmake-3.9/Modules/FindJPEG.cmake:30
> (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
> Libs/CMakeLists.txt:5 (find_package)
>
> Well, I provoked this intentionally for learning and testing, but if I
> hadn't been prepared, from the error message alone I would not have
> known how to proceed. `sudo apt install libjepg-dev` fixed the problem.
>
> Now I'm under Windows, Visual Studio Community 2017. Same error message,
> and obviously no solution as easy as `sudo apt ...`.
> It's quite clear that I have to add the libjpeg source code as a
> subfolder to my project and compile it as part of the main project. But,
> starting with the above `find_package(JPEG REQUIRED)`, how is this
> properly done?
>
> Generalizing my question:
>
> I started with `find_package(JPEG REQUIRED)` as shown above in order to
> the find the JPEG library that comes preinstalled with the system.
> How do I deal with the following scenarios?
>
> - libjpeg is theoretically available, but just not installed in the
> system (that is, `sudo apt install libjpeg-dev` would help)?
>
> - libjpeg is available in the system, but the version is too new or
> too old?
>
> - libjpeg is not available in the system at all (e.g. Windows)?
>
> - As a fallback, in the case that any of the above checks is
> negative, it seems that there is no alternative but to ship and compile
> a copy of libjpeg along with my project: How is this properly expressed
> in my project's CMakeLists.txt? Daniel mentioned something about the
> behavior of `find_package()` in his talk, but I'm afraid that I still
> cannot come up with a proper solution.

find_package() allows you to use external libraries (or other kinds of files for that matter)
which are not shipped with your source code. It knows nothing about how to install the
missing dependencies, or if this is possible at all (usually possible, because you can
compile dependencies from sources and maybe even share resulting binaries with other
developers). Instead, you can

1) add instruction how to install dependencies
2) use hand-made script or more complex solution to automate dependency installation, or
3) avoid using find_package() st all

>
> Best regards,
> Carsten
>
> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> http://public.kitware.com/mailman/listinfo/cmake
--
Regards,
Konstantin
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Johannes Zarl-Zierl
Hi,

I thought you might want some context for the suggestions:

On Dienstag, 21. November 2017 11:45:43 CET Konstantin Tokarev wrote:
> 1) add instruction how to install dependencies

This is what many/most projects do, and it works reasonably well.
Advantages:
 - You don't clutter your project with dependencies
 - People on each platform already know how to install dependencies
 - You don't complicate things for package maintainers
Disadvantages:
 - No automatic dependency resolution

> 2) use hand-made script or more complex solution to automate dependency
> installation, or

Hand-made scripts are often a maintenance nightmare and hard to get right for
all platforms. The One True Way(TM) would be a so-called "super-build", i.e. a
CMake project that uses external_project() to build your project along with
its dependencies.

> 3) avoid using find_package() st all

That's the first time I've heard that suggestion. I'm not sure if this will
ease your pain ;-)

4) Shipping the dependency with your project (not using external_project)
This can sometimes be useful, but you should carefully consider the
implications beforehand to see if it's worth it for your project. As a rule of
thumb: don't do this if the dependency is readily available and/or big.

Cheers,
  Johannes



--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Konstantin Tokarev


21.11.2017, 13:45, "Johannes Zarl-Zierl" <[hidden email]>:

> Hi,
>
> I thought you might want some context for the suggestions:
>
> On Dienstag, 21. November 2017 11:45:43 CET Konstantin Tokarev wrote:
>>  1) add instruction how to install dependencies
>
> This is what many/most projects do, and it works reasonably well.
> Advantages:
>  - You don't clutter your project with dependencies
>  - People on each platform already know how to install dependencies
>  - You don't complicate things for package maintainers
> Disadvantages:
>  - No automatic dependency resolution
>
>>  2) use hand-made script or more complex solution to automate dependency
>>  installation, or
>
> Hand-made scripts are often a maintenance nightmare and hard to get right for
> all platforms. The One True Way(TM) would be a so-called "super-build", i.e. a
> CMake project that uses external_project() to build your project along with
> its dependencies.

FWIW I've seen many projects that provide scripts or one-liners how to install all
dependencies on popular systems, and if things are readily available or otherwise pre-built
and downloadable from central place, it's not hard to maintain, at least when number of
dependencies is small

Examples:

1. (Not related to cmake, just to show idea):
https://wiki.qt.io/Building_Qt_5_from_Git#Linux.2FX11
- lists packages which you need to install on different distros on wiki page

2. https://trac.webkit.org/browser/webkit/trunk/Tools/gtk/install-dependencies
- similar thing but automated

3. https://trac.webkit.org/browser/webkit/trunk/Tools/Scripts/update-webkit-wincairo-libs.py
- downloads and unpacks zip file with all dependencies into fixed location

>
>>  3) avoid using find_package() st all
>
> That's the first time I've heard that suggestion. I'm not sure if this will
> ease your pain ;-)

I've meant by using things like ExternalProject, or from your point 4, or when
using other metabuilders. When all dependencies are in known locations,
you don't really need to use find_package anymore.

Though It may be handy though if you allow building with both external and
internal dependencies, e.g. if you develop open source project distributors
will be reluctant to include it if it can use bundled dependencies only.

>
> 4) Shipping the dependency with your project (not using external_project)
> This can sometimes be useful, but you should carefully consider the
> implications beforehand to see if it's worth it for your project. As a rule of
> thumb: don't do this if the dependency is readily available and/or big.
>
> Cheers,
>   Johannes
>
> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> http://public.kitware.com/mailman/listinfo/cmake

--
Regards,
Konstantin
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

R0b0t1
Hello friends!

The points brought up are good. However, I have some experience with
CMake's edge cases (due to using Gentoo) so I feel like I should give
my opinion on some of the solutions. The solutions are good, I just
think it is important to indicate that building truly cross platform
code with CMake still seems to be an open problem.

Specifically, if anyone has anything to add on how to use CMake to
find Windows dependencies, I am looking for help in that area.


On Tue, Nov 21, 2017 at 5:36 AM, Konstantin Tokarev <[hidden email]> wrote:

>
>
> 21.11.2017, 13:45, "Johannes Zarl-Zierl" <[hidden email]>:
>> Hi,
>>
>> I thought you might want some context for the suggestions:
>>
>> On Dienstag, 21. November 2017 11:45:43 CET Konstantin Tokarev wrote:
>>>  1) add instruction how to install dependencies
>>
>> This is what many/most projects do, and it works reasonably well.
>> Advantages:
>>  - You don't clutter your project with dependencies
>>  - People on each platform already know how to install dependencies
>>  - You don't complicate things for package maintainers
>> Disadvantages:
>>  - No automatic dependency resolution
>>

This is really the best solution on Unix-based operating systems and
will work in the vast majority of cases. The one sticking point is
that most FOSS libraries are not distributed by installer for Windows
anymore, and it is extremely likely you will need to bundle your
dependencies with your project when targeting Windows.

Also, sometimes fringe distributions will not have their library
install locations in the paths checked by CMake. Usually they will
have pkg-config configured properly, and you can find the libraries
and headers that way.

>>>  2) use hand-made script or more complex solution to automate dependency
>>>  installation, or
>>
>> Hand-made scripts are often a maintenance nightmare and hard to get right for
>> all platforms. The One True Way(TM) would be a so-called "super-build", i.e. a
>> CMake project that uses external_project() to build your project along with
>> its dependencies.
>
> FWIW I've seen many projects that provide scripts or one-liners how to install all
> dependencies on popular systems, and if things are readily available or otherwise pre-built
> and downloadable from central place, it's not hard to maintain, at least when number of
> dependencies is small
>

>>
>>>  3) avoid using find_package() st all
>>
>> That's the first time I've heard that suggestion. I'm not sure if this will
>> ease your pain ;-)
>
> I've meant by using things like ExternalProject, or from your point 4, or when
> using other metabuilders. When all dependencies are in known locations,
> you don't really need to use find_package anymore.
>
> Though It may be handy though if you allow building with both external and
> internal dependencies, e.g. if you develop open source project distributors
> will be reluctant to include it if it can use bundled dependencies only.
>

Using ExternalProject and a dependency fetching script suffer from the
same problem. It is very easy to implement these things insecurely,
and it makes your software hard to package for Linux distributions.
When I see a trendy new project that prominently features a "curl |
sh" line on its webpage I shudder and, try as I might, I usually write
it off in my mind. Besides those lines sometimes not having "https://"
in them, installing software outside of your package manager will
eventually lead to a slew of problems (developers that focus on one or
two projects may never experience those problems, but that is almost
entirely luck).

I think there are two major examples I can give:

1) Haskell's Cabal would fetch code (some immediately executed but
also the packages) over HTTP with no authentication, and that code
would often run as root. This has only recently been fixed, but I
still feel like I need to double check myself.

2) Sage Math bundles, I think, 80 pieces of software with it, and has
its own package management system. It builds GCC to build itself! For
some of the problems that this causes, see
https://bugs.gentoo.org/201321.

I do recognize that sometimes distributions simply won't have the
libraries you need. In that case, I recommend leaving it to the user
to find a way to get those libraries. Personally I install them to
~/.local and add them to the search paths, but this is hard to do with
CMake. Sometimes users will find newer libraries in a backports
repository.

>>
>> 4) Shipping the dependency with your project (not using external_project)
>> This can sometimes be useful, but you should carefully consider the
>> implications beforehand to see if it's worth it for your project. As a rule of
>> thumb: don't do this if the dependency is readily available and/or big.
>>

I dislike doing this on principle but it's pretty common for Windows.
Sticking a deps/ directory in your repository with precompiled
libraries and the header files is an easy way to reduce the burden for
potential contributors. I have also seen instructions for building
packages and specifying their location manually.

Should you do this, GPG-signing your commits would be an especially good idea.

Cheers,
     R0b0t1
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Konstantin Tokarev

> Using ExternalProject and a dependency fetching script suffer from the
> same problem. It is very easy to implement these things insecurely,
> and it makes your software hard to package for Linux distributions.
> When I see a trendy new project that prominently features a "curl |
> sh" line on its webpage I shudder and, try as I might, I usually write
> it off in my mind. Besides those lines sometimes not having "https://"
> in them,

You should check sha256 of all downloaded files. It really guarantees that
files were not tampered, unlike that "s" letter in the URL after "http" which
only checks that peer's TLS certificate looks okay.


> installing software outside of your package manager will
> eventually lead to a slew of problems (developers that focus on one or
> two projects may never experience those problems, but that is almost
> entirely luck).

This is not the case if done carefully, and is not relevant at all if dependencies
are not installed into system location

--
Regards,
Konstantin
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Carsten Fuchs
Hi all,

thanks to you all for your replies!

Concluding from your replies, it seems that the following approach for
each external dependency implements a good(?) solution:


find_package(JPEG)   # without "REQUIRED"

if (NOT JPEG_FOUND)
     # Optionally, under Linux only:
     # Stop with custom error message that explains how to install libjpeg.
     # Or ask if alternatively the shipped library should be used.
     # This complements the installation instructions in the user docs.
     ...   # TODO!

     # Proceed with the shipped copy of libjpeg:
     # Always under Windows and possibly under Linux as outlined above.
     # Always in source code form, compiling here; not pre-made binaries.
     # (This approach is my personal preference over the other options
     # that have been suggested.)
     add_subdirectory(../ExtLibs/libjpeg ../ExtLibs/libjpeg)

     ...   # see below
endif()

# How does this work in case `NOT JPEG_FOUND` above?
target_link_libraries(main_program ${JPEG_LIBRARIES})


That is, follow-up question: near the "..." above, we have got a target
"libjpeg", but how do I get the variables JPEG_INCLUDES, JPEG_LIBRARIES
etc. that `find_package(JPEG)` normally provides so that the last line
with the `target_link_libraries()` works?
I guess that defining them in `../ExtLibs/libjpeg/CMakeLists.txt` is wrong.

It seems to me that the 2017 talks by Mathieu Roperts and Daniel Pfeifer
(starting at slide 53, see especially slide 64 at
https://www.slideshare.net/DanielPfeifer1/effective-cmake) suggest that
this is how the modern, modular CMake is supposed to work?

Best regards,
Carsten
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Konstantin Tokarev


22.11.2017, 13:37, "Carsten Fuchs" <[hidden email]>:

> Hi all,
>
> thanks to you all for your replies!
>
> Concluding from your replies, it seems that the following approach for
> each external dependency implements a good(?) solution:
>
> find_package(JPEG) # without "REQUIRED"
>
> if (NOT JPEG_FOUND)
>      # Optionally, under Linux only:
>      # Stop with custom error message that explains how to install libjpeg.
>      # Or ask if alternatively the shipped library should be used.
>      # This complements the installation instructions in the user docs.
>      ... # TODO!
>
>      # Proceed with the shipped copy of libjpeg:
>      # Always under Windows

Note that there are package systems on Windows too, e.g. VCPKG or MSYS2.

Also there are a few packages which can be found by CMake by using registry
keys provided by their installers (not the case for libjpeg)


> and possibly under Linux as outlined above.
>      # Always in source code form, compiling here; not pre-made binaries.
>      # (This approach is my personal preference over the other options
>      # that have been suggested.)
>      add_subdirectory(../ExtLibs/libjpeg ../ExtLibs/libjpeg)
>
>      ... # see below
> endif()
>
> # How does this work in case `NOT JPEG_FOUND` above?
> target_link_libraries(main_program ${JPEG_LIBRARIES})
>
> That is, follow-up question: near the "..." above, we have got a target
> "libjpeg", but how do I get the variables JPEG_INCLUDES, JPEG_LIBRARIES
> etc. that `find_package(JPEG)` normally provides so that the last line
> with the `target_link_libraries()` works?
> I guess that defining them in `../ExtLibs/libjpeg/CMakeLists.txt` is wrong.
>
> It seems to me that the 2017 talks by Mathieu Roperts and Daniel Pfeifer
> (starting at slide 53, see especially slide 64 at
> https://www.slideshare.net/DanielPfeifer1/effective-cmake) suggest that
> this is how the modern, modular CMake is supposed to work?
>
> Best regards,
> Carsten
> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> http://public.kitware.com/mailman/listinfo/cmake

--
Regards,
Konstantin
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Johannes Zarl-Zierl
In reply to this post by Carsten Fuchs
On Mittwoch, 22. November 2017 11:32:22 CET Carsten Fuchs wrote:
> That is, follow-up question: near the "..." above, we have got a target
> "libjpeg", but how do I get the variables JPEG_INCLUDES, JPEG_LIBRARIES
> etc. that `find_package(JPEG)` normally provides so that the last line
> with the `target_link_libraries()` works?
> I guess that defining them in `../ExtLibs/libjpeg/CMakeLists.txt` is wrong.

You've found an ugly corner in CMake ;-)

The problem in this specific case is that CMake ships with a FindJPEG module
that does not define modern import libs, but uses the old way of defining
<PACKAGE>_LIBRARIES and <PACKAGE>_INCLUDE_DIRS.
IMO this highlights one of the main problems with find modules: nobody really
maintains them.

If JPEG had proper imported targets, your code could look like this:

find_package(JPEG)   # without "REQUIRED"

if (NOT JPEG_FOUND)
   ...
   # Proceed with the shipped copy of libjpeg:
   add_subdirectory(../ExtLibs/libjpeg ../ExtLibs/libjpeg)
endif()

target_link_libraries(main_program JPEG::JPEG)

You just have to make sure that your shipped libjpeg creates the proper
namespaced target:
add_library(JPEG ...)
add_library(JPEG::JPEG ALIAS JPEG)

HTH,
  Johannes

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Carsten Fuchs
Hello Johannes,

Am 2017-11-22 um 12:03 schrieb Johannes Zarl-Zierl:

> The problem in this specific case is that CMake ships with a FindJPEG module
> that does not define modern import libs, but uses the old way of defining
> <PACKAGE>_LIBRARIES and <PACKAGE>_INCLUDE_DIRS.
> IMO this highlights one of the main problems with find modules: nobody really
> maintains them.
>
> If JPEG had proper imported targets, your code could look like this:
> [...]
> You just have to make sure that your shipped libjpeg creates the proper
> namespaced target:
> add_library(JPEG ...)
> add_library(JPEG::JPEG ALIAS JPEG)

Thanks for your reply, but how can I proceed from here?

In order to be able to write in the parent script something that works
in either case, that is,

target_link_libraries(main_program <either JPEG::JPEG or ${JPEG...} or ???>)

it seems that I either

   - have to make a copy of FindJPEG.cmake, customize it to define
target JPEG::JEPG and ship it along with my project,

   - or write my `../ExtLibs/libjpeg/CMakeLists.txt` so that it globally
defines JPEG_LIBRARIES and JPEG_INCLUDE_DIRS

Is that right?

Best regards,
Carsten
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Johannes Zarl-Zierl
Hello Carsten,

On Samstag, 25. November 2017 11:46:44 CET Carsten Fuchs wrote:
> Thanks for your reply, but how can I proceed from here?
>
> In order to be able to write in the parent script something that works
> in either case, that is,
>
> target_link_libraries(main_program <either JPEG::JPEG or ${JPEG...} or ???>)

Well, that's one way, but that doesn't really provide any benefit above the
original solution (i.e. just define the JPEG_INCLUDES and JPEG_LIBRARIES
variables accordingly).

> it seems that I either
>
>    - have to make a copy of FindJPEG.cmake, customize it to define
> target JPEG::JEPG and ship it along with my project,

Either that or you define it yourself:
find_package(JPEG)
if (JPEG_FOUND)
 add_library(JPEG::JPEG UNKNOWN IMPORTED)
 set_property(
  TARGET JPEG::JPEG
  PROPERTY IMPORTED_LOCATION ${JPEG_LIBRARIES}
  )
 set_property(
  TARGET JPEG::JPEG PROPERTY
  INTERFACE_INCLUDE_DIRECTORIES ${JPEG_INCLUDES}
 )
endif()

I admit it's not a huge benefit over just using the variables. The advantages:
- you get slightly better error handling
- your target_link_libraries commands are slightly more readable.

>    - or write my `../ExtLibs/libjpeg/CMakeLists.txt` so that it globally
> defines JPEG_LIBRARIES and JPEG_INCLUDE_DIRS

That will work, too.


Cheers,
  Johannes

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Florent Castelli
On 29/11/2017 12:02, Johannes Zarl-Zierl wrote:

> Hello Carsten,
>
> On Samstag, 25. November 2017 11:46:44 CET Carsten Fuchs wrote:
>> Thanks for your reply, but how can I proceed from here?
>>
>> In order to be able to write in the parent script something that works
>> in either case, that is,
>>
>> target_link_libraries(main_program <either JPEG::JPEG or ${JPEG...} or ???>)
> Well, that's one way, but that doesn't really provide any benefit above the
> original solution (i.e. just define the JPEG_INCLUDES and JPEG_LIBRARIES
> variables accordingly).
>
>> it seems that I either
>>
>>     - have to make a copy of FindJPEG.cmake, customize it to define
>> target JPEG::JEPG and ship it along with my project,
> Either that or you define it yourself:
> find_package(JPEG)
> if (JPEG_FOUND)

I'd say "if(JPEG_FOUND AND NOT TARGET JPEG::JPEG)"
If someone improves FindJPEG.cmake, you won't break your build.

>   add_library(JPEG::JPEG UNKNOWN IMPORTED)
>   set_property(
>    TARGET JPEG::JPEG
>    PROPERTY IMPORTED_LOCATION ${JPEG_LIBRARIES}
>    )
>   set_property(
>    TARGET JPEG::JPEG PROPERTY
>    INTERFACE_INCLUDE_DIRECTORIES ${JPEG_INCLUDES}
>   )
> endif()
>
> I admit it's not a huge benefit over just using the variables. The advantages:
> - you get slightly better error handling
> - your target_link_libraries commands are slightly more readable.
>
>>     - or write my `../ExtLibs/libjpeg/CMakeLists.txt` so that it globally
>> defines JPEG_LIBRARIES and JPEG_INCLUDE_DIRS
> That will work, too.
>
>
> Cheers,
>    Johannes
>

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Carsten Fuchs
Thanks to all!

Well, I guess I'm among the people mentioned by Lectem at
https://www.mail-archive.com/cmake-developers@.../msg18267.html

I'll try to dig my way through it, but at this point I consider staying
with SCons under Linux, where finding packages is important and the
command line is used anyway, and using CMake under Windows only, where
quasi all external libraries are shipped along with the project and the
real goal is to obtain a Visual Studio solution. (I already have a
complete build with SCons that works under Windows and Linux for my
project which is of average complexity.)

Best regards,
Carsten

$ ls Cafu/ExtLibs/ -1
bullet
Cg
fbx
fmod
freealut
freetype
glfw
jpeg
libogg
libpng
libvorbis
lua
lwo
MersenneTwister.h
minizip
mpg123
noise
openal-soft
openal-win
pstdint.h
tclap
wxWidgets
zlib



Am 29.11.2017 um 21:17 schrieb Florent Castelli:

> On 29/11/2017 12:02, Johannes Zarl-Zierl wrote:
>> Hello Carsten,
>>
>> On Samstag, 25. November 2017 11:46:44 CET Carsten Fuchs wrote:
>>> Thanks for your reply, but how can I proceed from here?
>>>
>>> In order to be able to write in the parent script something that works
>>> in either case, that is,
>>>
>>> target_link_libraries(main_program <either JPEG::JPEG or ${JPEG...}
>>> or ???>)
>> Well, that's one way, but that doesn't really provide any benefit
>> above the
>> original solution (i.e. just define the JPEG_INCLUDES and JPEG_LIBRARIES
>> variables accordingly).
>>
>>> it seems that I either
>>>
>>>     - have to make a copy of FindJPEG.cmake, customize it to define
>>> target JPEG::JEPG and ship it along with my project,
>> Either that or you define it yourself:
>> find_package(JPEG)
>> if (JPEG_FOUND)
>
> I'd say "if(JPEG_FOUND AND NOT TARGET JPEG::JPEG)"
> If someone improves FindJPEG.cmake, you won't break your build.
>
>>   add_library(JPEG::JPEG UNKNOWN IMPORTED)
>>   set_property(
>>    TARGET JPEG::JPEG
>>    PROPERTY IMPORTED_LOCATION ${JPEG_LIBRARIES}
>>    )
>>   set_property(
>>    TARGET JPEG::JPEG PROPERTY
>>    INTERFACE_INCLUDE_DIRECTORIES ${JPEG_INCLUDES}
>>   )
>> endif()
>>
>> I admit it's not a huge benefit over just using the variables. The
>> advantages:
>> - you get slightly better error handling
>> - your target_link_libraries commands are slightly more readable.
>>
>>>     - or write my `../ExtLibs/libjpeg/CMakeLists.txt` so that it
>>> globally
>>> defines JPEG_LIBRARIES and JPEG_INCLUDE_DIRS
>> That will work, too.
>>
>>
>> Cheers,
>>    Johannes
>>
>

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

R0b0t1
On Monday, December 4, 2017, Carsten Fuchs <[hidden email]> wrote:
> Thanks to all!
>
> Well, I guess I'm among the people mentioned by Lectem at https://www.mail-archive.com/cmake-developers@.../msg18267.html
>
> I'll try to dig my way through it, but at this point I consider staying with SCons under Linux, where finding packages is important and the command line is used anyway, and using CMake under Windows only, where quasi all external libraries are shipped along with the project and the real goal is to obtain a Visual Studio solution. (I already have a complete build with SCons that works under Windows and Linux for my project which is of average complexity.)
>

Hello,

Are you able to link to your project? I am interested in how you have set up your build system.

Cheers,
    R0b0t1

> Best regards,
> Carsten
>
> $ ls Cafu/ExtLibs/ -1
> bullet
> Cg
> fbx
> fmod
> freealut
> freetype
> glfw
> jpeg
> libogg
> libpng
> libvorbis
> lua
> lwo
> MersenneTwister.h
> minizip
> mpg123
> noise
> openal-soft
> openal-win
> pstdint.h
> tclap
> wxWidgets
> zlib
>
>
>
> Am 29.11.2017 um 21:17 schrieb Florent Castelli:
>>
>> On 29/11/2017 12:02, Johannes Zarl-Zierl wrote:
>>>
>>> Hello Carsten,
>>>
>>> On Samstag, 25. November 2017 11:46:44 CET Carsten Fuchs wrote:
>>>>
>>>> Thanks for your reply, but how can I proceed from here?
>>>>
>>>> In order to be able to write in the parent script something that works
>>>> in either case, that is,
>>>>
>>>> target_link_libraries(main_program <either JPEG::JPEG or ${JPEG...} or ???>)
>>>
>>> Well, that's one way, but that doesn't really provide any benefit above the
>>> original solution (i.e. just define the JPEG_INCLUDES and JPEG_LIBRARIES
>>> variables accordingly).
>>>
>>>> it seems that I either
>>>>
>>>>     - have to make a copy of FindJPEG.cmake, customize it to define
>>>> target JPEG::JEPG and ship it along with my project,
>>>
>>> Either that or you define it yourself:
>>> find_package(JPEG)
>>> if (JPEG_FOUND)
>>
>> I'd say "if(JPEG_FOUND AND NOT TARGET JPEG::JPEG)"
>> If someone improves FindJPEG.cmake, you won't break your build.
>>
>>>   add_library(JPEG::JPEG UNKNOWN IMPORTED)
>>>   set_property(
>>>    TARGET JPEG::JPEG
>>>    PROPERTY IMPORTED_LOCATION ${JPEG_LIBRARIES}
>>>    )
>>>   set_property(
>>>    TARGET JPEG::JPEG PROPERTY
>>>    INTERFACE_INCLUDE_DIRECTORIES ${JPEG_INCLUDES}
>>>   )
>>> endif()
>>>
>>> I admit it's not a huge benefit over just using the variables. The advantages:
>>> - you get slightly better error handling
>>> - your target_link_libraries commands are slightly more readable.
>>>
>>>>     - or write my `../ExtLibs/libjpeg/CMakeLists.txt` so that it globally
>>>> defines JPEG_LIBRARIES and JPEG_INCLUDE_DIRS
>>>
>>> That will work, too.
>>>
>>>
>>> Cheers,
>>>    Johannes
>>>
>>
>
> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> http://public.kitware.com/mailman/listinfo/cmake
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package() portably?

Carsten Fuchs
Hi,

Am 2017-12-05 um 01:27 schrieb R0b0t1:
> Are you able to link to your project? I am interested in how you have
> set up your build system.

https://www.cafu.de

If you're specifically looking at the SCons scripts, please note that
they historically grew and are not perfect either: Especially, I used to
use custom builds of quasi all direct external dependencies under Linux
either, using only libpng and zlib from the system. This was mainly
motivated by the fact that I needed to ship them for Windows anyways,
the system's versions were in some cases very outdated (if available at
all) and that I sometimes added a fix or patch here and there.
Especially wxWidgets is a special case of which I plan to use the
system's copy in the future; this in turn will make it possible to also
use other system libraries as well.

Best regards,
Carsten
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/cmake