GithubHelp home page GithubHelp logo

Comments (6)

alexshpilkin avatar alexshpilkin commented on July 24, 2024 1

Well, as @jtojnar points out in the first link above, the docs for GNUInstallDirs explicitly say that the value of a CMAKE_INSTALL_*DIR variable “should typically be a path relative to the installation prefix [...]. However, an absolute path is also allowed.” (NixOS makes occasional use of that to make user and development files go into separate trees, and so just always passes absolute paths even if they are in fact located under the prefix.)

I’ll try to help if you’re willing to rely on my nearly-nonexistent understanding of CMake, but probably not before I finish my first round through all Nix packages with this problem (currently on package 62 of 85 😮‍💨 ).

from orcania.

babelouest avatar babelouest commented on July 24, 2024

Hi,

I'm not familiar with absolute paths for CMAKE_INSTALL_{INCLUDE,LIB}DIR variables, as I understand, the CMAKE_INSTALL_PREFIX is supposed to be an absolute path, to be combined with the CMAKE_INSTALL_* variables.

Also, I took a look at your references and made some tests, but I can't find a solution yet, can you provide a pull request to help with that?

from orcania.

babelouest avatar babelouest commented on July 24, 2024

Out of curiosity, what arguments are you using when packaging for NixOS?

from orcania.

alexshpilkin avatar alexshpilkin commented on July 24, 2024

The CMake infrastructure in Nixpkgs is... general, to put it politely, so a full list of configuration flags is unlikely to be helpful. If you want a quick, non-NixOS-dependent reproduction, here’s one (cf NixOS/nixpkgs#172347):

$ cd /tmp
$ mkdir prefix prefix-include prefix-lib
$ git clone https://github.com/babelouest/orcania
[snip]
$ cd orcania
$ mkdir build && cd build
$ cmake -DCMAKE_INSTALL_PREFIX=/tmp/prefix -DCMAKE_INSTALL_INCLUDEDIR=/tmp/prefix-include -DCMAKE_INSTALL_LIBDIR=/tmp/prefix-lib ..
[snip]
$ make && make install
[snip]
$ grep -r '//tmp/prefix' /tmp/prefix-lib
/tmp/prefix-lib/pkgconfig/liborcania.pc:libdir=${exec_prefix}//tmp/prefix-lib
/tmp/prefix-lib/pkgconfig/liborcania.pc:includedir=${prefix}//tmp/prefix-include
$ # oops, this won't work

If, on the other hand, you’re wondering why anyone would do that, well, on NixOS it’s not exactly that, but the name of the game is to have separate trees (with their own bin, lib, etc.) for every package, link them together following (explicitly declared) dependencies and/or set up search paths so that the set of packages the user wants to be active at the moment gets used.

Thus, when a derivation uses separate dev and/or doc outputs (what would on other systems be separate dev or devel and/or doc packages), those too are placed into completely separate trees (user-usable things like binaries and shared libraries into /nix/store/HASH-NAME-VERSION, developer-usable things like include files and static libraries into /nix/store/HASH-NAME-VERSION-dev, documentation into /nix/store/HASH-NAME-VERSION-doc), and the CMake tooling uses the CMAKE_INSTALL_*DIR variables to achieve that. Now, the Nixpkgs derivation for orcania specifically does not currently separate its outputs in this way because it’s not that large (and because nobody cared to make it so), but the tooling passes absolute paths anyway—for simplicity and because a CMake build system is supposed to accept them in any case.

(To be clear, I’m not the Nixpkgs maintainer for orcania, I’m the person trying to fix these CMake-induced bugs throughout the package set. Nixpkgs is rather chaotic so this is not as unusual as “non-maintainer uploads” would be in other places.)

from orcania.

babelouest avatar babelouest commented on July 24, 2024

I have something that would work.

If I add the following lines in the CMakeLists.txt:


if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
  set(PKGCONFIG_TARGET_INCLUDES "${CMAKE_INSTALL_INCLUDEDIR}")
else()
  set(PKGCONFIG_TARGET_INCLUDES "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
endif()

if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
  set(PKGCONFIG_TARGET_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
else()
  set(PKGCONFIG_TARGET_LIBDIR "\${prefix}/${CMAKE_INSTALL_LIBDIR}")
endif()

And set the file liborcania.pc.in like that:

prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=@CMAKE_INSTALL_PREFIX@
libdir=@PKGCONFIG_TARGET_LIBDIR@
includedir=@PKGCONFIG_TARGET_INCLUDES@

Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
URL: @PROJECT_BUGREPORT_PATH@
Version: @LIBRARY_VERSION@
Requires: @PKGCONF_REQ@
Requires.private: @PKGCONF_REQ_PRIVATE@
Libs: -L${libdir} -lorcania @LIB_STATIC@
Cflags: -I${includedir}

Then, the file liborcania.pc content look like that:

$ # run cmake script with absolute paths for CMAKE_INSTALL_{INCLUDE,LIB}DIR
$ cmake -DCMAKE_INSTALL_PREFIX=/tmp/prefix -DCMAKE_INSTALL_INCLUDEDIR=/tmp/prefix-include -DCMAKE_INSTALL_LIBDIR=/tmp/prefix-lib ..
$ cat liborcania.pc
prefix=/tmp/prefix
exec_prefix=/tmp/prefix
libdir=/tmp/prefix-lib
includedir=/tmp/prefix-include

Name: orcania
Description: Potluck with different functions for different purposes that can be shared among programs
URL: https://github.com/babelouest/orcania/issues
Version: 2.2.2
Requires: 
Requires.private: 
Libs: -L${libdir} -lorcania 
Cflags: -I${includedir}
$ # run cmake script with relative paths for CMAKE_INSTALL_{INCLUDE,LIB}DIR
$ cmake ..
$ cat liborcania.pc
prefix=/usr/local
exec_prefix=/usr/local
libdir=${prefix}/lib
includedir=${prefix}/include

Name: orcania
Description: Potluck with different functions for different purposes that can be shared among programs
URL: https://github.com/babelouest/orcania/issues
Version: 2.2.2
Requires: 
Requires.private: 
Libs: -L${libdir} -lorcania 
Cflags: -I${includedir}

from orcania.

alexshpilkin avatar alexshpilkin commented on July 24, 2024

Yes, that should work, thank you :)

from orcania.

Related Issues (15)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.