mpusz / mp-units

The quantities and units library for C++
https://mpusz.github.io/mp-units/
MIT License
1.07k stars 85 forks source link

Failed to follow conan + CMake instructions #436

Closed correaa closed 1 year ago

correaa commented 1 year ago

I am trying to follow the conan + CMake instructions as best as I can.

First some environment information:

$ cmake --version
cmake version 3.25.2

$ conan --version
Conan version 1.58.0

$ cat ~/.conan/profiles/default 
[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=12
compiler.cppstd=20

My very simple project looks like this:

$ cat CMakeLists.txt 
cmake_minimum_required(VERSION 3.24)

project(
  my_project
  LANGUAGES CXX)

find_package(mp-units CONFIG REQUIRED)

add_executable(my_program my_program.cpp)

target_link_libraries(my_program PUBLIC mp-units::mp-units)
$ cat conanfile.txt 
[requires]
mp-units/0.7.0

[generators]
CMakeToolchain
CMakeDeps

I am just including some units headers:

$ cat my_program.cpp 
#include <units/quantity_io.h>
#include <units/isq/si/mass.h>
#include <units/isq/si/length.h>

int main(int /*argc*/, char ** /*argv*/) {
}

These are the actions I do:

$ mkdir build && cd build

$ conan install .. -pr:b=default -s compiler.cppstd=20 -b=missing
Configuration (profile_host):
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.libcxx=libstdc++
compiler.version=12
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

Configuration (profile_build):
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.libcxx=libstdc++
compiler.version=12
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

conanfile.txt: Installing package
Requirements
    fmt/7.1.3 from 'conancenter' - Cache
    gsl-lite/0.38.0 from 'conancenter' - Cache
    mp-units/0.7.0 from 'conancenter' - Cache
Packages
    fmt/7.1.3:024cb7f7720796c66e6113005f88dba545be8833 - Cache
    gsl-lite/0.38.0:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache
    mp-units/0.7.0:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache

Installing (downloading, building) binaries...
fmt/7.1.3: Already installed!
gsl-lite/0.38.0: Already installed!
mp-units/0.7.0: Already installed!
conanfile.txt: Generator txt created conanbuildinfo.txt
conanfile.txt: Generator 'CMakeToolchain' calling 'generate()'
conanfile.txt: Preset 'release' added to CMakePresets.json. Invoke it manually using 'cmake --preset release'
conanfile.txt: If your CMake version is not compatible with CMakePresets (<3.19) call cmake like: 'cmake <path> -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=/home/correaa/boron_hydride/ground_state/build/conan_toolchain.cmake -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release'
conanfile.txt: Generator 'CMakeDeps' calling 'generate()'
conanfile.txt: Aggregating env generators
conanfile.txt: Generated conaninfo.txt
conanfile.txt: Generated graphinfo
$ cmake ..  -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake
-- Using Conan toolchain: /home/correaa/boron_hydride/ground_state/build/conan_toolchain.cmake
-- Conan toolchain: C++ Standard 20 with extensions OFF
-- Conan: Component target declared 'mp-units::core'
...
-- Conan: Component target declared 'mp-units::systems'
-- Conan: Target declared 'mp-units::mp-units'
-- Conan: Component target declared 'gsl::gsl-lite'
-- Conan: Component target declared 'fmt::fmt'
-- Configuring done
-- Generating done
-- Build files have been written to: /home/correaa/boron_hydride/ground_state/build

So far so good, however when trying to make it doesn't find the include directory:

$ make VERBOSE=1
/usr/bin/cmake -S/home/correaa/boron_hydride/ground_state -B/home/correaa/boron_hydride/ground_state/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/correaa/boron_hydride/ground_state/build/CMakeFiles /home/correaa/boron_hydride/ground_state/build//CMakeFiles/progress.marks
make  -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/correaa/boron_hydride/ground_state/build'
make  -f CMakeFiles/my_program.dir/build.make CMakeFiles/my_program.dir/depend
make[2]: Entering directory '/home/correaa/boron_hydride/ground_state/build'
cd /home/correaa/boron_hydride/ground_state/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/correaa/boron_hydride/ground_state /home/correaa/boron_hydride/ground_state /home/correaa/boron_hydride/ground_state/build /home/correaa/boron_hydride/ground_state/build /home/correaa/boron_hydride/ground_state/build/CMakeFiles/my_program.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/correaa/boron_hydride/ground_state/build'
make  -f CMakeFiles/my_program.dir/build.make CMakeFiles/my_program.dir/build
make[2]: Entering directory '/home/correaa/boron_hydride/ground_state/build'
[ 50%] Building CXX object CMakeFiles/my_program.dir/my_program.cpp.o
/usr/bin/c++ -D_GLIBCXX_USE_CXX11_ABI=0  -m64 -O3 -DNDEBUG -std=c++20 -MD -MT CMakeFiles/my_program.dir/my_program.cpp.o -MF CMakeFiles/my_program.dir/my_program.cpp.o.d -o CMakeFiles/my_program.dir/my_program.cpp.o -c /home/correaa/boron_hydride/ground_state/my_program.cpp
/home/correaa/boron_hydride/ground_state/my_program.cpp:1:10: fatal error: units/quantity_io.h: No such file or directory
    1 | #include <units/quantity_io.h>
      |          ^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/my_program.dir/build.make:76: CMakeFiles/my_program.dir/my_program.cpp.o] Error 1
