I am working on a C project which I downloaded from the Internet.
I am trying to add some functions in which Eigen is to be used for linear algebra.
To that end, I added the following lines to the CMakeLists.txt :
PKG_CHECK_MODULES(EIGEN3 REQUIRED eigen3)
INCLUDE_DIRECTORIES(${EIGEN3_INCLUDE_DIRS})
LINK_DIRECTORIES(${EIGEN3_LIBRARY_DIRS})
ADD_EXECUTABLE(main main.c)
TARGET_LINK_LIBRARIES(main ${EIGEN3_LIBRARIES})
and I get no errors when running cmake . and then make
The issue is when I try to include <Eigen/Dense> in one of the c functions, I get the following error when I try to make:
/usr/include/eigen3/Eigen/Core:28:19: fatal error: complex: No such file or directory #include <complex>
Eigen/Dense includes Eigen/Core and Eigen/Core includes <complex>
I think it's just not looking in the correct directory to find complex... How to make it look there?
Eigen in C++ library, while your application source is C file (main.c). Since it has a .c extension, CMake threats it as C source and use C compiler, which doesn't know about C++ standard library (<complex>). Rename main.c to main.cpp.
Related
I am trying to build a very simple 'hello triangle' OpenGL application using CMake. I want to use find_package(GLEW) and the resulting imported target to link with Glew. When I run the make command, I am getting a 'No rule to make target' error.
According to the CMake documentation
https://cmake.org/cmake/help/latest/module/FindGLEW.html
https://cmake.org/cmake/help/latest/command/find_package.html
I can use find_package(GLEW) to return a target GLEW::GLEW which I will be able to use to link the Glew library to my code. When I run cmake .. everything builds and it reports that the glew-config.cmake file has been found.
-- Found GLEW: /usr/local/lib/cmake/glew/glew-config.cmake
I then run make and receive this error
$ make
Scanning dependencies of target test
[ 50%] Building CXX object CMakeFiles/test.dir/main.cpp.o
make[2]: *** No rule to make target `/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/OpenGL.framework', needed by `test'. Stop.'
I am running Mojave 10.14 and used homebrew to install cmake and glew which are both up to date. The path returned in the error above does not exist and I don't know where it is coming from.
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.15)
project(test)
find_package(GLEW REQUIRED)
add_executable(test main.cpp)
target_link_libraries(test GLEW::GLEW)
Here is my source code:
#include <GL/glew.h>
#include <iostream>
int main(int argc, char **argv){
std::cout << "Glew Test" << std::endl;
}
As you can see it is the bare minimum code needed to simply link Glew.
The problem seems to be similar to this question:
CMake FIND_PACKAGE succeeds but returns wrong path
However, in that case there was a solution using a command line flag specific to Boost. The only reference I have found regarding FindGLEW and problems with macOS is here:
https://gitlab.kitware.com/cmake/cmake/issues/19542
But that seems to have been resolved.
The problem I am having seems to be this path that FindGLEW.cmake is returning:
/Applications/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/OpenGL.framework
I have looked in the actual FindGLEW.cmake file to see if I could find the source of this path but I'm not an expert with CMake so got lost pretty quickly. How could I find the origin of this path? Are there any CMake flags or variables I can set to work around this similar to the Boost question above?
I have successfully linked with Glew using this CMakeLists.txt:
cmake_minimum_required(VERSION 3.15)
project(test)
find_library(GLEW_DYLIB GLEW "/usr/local/Cellar/glew/2.1.0/lib")
if(NOT GLEW_DYLIB)
message(FATAL_ERROR "Glew not found")
endif()
add_library(Glew_target SHARED IMPORTED)
set_property(TARGET Glew_target PROPERTY IMPORTED_LOCATION "/usr/local/Cellar/glew/2.1.0/lib/libGLEW.dylib")
set_property(TARGET Glew_target PROPERTY IMPORTED_IMPLIB ${GLEW_DYLIB})
include_directories(
"/usr/local/Cellar/glew/2.1.0/include/"
)
add_executable(test main.cpp)
target_link_libraries(test Glew_target)
However, I would prefer to keep things as simple as possible with find_package() as that is definitely the cleaner method.
EDIT: SOLVED - see Tsyvarev's comment below clarifying the nature of the glew-config file that CMake was finding above. I removed this file and rebuilt the project with no problems.
Question: How to add the standard library to arm-fslc-linux-gnueabi-gcc
Background:
I just had bitbake compile the meta-toolchain in the Yocto project.
I then installed the resulting SDK-toolchain
$
./build/tmp/deploy/sdk/fslc-framebuffer-glibc-x86_64-meta-toolchain-armv7at2hf-neon-toolchain-2.4.2.sh
which then installed the SDK-toolchain in /opt/fslc-framebuffer/2.4.2/
I can then easily run the executable to source the correct environment variables.
$
./opt/fslc-framebuffer/2.4.2/environment-setup-armv7at2hf-neon-fslc-linux-gnueabi
I now have access to the cross-compiler arm-fslc-linux-gnueabi-gcc
So far so good...
I then downloaded the barebone SDK from NXP here.
It's a great piece of work, but it might be somewhat outdated. First unzip the file, and then follow steps within the SDK readme.pdf.
Following the readme.pdf i do the following: To build the SDK, use the ./tools/build_sdk command from the root folder. I get multiple error but they are all related to the standard library such as:
iMX6_Platform_SDK/sdk/drivers/accelerometer/src/mma8451.c:31:10: fatal error: string.h: No such file or directory #include <string.h>
iMX6_Platform_SDK/sdk/include/sdk.h:40:10: fatal error: stdio.h: No such file or directory #include <stdio.h>
So how do I solve this? Do I cross compile the standard library or do I get the binary some other place?
SDK build by yocto is little bit different than normal arm toolchain.
I believe you used
arm-fslc-linux-gnueabi-gcc hello.c
but actually you need to use Makefiles or Macros like below,
${CC} hello.c -o hello
Write this directly into your terminal or put it into a makefile.
This question isn't specifically related to cross-compiling but has arisen as I have a problem related to architecture specific headers while trying to cross-compile a library.
I am trying to cross-compile OpenCV, the target is an ARM processor and I am compiling on an x86_64 processor. The build fails because a header file cannot be located:
/usr/include/zlib.h:34:19: fatal error: zconf.h: No
such file or directory #include "zconf.h"
Sure enough in zlib.h there is a reference to zconf.h:
#include "zconf.h"
However when I look under <path_to_arm_filesys>/usr/include I actually find zconf.h under <path_to_arm_filesys>/usr/include/arm-linux-gnueabihf directory. So as I understand it the C preprocessor won't find zconf.h as the reference to it does not include the reference to the architecture-specific sub-directory.
To try and understand how zconf.h is actually found, I referred to the host machine and where zconf.h is located. Similarly, it is located under /usr/include but under the architecture-specific x86_64-linux-gnu directory.
So if in the source code the is no specific reference to architecture (as to be expected) in any #include how does the (GNU) C pre-processor know where to look? Is it a case that the pre-processor already knows its architecture-target and can automatically append another architecture specific directory to all the include directories it knows about? Or must I specifically inform it with the use of the -I flag of these specific directories?
There are 3 ways to say the compiler where to find headers :
set the --sysroot option #preferred for cross-compilation
-sysroot=dir Use dir as the logical root directory for headers and libraries. For example, if the compiler normally searches for headers
in /usr/include and libraries in /usr/lib, it instead searches
dir/usr/include and dir/usr/lib.
In this case you must have all libraries and headers under the sysroot folder.
Directly say with -I options where to find the headers.
Set the C_INCLUDE_PATH/ CPLUS_INCLUDE_PATH env variables
For #include preprocessor will seachy in search system directories and directories that were provided by compiler.
For #include "filename" preprocessor will search in the same folder where you have file that have this include.
https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html
https://gcc.gnu.org/onlinedocs/gcc/Environment-Variables.html
I have included the boost library in a Codeblocks c++ project.
Now, in the file
boost/function.hpp
there is an include statement
#include <boost/preprocessor/iterate.hpp>
However I get this error in Codeblocks when I try and compile:
/home/arvind/Documents/Workspace/Browser/boost/function.hpp|15|fatal error:
boost/preprocessor/iterate.hpp: No such file or directory|
What am I doing wrong here? I have simply included the Boost library as it is.
Also, I cannot find the screen/option to set the main class (which will actually execute).
How do I do this?(I am new to CodeBlocks hence this question).
Your boost includes seem to be in a non-standard/system directory : /home/arvind/Documents/Workspace/Browser, you must tell the compiler to look there (gcc -I command-line switch).
Go to Project->Build Options->Search Directories->Compiler and add the directory where boost includes are. I don't have a codeblocks install right here so this was from here.
If you can, I would recommand installing boost on your system once and for all instead of just copying files in your codeblocks workspace.
I have a c function that I'd like to use but thats compiled with the Intel compiler instead of the gnu C compiler. I'm using cmake to build the program.
(I'm actually using ROS and hence rosmake but the base is cmake so I think its more of a cmake issue than a ROS issue).
Suppose the file built with icc is x.c and produces an x.s file. I want to use the function a() from x.c in my file y.cpp.
In y.cpp I have:
#include "x.h"
.....
call a()
which works if CMakeLists.txt has
rosbuild_add_executable(y y.cpp x.c)
rosbuild_add_executable is analogous to add_executable(...)
but if I build x.c with icc and try to include the x.s file instead:
rosbuild_add_executable(y y.cpp x.s)
It doesnt work. Is there some change I should make to the way I call a() in y.cpp? or is there some other way to link it.
When using gcc, you can compile .S files with your C compiler (no explicit invocation of asm needed). CMake can be told to do so using
set_property(SOURCE <myfile>.S PROPERTY LANGUAGE C)
for each of your .S files.
To work with .s files you'll have to enable assembly language support in CMake with enable_language.
You can find more information here: https://gitlab.kitware.com/cmake/community/-/wikis/doc/cmake/languages/Assembler