facebook / folly

An open-source C++ library developed and used at Facebook.
https://groups.google.com/forum/?fromgroups#!forum/facebook-folly
Apache License 2.0
27.88k stars 5.51k forks source link

Installing with cmake #2165

Open thetazero opened 5 months ago

thetazero commented 5 months ago

Having a lot of trouble installing this project into an existing cmake project. There is a decent chance that this is just a lack of CMake knowledge on my end, but I do believe the install instructions are quite difficult for beginners. Happy to help write a installation guide for beginners like me (if you think it's useful) if someone could help point me in the right direction. OS: Ubuntu 22.04.4 LTS

Wrote a shell script to do the building for me, to make my issues reproducible.

mv install /tmp
cd folly
git checkout main
git pull
mkdir -p install
sudo ./build/fbcode_builder/getdeps.py install-system-deps --recursive
python3 ./build/fbcode_builder/getdeps.py --allow-system-packages build
# python3 ./build/fbcode_builder/getdeps.py --allow-system-packages test
FOLLY_PATH=$(python3 ./build/fbcode_builder/getdeps.py show-build-dir)
cp -r $FOLLY_PATH/../../installed/ ../install

cd ..
mv install/fmt*/ install/fmt
mv install/googletest* install/googletest

Put this in the cmake to try and put it together.

find_package(Gflags CONFIG REQUIRED)

set_target_properties(gflags_shared PROPERTIES
        MAP_IMPORTED_CONFIG_DEBUG Release
)
find_package(folly REQUIRED)
set_and_check(FOLLY_INCLUDE_DIR /home/thetazero/research/new_stuff/run_all_benchmarks/install/folly/include)
set_and_check(FOLLY_INCLUDE_DIR /home/thetazero/research/new_stuff/run_all_benchmarks/install/folly/lib/cmake/folly)
if (NOT TARGET Folly::folly)
  include("${FOLLY_CMAKE_DIR}/folly-targets.cmake")
endif()

set(FOLLY_LIBRARIES Folly::folly)

if (NOT folly_FIND_QUIETLY)
  message(STATUS "Found folly: ${PACKAGE_PREFIX_DIR}")
endif()
target_link_libraries(cdrc INTERFACE ${FOLLY_LIBRARIES})

Getting the following error (yes the directories are correct/exist I triple checked)

CMake Error at CMakeLists.txt:136 (find_package):
  By not providing "Findfolly.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "folly", but
  CMake did not find one.

  Could not find a package configuration file provided by "folly" with any of
  the following names:

    follyConfig.cmake
    folly-config.cmake

  Add the installation prefix of "folly" to CMAKE_PREFIX_PATH or set
  "folly_DIR" to a directory containing one of the above files.  If "folly"
  provides a separate development package or SDK, be sure it has been
  installed.
kuro337 commented 3 months ago

@thetazero So you are trying to use that CMake file and call the script to build Folly on your machine?

I believe you should just be able to run a make command and use the provided files to build it.

1 - Install Folly on your system (dont need to create your own CMake file for this)

2 - Use the Installed library

1. installing

For example


git clone https://github.com/facebook/folly && cd folly/build

# here you pass flags according to your system

cmake \
-DBUILD_BENCHMARKS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=20 \
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..

So I use a non standard Compiler and if particular Libraries Folly requires aren't in your Path - you need to provide it explicitly in the cmake command so the dependencies can be found for linking

In my case - I use clang and OpenSSL and this differs for my system - if you don't have multiple C++ and C compilers installed you won't need those steps

This the command I use based off of my toolchain - same command works for me on both Linux and MacOS (adjusting paths)

# set openssl path , it was picking up GStreamer OpenSSL
cmake \
-DCMAKE_CXX_COMPILER=/opt/homebrew/opt/llvm/bin/clang++ \
-DCMAKE_C_COMPILER=/opt/homebrew/opt/llvm/bin/clang \
-DCMAKE_CXX_FLAGS="-O3 -stdlib=libc++ -I/opt/homebrew/opt/llvm/include" \
-DCMAKE_EXE_LINKER_FLAGS="-L/opt/homebrew/opt/llvm/lib" \
-DBUILD_BENCHMARKS=ON \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_STANDARD=20 \
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
-DOPENSSL_ROOT_DIR=/opt/homebrew/openssl@3/3.2.1 \
-DCMAKE_EXE_LINKER_FLAGS="-L/opt/homebrew/opt/llvm/lib -L/opt/homebrew/Cellar/openssl@3/3.2.1/lib -lssl -lcrypto" \
-DOPENSSL_INCLUDE_DIR=/opt/homebrew/opt/openssl@3/include \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..

make all  # build everything and confirm tests pass
sudo make install   # install to /usr/local finally

2. Using the built library

It will take some while to build - once it succeeds and tests pass

You can then import and use Folly libraries in your code

Example CMakeLists.txt file to bring it all together

cmake_minimum_required(VERSION 3.20)
project(FollyconcurrentMap)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

find_package(Folly CONFIG REQUIRED)
find_package(gflags CONFIG REQUIRED)

# gtest
include(FetchContent)
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
  DOWNLOAD_EXTRACT_TIMESTAMP TRUE  
)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) # windows setting
FetchContent_MakeAvailable(googletest)

