I am beginner in arm build. I want to build this code for armel platform. I have a code:
#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <nlohmann/json.hpp>
int main()
{
return 0;
}
Also I have Cmake file:
cmake_minimum_required(VERSION 2.8.10 FATAL_ERROR)
project(test CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++-10)
set(SRC_FILES test.cpp)
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY)
add_definitions(-DBOOST_SYSTEM_NO_DEPRECATED)
add_definitions(-DBOOST_ALL_NO_LIB)
add_definitions(-DBOOST_NO_RTTI)
add_definitions(-DBOOST_NO_TYPEID)
add_definitions(-DBOOST_ASIO_DISABLE_THREADS)
add_executable(${PROJECT_NAME} ${SRC_FILES})
I install nlohmann library into:
/usr/local/include/nlohmann/json.hpp
After I generate make and make:
/home/test-machine/project-dir/test/test.cpp:3:10: fatal error: nlohmann/json.hpp: No such file or directory
3 | #include <nlohmann/json.hpp>
| ^~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [CMakeFiles/test.dir/build.make:82: CMakeFiles/test.dir/test.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:95: CMakeFiles/test.dir/all] Error 2
make: *** [Makefile:103: all] Error 2
Why I have this error. Help me pls!!!
It seems to me that the more correct way would be to properly install library and then use the find_package directive.
# CMakeLists.txt
find_package(nlohmann_json 3.2.0 REQUIRED)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)
Example above is a part of nlohmann Cmake documentation.
With non native compilers, you must configure the whole environment.
In fact, when doing so, I would highly suggest using a toolchain file.
Using that you can setup your toolchain, or even multiple toolchain.
Then, for the environment, I would suggest installing the libraries using their installer and let CMake find it. Take nlohmann json for example:
nlohmann_json$ mkdir build
nlohmann_json$ cd build
nlohmann_json/build$ cmake .. -DCMAKE_INSTALL_PREFIX=/home/youruser/arm-prefix -DCMAKE_TOOLCHAIN_FILE=yourtoolchain.cmake
nlohmann_json/build$ cmake --build . --target install
Those command will setup nlohmann json with your toolchain, and will install it in a new prefix.
Then, in your project, you can have such toolchain and such CMakeLists.txt file:
toolchain.cmake:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++-10)
set(CMAKE_C_COMPILER arm-linux-gnueabi-gcc-10)
set(CMAKE_STAGING_PREFIX /home/youruser/arm-prefix)
set(CMAKE_SYSTEM_PREFIX_PATH /home/youruser/arm-prefix)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
CMakeLists.txt:
project(test CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(test)
find_package(nlohmann_json REQUIRED)
target_sources(test PRIVATE test.cpp)
target_link_libraries(test PUBLIC nlohmann_json::nlohmann_json)
The magic lies in the prefix path. When you set an install prefix to install libraries into and you set the same prefix path when building your project, find_package suddenly works. If you use the same toolchain between those two projects, then CMake will detect those two packages as compatible.
Notice that I also explicitly didn't used variables in the CMakeLists file. This is because variables are a pain point of CMake and results in unexpected behaviour. In normal CMake file to define a project, their usage should be rare.
Also, stay away from add_definitions, link_directories, include_directories and all of those. Always prefer target_compile_definitions, target_link_libraries, target_include_directories and other target based commands.
As for boost I don't know their build system very well. There might be ways to cross compile the library and install it, but my knowledge ends here.
There are some problems with your code. If you don't mind I'll be using newer CMake.
# CMakeLists.txt
cmake_minimum_required(VERSION 3.13)
project(test LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(foobar)
target_sources(foobar PRIVATE
test.cpp
)
target_compile_definitions(foobar PRIVATE
BOOST_ERROR_CODE_HEADER_ONLY
BOOST_SYSTEM_NO_DEPRECATED
BOOST_ALL_NO_LIB
BOOST_NO_RTTI
BOOST_NO_TYPEID
BOOST_ASIO_DISABLE_THREADS
)
To specify your ARM compiler use a CMAKE_TOOLCHAIN_FILE. If you specify your compiler in your CMake code it might be nice at first but will cause issues later down the road.
# arm.cmake
set(CMAKE_CXX_COMPILER arm-linux-gnueabi-g++-10)
set(CMAKE_C_COMPILER arm-linux-gnueabi-g-10)
Now when you make your project do the following:
cd <your-project>
cmake -S . -B build/ -D CMAKE_TOOLCHAIN_FILE=arm.cmake
Now the issue remaining with your code is that you have no way to find your third party dependencies.
You need to add code to find/link boost. And find/link nlohmann/json
How do you add Boost libraries in CMakeLists.txt?
This repo actually has pretty good docs on how to add the library to your CMake project.
https://github.com/nlohmann/json#cmake
TLDR:
To use this library from a CMake project, you can locate it directly with find_package() and use the namespaced imported target from the generated package configuration:
# CMakeLists.txt
find_package(nlohmann_json 3.2.0 REQUIRED)
...
add_library(foo ...)
...
target_link_libraries(foo PRIVATE nlohmann_json::nlohmann_json)