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!!!
CodePudding user response:
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.
CodePudding user response:
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.
CodePudding user response:
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
Boost
How do you add Boost libraries in CMakeLists.txt?
nlohmann/json
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)