Open vvs- opened 5 years ago
Unfortunately, CMake modules are often written in the least portable way possible, usually hard-coding paths like this:
IMHO, the best approach would be rewriting the module to find the appropriate paths using pkg-config
, which would probably also be upstreamable. Maybe open an issue upstream.
Even worse. There exists a habit to distribute package's own CMake modules within the sources. This is particularly popular for modules that don't (yet) exist in CMake. BTW, the same practice exists for GNU autotools as well.
I wasn't able to find anything that would suggest how to solve this particular problem in NixOS. I've found parts of the solution throughout Nixpkgs expressions and manuals. The purpose of this issue is to discuss best practices and at least document it.
I'm not sure if there's anything actionable in this issue itself, except of moving upstreams more to using pkg-config
.
Ok. But what others should do when confronted by this problem? Every man for himself?
Here is what I've found. Create default.nix
expression with the following contents:
with import <nixpkgs> { };
stdenv.mkDerivation {
name = "project";
buildInputs = [ cmake gtk2 glib ];
cmakeFlags = [
"-DGTK2_GDKCONFIG_INCLUDE_DIR=${gtk2.out}/lib/gtk-2.0/include"
"-DGTK2_GLIBCONFIG_INCLUDE_DIR=${glib.out}/lib/glib-2.0/include"
];
}
Add other required inputs and CMake flags. Put it in the same folder where top CMakeLists.txt resides. Run nix-shell
and inside its prompt cmakeConfigurePhase
. After that everything should work as expected.
For GTK3 change default.nix
to the following contents:
with import <nixpkgs> { };
stdenv.mkDerivation {
name = "project";
buildInputs = [ cmake pkgconfig gtk3 glib pcre xorg.libpthreadstubs xorg.libXdmcp libuuid libselinux libsepol libxkbcommon epoxy at_spi2_core dbus ];
}
I think upstream should be patched. However, there seems also the env path $GTKMM_BASE_PATH
Which maybe gtk2 can add to it's setup hook?
I'm not sure if I understand the problem.
If you add gtk2
to buildInputs
, and also added pkgconfig
to nativeBuildInputs
, the tooling will add the directory of .pc
files from the corresponding dev
output to PKG_CONFIG_PATH
- so pkgconfig will be able to provide these locations if the build system of the package you're building asks it.
This is also (somewhat) documented in the nixpkgs manual and NixOS wiki.
If the buildsystem doesn't use pkgconfig, but hardcodes this to some FHS paths, or requires you to set other variables, there's not much nix can do, how should it know how to configure the build system?
@flokli CMake package contains FindGTK2
module with hardcoded paths and fixing it would also fix packages depending on that module. I am not sure where we would find a person to patch that module though. Especially since only some fringe ancient projects will benefit from the fix.
Not so ancient as you might think. Here is an IF authoring system released in October (!) which by default uses GTK2. I've encountered enough of such things. Sure, they are not as widespread as Firefox, but which programming languages are (except JS)?
BTW, search for GTK2_GDKCONFIG_INCLUDE_DIR
in Nixpkgs and there are too much of it for my tastes.
@vvs- fixing FindGTK2
in cmake would surely remove a lot of these usages.
I quickly skimmed cmake, seems these hardcoded paths are in Modules/FindGTK2.cmake
. We can't hardcode gtk paths in there, as this would pull in a runtime dependency on gtk.
What we could do, would be replacing these calls by some find_package(PkgConfig REQUIRED)
and pkg_check_modules(…)
calls - but as @jtojnar mentioned, it probably isn't that pleasant to work through this…
Thank you for your contributions. This has been automatically marked as stale because it has had no activity for 180 days. If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity. Here are suggestions that might help resolve this more quickly:
I'm not sure if this ever will be fixed, given priority for "latest and greatest", but let's our hope to extend for another few months at least.
IIRC, there were some upstream changes in FindGTK2 recently does it still happen?
Still happens with nixos-unstable.
I marked this as stale due to inactivity. → More info
This still uses hardcoded paths - see https://github.com/Kitware/CMake/blob/master/Modules/FindGTK2.cmake#L280.
I marked this as stale due to inactivity. → More info
still relevant.
I stumbled on this using Guix while trying to build Overgrowth. Same problem. Annoying.
I could make it work by specifying some extra CMAKE_PREFIX_PATH, like so:
;; Help CMake's FindGTK2.cmake, which doesn't look under lib/include
;; for the glibconfig.h and gdkconfig.h headers, among other problems,
;; which causes GTK2_INCLUDE_DIRS to be empty.
#~(list (string-append "-DCMAKE_PREFIX_PATH="
#$(this-package-input "gtk+") "/lib/;"
#$(this-package-input "glib") "/lib"))
Which means that FindGTK2.cmake already mostly works, and would simply need to be modified like this:
1 file changed, 3 insertions(+)
Modules/FindGTK2.cmake | 3 +++
modified Modules/FindGTK2.cmake
@@ -285,6 +285,9 @@ function(_GTK2_FIND_INCLUDE_DIR _var _hdr)
foreach(_d ${_gtk_packages})
list(APPEND _suffixes ${_d})
list(APPEND _suffixes ${_d}/include) # for /usr/lib/gtk-2.0/include
+ # Guix does not add lib/ to the CMAKE_PREFIX_PATH, so manually do so here.
+ list(APPEND _suffixes lib/${_d})
+ list(APPEND _suffixes lib/${_d}/include)
endforeach()
if(GTK2_DEBUG)
Alternatively, the CMAKE_PREFIX_PATH search path in Guix could be modified to not only include the root installation prefix of all packages but also their $prefix/lib directory.
I've opened a merge request to the Kitware folks here: https://gitlab.kitware.com/cmake/cmake/-/merge_requests/9417
Describe the bug If you try to build any software that uses CMake and GTK2 you'll notice that CMake can't find all the required components. In particular it'll complain about GTK2_GDKCONFIG_INCLUDE_DIR and GTK2_GLIBCONFIG_INCLUDE_DIR not found. This bug is presently circumvented in Nixpkgs by using Nix expressions to substitute actual paths to CMake before configuring phase so it won't need to search for them.
While this works for Nixpkgs it makes it extremely difficult for newbies to compile such software from sources. Using just nix-shell won't suffice anymore. I believe that fixing CMake FindGTK2 module would make more sense.
To Reproduce Steps to reproduce the behavior:
CMakeLists.txt
with just one line:find_package(GTK2)
nix-shell -p cmake pkgconfig gtk2
cmake .
Expected behavior It should succeed without complaining about files not found.
Metadata