Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CMakeLists.txt #25

Closed
wants to merge 26 commits into from
Closed

Add CMakeLists.txt #25

wants to merge 26 commits into from

Conversation

h3ndrk
Copy link
Contributor

@h3ndrk h3ndrk commented May 28, 2021

This PR adds CMake support for opusfile and opusurl. autoconf is untouched.

Fixes #15

@h3ndrk h3ndrk marked this pull request as ready for review May 29, 2021 16:44
@h3ndrk
Copy link
Contributor Author

h3ndrk commented May 29, 2021

This PR is ready for review. Some questions to the authors:

  1. Currently the version is hard-coded in the CMakeLists.txt. How is your normal workflow for embedding it into the library and distribution files etc.? I only had a brief look at the many scripts that somehow mutate and propagate the version. It seems very complex tooling for the job... Maybe there is a simple way that I don't see currently?
  2. Do we want to also build the documentation with CMake? There is also another problem with it, see Documentation #21

Thanks!

@rillian
Copy link
Contributor

rillian commented May 29, 2021

I only had a brief look at the many scripts that somehow mutate and propagate the version. It seems very complex tooling for the job...

Yes, this is pretty complicated. The requirements are:

  • When building from a repository, the software version should be derived from git describe --tags for clarity and correctness.
  • When building from a release source package, where no revision history is available, the version should be set statically.
  • Version info needs to be propagated to:
    • config.h for use in the library
    • pkg-config files describing the library
    • source package naming
    • documentation

That way we get something like 0.12 for a release but 0.12-6-g641bf7e the current development tree.

There's a unix shell script update_version which queries git and writes the result to a file package_version which is read by various build systems. This file isn't tracked by git, but is included in release source packages. Together that covers the static and dynamic version requirements.

Now, opusfile library code doesn't currently use the PACKAGE_VERSION define, cmake doesn't create pkg-config files or source packages, so you'd only need this for documentation, if you add support for building that (which would be nice). However, opusfile might use the version string at some point in the future, so a cmake build should support it.

You can't call the unix shell script on Windows. I suggest copying cmake/OpusPackageVersion.cmake from the opus repo, which re-implements the script in cmake.

Copy link
Contributor

@rillian rillian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see the version TODO addressed, and some ci converage before this lands. Building the documentation would be nice, but can also be a separate PR. Otherwise I looks fine to me.

@evpobr, @xnorpx do you have any comments?

@xnorpx
Copy link

xnorpx commented May 29, 2021

I can take a look next week.

Do you need cmake_minimum_required(VERSION 3.16) ?

(people with old linux distros always complain with high cmake versions :) )

@h3ndrk
Copy link
Contributor Author

h3ndrk commented May 31, 2021

Do you need cmake_minimum_required(VERSION 3.16) ?

(people with old linux distros always complain with high cmake versions :) )

I've only tested with CMake 3.16 (officially available on Ubuntu 20.04) and I know at least one feature (timestamping of Doxygen) which requires 3.16. But compatibility vs. modern features is always a hard question... In the book Professional CMake, the author says that it is preferred to not limit the project maintainers in functionality caused by old CMake versions but rather require users to download a more recent version of CMake themselves (which is very easy).

I'd like to see the version TODO addressed

Done, version is retrieved via a CMake module taken from opus.

Building the documentation would be nice

Done with changing behavior: The output paths change because I would like to use the official FindDoxygen.cmake module which makes integrating Doxygen very easy in CMake. The module generates a Doxyfile automatically and outputs the documentation into a subdirectory in the build directory which means the Doxygen.in file is obsolete and documentation is generated not in the doc/ directory.

some ci converage before this lands

Currently, there is no CMake find module for opus and ogg which means that the CMakeLists.txt of opusfile will only work with opus and ogg installed with CMake configs instead of legacy pkgconfig. Not installing CMake configs is quite common in most distributions sadly (the Travis CI also has this problem). I will try to come up with some find modules relying on CMake configs and pkgconfig as a fallback. I've no experience how opusfile is built on Windows and how it finds its dependencies there. I will add some CI steps after the find modules are done.

@h3ndrk
Copy link
Contributor Author

h3ndrk commented May 31, 2021

  • Find modules added
  • Travis CI passing
  • The same commands have been added to GitLab CI

.gitlab-ci.yml Outdated
apt-get install -y libopus-dev libogg-dev libssl-dev
doxygen
script:
- wget https://cmake.org/files/v3.16/cmake-3.16.9-Linux-x86_64.tar.gz
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding a CI config. That's nice to see, and these steps are green on our gitlab.

Pulling a binary like this is unfortunate. It makes the build description specific to x86_64-linux, so at the very least you need an arch-specific tag.

The gcc:9 container we use is based on debian:10 which has cmake 3.13.3, and is used by all our other gitlab ci jobs. Is that also too old? See, I'm already complaining about the aggressive cmake version. :)