make[2]: Leaving directory '/home/correaa/boron_hydride/ground_state/build'
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/my_program.dir/all] Error 2
make[1]: Leaving directory '/home/correaa/boron_hydride/ground_state/build'
make: *** [Makefile:91: all] Error 2

Am I missing something, the header file of course exists in ~/.conan/ ... /3431243124132112/ ... /units/quantity_io.h.

mpusz commented 1 year ago

Hi @correaa! Thanks a lot for the interest in the library πŸ˜ƒ

If I recall properly, at some point, Conan stopped to specify a CMAKE_BUILD_TYPE in the toolchain file, and you did not provide it for your CMake generator. I see you are using make so a single-configuration generator in CMake ("Unix Makefiles"). In such a case you should provide it during configure step with -DCMAKE_BUILD_TYPE=Release. "Unnamed" build type is not the same as "Release" in CMake. Please try it, and I hope it will help.

correaa commented 1 year ago

Your library looks great. I have some (uncalled) feedback about it, but first I have to make it work.

I have using and abusing Boost.Units so far, even create whole custom units systems for chemistry and materials (a lot of "nonSI" units and ad hoc unit systems, like atomic units and matter units, like "mole", "atoms/molecules/species".

Yes, I understand what you are saying (I learned it from one of your talks.) Sorry, I have to use make, since this is going to be for a larger system that uses make I need to make it work with make first.

I tried setting up the -DCMAKE_BUILD_TYPE=Release but I get the same error. See the cmake line below, I started from scratch again.

$ rm -rf build
$ mkdir build
$ cd build/
$ conan install .. -pr:b=default -s compiler.cppstd=20 -b=missing
Configuration (profile_host):
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.libcxx=libstdc++
compiler.version=12
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

Configuration (profile_build):
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.libcxx=libstdc++
compiler.version=12
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

conanfile.txt: Installing package
Requirements
    fmt/7.1.3 from 'conancenter' - Cache
    gsl-lite/0.38.0 from 'conancenter' - Cache
    mp-units/0.7.0 from 'conancenter' - Cache
Packages
    fmt/7.1.3:024cb7f7720796c66e6113005f88dba545be8833 - Cache
    gsl-lite/0.38.0:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache
    mp-units/0.7.0:5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9 - Cache

Installing (downloading, building) binaries...
fmt/7.1.3: Already installed!
gsl-lite/0.38.0: Already installed!
mp-units/0.7.0: Already installed!
conanfile.txt: Generator 'CMakeDeps' calling 'generate()'
conanfile.txt: Generator 'CMakeToolchain' calling 'generate()'
conanfile.txt: Preset 'release' added to CMakePresets.json. Invoke it manually using 'cmake --preset release'
conanfile.txt: If your CMake version is not compatible with CMakePresets (<3.19) call cmake like: 'cmake <path> -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=/home/correaa/boron_hydride/ground_state/build/conan_toolchain.cmake -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release'
conanfile.txt: Generator txt created conanbuildinfo.txt
conanfile.txt: Aggregating env generators
conanfile.txt: Generated conaninfo.txt
conanfile.txt: Generated graphinfo
$ cmake .. -DCMAKE_BUILD_TYPE=Release  -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake
-- Using Conan toolchain: /home/correaa/boron_hydride/ground_state/build/conan_toolchain.cmake
-- Conan toolchain: C++ Standard 20 with extensions OFF
-- The CXX compiler identification is GNU 12.2.1
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: Component target declared 'mp-units::core'
-- Conan: Component target declared 'mp-units::core-io'
-- Conan: Component target declared 'mp-units::core-fmt'
-- Conan: Component target declared 'mp-units::isq'
-- Conan: Component target declared 'mp-units::isq-natural'
-- Conan: Component target declared 'mp-units::si'
-- Conan: Component target declared 'mp-units::si-cgs'
-- Conan: Component target declared 'mp-units::si-fps'
-- Conan: Component target declared 'mp-units::si-iau'
-- Conan: Component target declared 'mp-units::si-imperial'
-- Conan: Component target declared 'mp-units::si-international'
-- Conan: Component target declared 'mp-units::si-typographic'
-- Conan: Component target declared 'mp-units::si-uscs'
-- Conan: Component target declared 'mp-units::isq-iec80000'
-- Conan: Component target declared 'mp-units::systems'
-- Conan: Target declared 'mp-units::mp-units'
-- Conan: Component target declared 'gsl::gsl-lite'
-- Conan: Component target declared 'fmt::fmt'
-- Configuring done
-- Generating done
-- Build files have been written to: /home/correaa/boron_hydride/ground_state/build
$ make VERBOSE=1
/usr/bin/cmake -S/home/correaa/boron_hydride/ground_state -B/home/correaa/boron_hydride/ground_state/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/correaa/boron_hydride/ground_state/build/CMakeFiles /home/correaa/boron_hydride/ground_state/build//CMakeFiles/progress.marks
make  -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/correaa/boron_hydride/ground_state/build'
make  -f CMakeFiles/my_program.dir/build.make CMakeFiles/my_program.dir/depend
make[2]: Entering directory '/home/correaa/boron_hydride/ground_state/build'
cd /home/correaa/boron_hydride/ground_state/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/correaa/boron_hydride/ground_state /home/correaa/boron_hydride/ground_state /home/correaa/boron_hydride/ground_state/build /home/correaa/boron_hydride/ground_state/build /home/correaa/boron_hydride/ground_state/build/CMakeFiles/my_program.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/correaa/boron_hydride/ground_state/build'
make  -f CMakeFiles/my_program.dir/build.make CMakeFiles/my_program.dir/build
make[2]: Entering directory '/home/correaa/boron_hydride/ground_state/build'
[ 50%] Building CXX object CMakeFiles/my_program.dir/my_program.cpp.o
/usr/bin/c++ -D_GLIBCXX_USE_CXX11_ABI=0  -m64 -O3 -DNDEBUG -std=c++20 -MD -MT CMakeFiles/my_program.dir/my_program.cpp.o -MF CMakeFiles/my_program.dir/my_program.cpp.o.d -o CMakeFiles/my_program.dir/my_program.cpp.o -c /home/correaa/boron_hydride/ground_state/my_program.cpp
/home/correaa/boron_hydride/ground_state/my_program.cpp:1:10: fatal error: units/quantity_io.h: No such file or directory
    1 | #include <units/quantity_io.h>
      |          ^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/my_program.dir/build.make:76: CMakeFiles/my_program.dir/my_program.cpp.o] Error 1
