-
Notifications
You must be signed in to change notification settings - Fork 169
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 CMake build system (based on previous work from @mdsitton and @jcelerier) and CI #24
Conversation
This is a pretty large PR. Probably won't get time to have a proper look at it until the weekend. |
hey, sorry, I had entirely forgot my PR. this looks pretty nice and complete ! But are you sure you want to support CMake versions that didn't even have PUBLIC / PRIVATE ? Are there still widely-used systems with such old version (that couldn't just install CMake's statically-built latest version) ? |
@erikd No worries, take your time. :) |
libsndfile builds on travis with CMake min version of 3.1.3. Maybe figure out what that is doing. |
Those builds aren't normal Travis instances; they are cross compiling and testing on many different Docker images (some of them using qemu internally?) and aren't maintained by me. (They are from cross which is ""Zero setup" cross compilation and "cross testing" of Rust crates"). If you guys don't think it's worth supporting such an old CMake version I have no problems reverting the last few changes. I would then just drop those few Travis instances or try to upgrade CMake in those Docker images. |
Yeah, I don't think its worth supporting any CMake version older than the ones libsndfile uses. |
that's interesting: these docker images have rust which is very recent, but don't have five-years old versions of CMake :p are they hosted somewhere on github ? it could be worth it to send PRs to them so that everyone doing such a work can at least leverage recent versions. |
Reverted the last changes. |
@Bobo1239 do you offer any build artifacts for I'm most interested in the win32 artifacts for multi-platform. The other OSs (unix/linux/macos) have methods to fetch |
CMakeLists.txt
Outdated
set(HAVE_ALSA ${ALSA_FOUND}) | ||
|
||
find_package(Sndfile) | ||
set(HAVE_SNDFILE ${SNDFILE_FOUND}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Bobo1239 cmake does not seem to provide FindSndfile.cmake
or FindFFTW.cmake
on some systems which means if they're in a non-standard location, the linking and including won't work as it would in a vanilla POSIX environment.
Would you consider adding an additional pkg-config
dependency on this? Then you could do the following:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 394de75..1b85d17 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,6 +9,7 @@ include(CheckIncludeFiles)
include(CheckSymbolExists)
include(CheckTypeSize)
include(ClipMode)
+include(FindPkgConfig)
set(SAMPLERATE_SRC
${PROJECT_SOURCE_DIR}/src/samplerate.c
@@ -53,12 +54,24 @@ clip_mode()
find_package(ALSA)
set(HAVE_ALSA ${ALSA_FOUND})
+if(ALSA_FOUND)
+ include_directories("${ALSA_INCLUDE_DIRS}")
+ link_directories("${ALSA_LIBRARY_DIRS}")
+endif()
-find_package(Sndfile)
+pkg_check_modules(Sndfile sndfile>=1.0.0)
set(HAVE_SNDFILE ${SNDFILE_FOUND})
+if(SNDFILE_FOUND)
+ include_directories("${SNDFILE_INCLUDE_DIRS}")
+ link_directories("${SNDFILE_LIBRARY_DIRS}")
+endif()
-find_package(FFTW)
+pkg_check_modules(FFTW3 fftw3>=3.0.0)
set(HAVE_FFTW3 ${FFTW_FOUND})
+if(FFTW3_FOUND)
+ include_directories("${FFTW3_INCLUDE_DIRS}")
+ link_directories("${FFTW3_LIBRARY_DIRS}")
+endif()
configure_file(${PROJECT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FindSndfile.cmake
and FindFFTW.cmake
are the cmake
directory which should be loaded by set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake)
at the top. (ClipMode.cmake
is also affected by this.)
Regarding pkg-config: What do @erikd and @jcelerier think? Should I switch from the two cmake modules to pkg-config? I really don't know what is better supported across the board.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't know what is better supported across the board.
To give a bit more background information on this:
Ubuntu 14.04, default for Travis-CI:
locate -i FindALSA.cmake
(found) /usr/share/cmake-3.5/Modules/FindALSA.cmake
locate -i FindFFTW
(not found)
locate -i FindSndfile
(not found)
What this means is if a project requires any of the variables expected to be available for includes or libraries, they won't be available. Msys2 re-uses the POSIX-style paths so it hides this bug as the default include
and lib
paths work out of the box.
In the case of a build system that has CMAKE_PREFIX_PATH
setup to search for these libraries, it'll find that they exist, but not know how to find the headers or the libraries without the appropriate .cmake
file if they're installed anywhere except where a Unix environment would expect.
Case and point is that if you were to download the libsndfile
from the website, it offers a libsndfile.pc
file, not a FindSndfile.cmake
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Bobo1239 On second thought, perhaps this is a problem with my environment. CMAKE_PREFIX_PATH
clearly states that it searches the same paths as pkg-config
. Here's an excerpt from the website:
[CMAKE_PREFIX_PATH] contains the “base” directories, the
FIND_XXX()
commands append appropriate subdirectories to the base directories. SoFIND_PROGRAM()
adds/bin
to each of the directories in the path,FIND_LIBRARY()
appends/lib
to each of the directories, andFIND_PATH()
andFIND_FILE()
append/include
.
I will investigate this some more on my end as to why the paths are found, but the includes and libs are not. If working properly, the existing code should work just fine with cmake.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you may have misunderstood me. FindFFTW and FindSndFile are distributed with the source (in the cmake
directory) in the repo and aren't required from the environment. And they should get loaded because we're extending CMAKE_MODULE_PATH
to include the cmake
directory.
edit: Didn't see your response before I submitted this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Bobo1239 you are correct, I missed that they were distributed with the project. I think I found the culprit: https://github.com/erikd/libsamplerate/pull/24/files#r157310099. Your original technique should be just fine but I recommend making the variables consistently named. Also, include_directories(...)
and link_directories(...)
will still be required for some environments. That part will still need to be (fixed to use the right variables and) added as a safeguard, even if redundant on some systems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at some more FindXXX.cmake
modules and they all appear to follow slightly different conventions, so it's hard to argue for consistency. Working with what we have now... Here's what works out of the box using this PR without adding pkg-config
:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 394de75..a2aad7f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -53,11 +53,23 @@ clip_mode()
find_package(ALSA)
set(HAVE_ALSA ${ALSA_FOUND})
+if(ALSA_FOUND)
+ include_directories("${ALSA_INCLUDE_DIR}")
+ link_directories("${ALSA_LIBRARY}/../")
+endif()
find_package(Sndfile)
set(HAVE_SNDFILE ${SNDFILE_FOUND})
+if(SNDFILE_FOUND)
+ include_directories("${SNDFILE_INCLUDE_DIR}")
+ link_directories("${SNDFILE_LIBRARY}/../")
+endif()
find_package(FFTW)
+if(FFTW_FOUND)
+ include_directories("${FFTW_INCLUDES}")
+ link_directories("${FFTW_LIBRARIES}/../")
+endif()
set(HAVE_FFTW3 ${FFTW_FOUND})
configure_file(${PROJECT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
@tresf I'll try to look into AppVeyor build artifacts this weekend. |
cmake/FindFFTW.cmake
Outdated
@@ -0,0 +1,25 @@ | |||
# From: https://github.com/wjakob/layerlab/blob/master/cmake/FindFFTW.cmake | |||
# FIXME: License concerns? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The license is BSD 2-clause "Simplified" License
. (found it at layerlab) This and the BSD 3-clause are GPL compatible and very common for cmake scripts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be fine with either a BSD or BSD 2-clause license for the CMake files.
cmake/FindFFTW.cmake
Outdated
set (FFTW_FIND_QUIETLY TRUE) | ||
endif (FFTW_INCLUDES) | ||
|
||
find_path (FFTW_INCLUDES fftw3.h) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok... I think I found the problem. I had expected this to be FFTW_INCLUDE_DIRS
and FFTW_LIBRARY_DIRS
. See Edit: No, that's slightly off as well. This is definitely why FindSndfile.cmake
as an examplepkg-config
worked and find_package
failed. pkg-config
uses more predictable names across the board; cmake you can provide your own. I can change my code to accommodate.
36ab528
to
395e851
Compare
@Bobo1239 I will also be needing the header file and the pkg-config ( Also, long-term, if there are no objections, it would be nice to have the file hosted at an unauthenticated, tagged location such as the github release area, if @erikd would entertain this. AppVeyor is able to do this. |
@tresf I guess it would make sense to setup the install target in CMake so we get that kind of structure for all platforms (also we're currently not generating a |
@Bobo1239 AFAIK prefix=
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: samplerate
Description: An audio Sample Rate Conversion library
Requires:
Version: 0.1.8
Libs: -L${libdir} -lsamplerate
Libs.private: Ext/libsndfile.a
Cflags: -I${includedir} CMake can configure this file like so (sample, I haven't tested it for syntax errors) SET(prefix "")
SET(exe_prefix "\\${prefix}")
SET(libdir "\\${exec_prefix}/lib")
SET(includedir "\\${prefix}/include")
SET(VERSION "${PROJECT_VERSION}")
SET(LIBS "Ext/libsndfile.a")
CONFIGURE_FILE(samplerate.pc.in samplerate.pc @ONLY) |
I agree, although I can rearrange the files in the packaging utility if needed, that's what we have to do with fftw's for example. Getting the output files is enough to start offering this package to win32 developers. |
bf22644
to
2274269
Compare
@tresf https://ci.appveyor.com/project/Bobo1239/libsamplerate/build/job/psucvyvat0tv6vye/artifacts Does this work for you? |
@erikd Is there anything I should do here? |
if (file == NULL) | ||
return name ; | ||
|
||
#if defined (__linux__) || defined (__APPLE__) || defined (__FreeBSD__) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something's not right there. Why has that #if
been removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem here is the pclose
call afterwards which fails to link on Windows. An alternative would be to replace is_pipe
with #define IS_PIPE
(+ #undef IS_PIPE
at the end) and
if (is_pipe)
pclose (file) ;
else
fclose (file) ;
with
#ifdef IS_PIPE
pclose (file) ;
#else
fclose (file) ;
#endif
Do you want me to do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What problem was this change trying to address?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Native Windows (MSVC) doesn't provide pclose
(though apparently it has _pclose
) so it must be removed by the preprocessor.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, how about you just sqash this PR down to a single commit and I'll sort it out,
Would you be fix the |
This commit adds a new CMake-based build system. The build time configuration should match the one by autoconf. Then this build system gets tested on Travis (Linux) and AppVeyor (Windows; MSVC and MinGW). Additionally on AppVeyor, a build artifact is produced for easier distribution to Windows. Some minor changes are introduced to fix compilation on Windows. This commit is based on previous attempts at a CMake-based build by Jean-Michaël Celerier (jcelerier) and Matthew Sitton (mdsitton).
Sorry for the delay. Finally got around to do this. (Was busy with university...) |
Thank you all for your contribution! |
Hi @erikd,
thanks for creating this library. I wanted to create some Rust bindings and to simplify cross-platform compilation I continued the previous CMake attempts from @mdsitton and @jcelerier. I've also tried to setup some CI (Travis for Linux; Appveyor for Windows). Admittedly I've not really done much C development till now so please feel free to point out any problems with this PR.
https://travis-ci.org/Bobo1239/libsamplerate
https://ci.appveyor.com/project/Bobo1239/libsamplerate