# The path to the C++ file should be relative to where this CMakeLists.txt file is
add_executable(
 atomic 
 atomic.cc
)

target_link_libraries(
  atomic
  PUBLIC GTest::gtest_main
  PUBLIC Folly::folly
)

# From where your CMakeLists.txt file is - run this 

# mkdir build
# cd build
# cmake ..
# cmake --build .
# then go to bin and run your app ./atomic

Assuming your atomic.cc file looks something like this

#include <folly/AtomicUnorderedMap.h>

int main(int argc, char *argv[]) {
  folly::AtomicUnorderedInsertMap<int, std::string> atomicMap(100); 
  ....
  ....
}

But on Ubuntu - you don't have to build from source too - you can skip the 1st part I mentioned

and simply use sudo apt install -y libfolly-dev to install it - then start using it (step 2 and onwards)

kuro337 commented 3 months ago

Put this in the cmake to try and put it together.

find_package(Gflags CONFIG REQUIRED)

set_target_properties(gflags_shared PROPERTIES
        MAP_IMPORTED_CONFIG_DEBUG Release
)
find_package(folly REQUIRED)
set_and_check(FOLLY_INCLUDE_DIR /home/thetazero/research/new_stuff/run_all_benchmarks/install/folly/include)
set_and_check(FOLLY_INCLUDE_DIR /home/thetazero/research/new_stuff/run_all_benchmarks/install/folly/lib/cmake/folly)
if (NOT TARGET Folly::folly)
  include("${FOLLY_CMAKE_DIR}/folly-targets.cmake")
endif()

set(FOLLY_LIBRARIES Folly::folly)

if (NOT folly_FIND_QUIETLY)
  message(STATUS "Found folly: ${PACKAGE_PREFIX_DIR}")
endif()
target_link_libraries(cdrc INTERFACE ${FOLLY_LIBRARIES})

Getting the following error (yes the directories are correct/exist I triple checked)

CMake Error at CMakeLists.txt:136 (find_package):
  By not providing "Findfolly.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "folly", but
  CMake did not find one.

  Could not find a package configuration file provided by "folly" with any of
  the following names:

    follyConfig.cmake
    folly-config.cmake

  Add the installation prefix of "folly" to CMAKE_PREFIX_PATH or set
  "folly_DIR" to a directory containing one of the above files.  If "folly"
  provides a separate development package or SDK, be sure it has been
  installed.

(Will note as a preface I am not a core maintainer and not an expert about the Library and CMake)

So here - I think you are trying to do 2 things at once -

  1. Build and Install Folly
  2. Use it
find_package(folly REQUIRED)

This means "CMake - find the installed Folly on my System" (by looking for the provided .cmake files generated once it is installed)

set(FOLLY_LIBRARIES Folly::folly)

If find_package is successful - then you will be able to use the variables FOLLY_LIBRARIES and Folly::folly , etc.

target_link_libraries(cdrc INTERFACE ${FOLLY_LIBRARIES})

This is the crucial part - it will Link the necessary library to your Code

Linking basically is - a way for the code you write to actually use any other code you write by using the Generated .so or .a files during your build.

So I am not sure if that is the correct way of approaching this - I believe for find_package and target_link_libraries to work you must have Folly actually installed on your System first

good luck!