make[2]: Leaving directory '/home/correaa/boron_hydride/ground_state/build'
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/my_program.dir/all] Error 2
make[1]: Leaving directory '/home/correaa/boron_hydride/ground_state/build'
make: *** [Makefile:91: all] Error 2
mpusz commented 1 year ago

I just created a project based on your files and used the exact lines you are using. Unfortunately, it worked for me 😒 The only difference I noticed is that you do not use libstdc++11 in a Conan profile, but that should result in possible linkage issues rather than a not found header file. Could you please check if cmake --build . works for you instead of make? If not, can you try cmake --build . --config Release as well?

correaa commented 1 year ago

I think something was wrong with the ~/.conan directory I deleted it and followed the instructions again and it worked.

[correaa@PROART build]$ conan --version
Conan version 1.58.0
[correaa@PROART build]$ cat ~/.conan/profiles/default 
[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=12
compiler.libcxx=libstdc++
build_type=Release
[options]
[build_requires]
[env]
correaa commented 1 year ago

Sorry to come back to this. Part of the problem, now I see, is that sometimes I was forgetting to set -DCMAKE_BUILD_TYPE=Release and I was setting -DCMAKE_BUILD_TYPE=Debug.

When I use Debug the compilation simply fails, it can't find a header:

/builds/project-0/ground_state/ground_state.cpp:5:10: fatal error: units/quantity_io.h: No such file or directory
    5 | #include <units/quantity_io.h>
      |          ^~~~~~~~~~~~~~~~~~~~~

I tried in a fresh docker image and this is the only change I make (Release->Debug).

What do I have to do to build my program in debug mode?

mpusz commented 1 year ago

No worries πŸ˜„

If you want Conan to provide debug dependencies you should either use -s build_type=Debug in the command line or create a dedicated profile file for such configuration and set an appropriate field to Debug there.

correaa commented 1 year ago

Do you mean in the line conan install .. -pr:b=default -s compiler.cppstd=20 -b=missing?

Should install the library twice?

$ conan install .. -pr:b=default -s build_type=Debug compiler.cppstd=20 -b=missing
$ conan install .. -pr:b=default -s build_type=Release compiler.cppstd=20 -b=missing

I guess you recommend always specifying the build type then in cmake (or cmake --build (with multiconfig)).

mpusz commented 1 year ago

You can run both Conan lines in case you use multi-config CMake generator (i.e. Ninja Multi-Config). In case you use Makefile or Ninja as a CMake generator, you should use separate build directories for those anyway (i.e. build_release, build_debug). Otherwise, CMake will be confused or you will have to clear cache and reconfigure all the time.

correaa commented 1 year ago

Ah, yes, I meant that. I have to be consistent within each build directory also. It seems tricky to enforce that. I should stop insisting on using make.

mpusz commented 1 year ago

Ninja is much faster πŸ˜„

But I think that is not a big issue. If you will create two named separate directories for release and debug builds then you have to call Conan only once before the first CMake build, and then you do not have to use Canon anymore (unless some dependency needs to be updated).