There's a kitware/cmake container feed on docker hub (just as huge as the gcc images!) but it seems to just be their internal ci runners, rather than something for external use. At least, I couldn't make sense of the versioning for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean with arch-specific tag. Could you elaborate on this?

I also found rikorose/gcc-cmake, but it is third-party and I'm not sure if you want to rely on that.

Regarding the CMake version, see my comment below.

.travis.yml Outdated
homebrew:
brewfile: true

env: PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opt/openssl/lib/pkgconfig

before_script:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then
wget https://cmake.org/files/v3.16/cmake-3.16.9-Linux-x86_64.tar.gz;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use curl -O here to avoid having to install wget.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

CMakeLists.txt Outdated
@@ -52,6 +56,7 @@ target_link_libraries(opusfile
PUBLIC
Ogg::ogg
Opus::opus
$<$<BOOL:OP_HAVE_LIBM>:m>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$<$<BOOL:${OP_HAVE_LIBM}>:m>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@evpobr
Copy link

evpobr commented Jun 1, 2021

I've only tested with CMake 3.16 (officially available on Ubuntu 20.04) and I know at least one feature (timestamping of Doxygen) which requires 3.16. But compatibility vs. modern features is always a hard question... In the book Professional CMake, the author says that it is preferred to not limit the project maintainers in functionality caused by old CMake versions but rather require users to download a more recent version of CMake themselves (which is very easy).

In theory it is correct. In practice version it is too high for some Linux distros. It's surprising to me that someone is using such old distros, but i have encountered similar reports on a regular basis.

I could recommend to use more or less safe version (e.g. 3.6) and enable features depending on CMAKE_VERSION checks. You can display message if some feature is disabled because CMake version is too low.

CMakeLists.txt Outdated
include(CheckCSourceCompiles)
cmake_push_check_state(RESET)
if(WIN32)
check_include_file("winsock2.h" OP_HAVE_WINSOCK2_H)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

winsock2 is from Win95 times, not sure it is required to check it today.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to do a nearly exact port of the autoconf/autotools scripts. Since I don't have access to Windows please say more directly how we should proceed here. Should I just remove the check?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

$<$<C_COMPILER_ID:MSVC>:/wd4267>
$<$<C_COMPILER_ID:MSVC>:/wd4244>
$<$<C_COMPILER_ID:MSVC>:/wd4090>
$<$<C_COMPILER_ID:Clang,GNU>:-std=c89>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd propose to just omit that compiler flag because C_STANDARD does not seem to support any value for C89. Maybe that is already default?

@h3ndrk
Copy link
Contributor Author

h3ndrk commented Jun 4, 2021

I could recommend to use more or less safe version (e.g. 3.6) and enable features depending on CMAKE_VERSION checks. You can display message if some feature is disabled because CMake version is too low.

Testing and back-porting the CMake scripts is a lot of effort because

  1. ... there are things that don't exist in older versions. I don't have much motivation to re-implement things that already exist in newer versions.
  2. ... back-porting can lead to nasty bugs in CMake without helpful error messages. See https://alexreinking.com/blog/how-to-use-cmake-without-the-agonizing-pain-part-1.html (section "Validating Your Minimum Version").
  3. ... manually figuring out what features are needed from newer versions and implementing reasonable fallbacks is complicated and error-prone.

These points are also argued by CMake experts, saying that developers of CMake build systems should not try to support very old versions but rather require the version that they have developed on.

Because of these reasons I would like to keep cmake_minimum_required(VERSION 3.16).

@petterreinholdtsen
Copy link

petterreinholdtsen commented Jun 4, 2021 via email

@h3ndrk
Copy link
Contributor Author

h3ndrk commented Jun 4, 2021

@evpobr
Copy link

evpobr commented Jun 5, 2021

https://repology.org/project/cmake/versions

@Be-ing
Copy link

Be-ing commented Jun 6, 2021

Thanks for working on this! It will make this library easier to use, especially on Windows.

@h3ndrk
Copy link
Contributor Author

h3ndrk commented Jun 28, 2021

Ping

CMakeLists.txt Outdated
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be ${CMAKE_INSTALL_INCLUDEDIR}/opus?

https://packages.debian.org/sid/amd64/libopusfile-dev/filelist

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it correct that we install in /usr/include/opus instead of /usr/include/opusfile?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess so:

opusincludedir = ${includedir}/opus

And public include directory should be ${CMAKE_INSTALL_INCLUDEDIR}/include/opus:

#include <opusfile.h>

Copy link
Contributor Author

@h3ndrk h3ndrk Jul 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. You wrote ${CMAKE_INSTALL_INCLUDEDIR}/include/opus, I'am putting it in ${CMAKE_INSTALL_INCLUDEDIR}/opus. I hope this is fine.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you're right.

@Yohannfra
Copy link

Hi, any news for this PR ?

@rillian
Copy link
Contributor

rillian commented Jan 15, 2022

Merged upstream in cf218fb. Thanks!

@rillian rillian closed this Jan 15, 2022
@h3ndrk h3ndrk deleted the cmake branch January 15, 2022 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add CMake support
7 participants