I have an embedded C project that builds and runs just fine using make on the console, but Eclipse CDT is giving me errors.
In main.c, this function uses a macro, APP_BUTTON_INIT:
static void buttons_init(void)
{
static app_button_cfg_t buttons[] =
{
{SIGNAL_ALERT_BUTTON, false, NRF_GPIO_PIN_NOPULL, button_event_handler},
{BONDMNGR_DELETE_BUTTON_PIN_NO, false, NRF_GPIO_PIN_NOPULL, NULL}
};
APP_BUTTON_INIT(buttons, sizeof(buttons) / sizeof(buttons[0]), BUTTON_DETECTION_DELAY, false);
}
The APP_BUTTON_INIT macro is defined in app_button.h like this:
#define APP_BUTTON_INIT(BUTTONS, BUTTON_COUNT, DETECTION_DELAY, USE_SCHEDULER) \
do \
{ \
uint32_t ERR_CODE = app_button_init((BUTTONS), \
(BUTTON_COUNT), \
(DETECTION_DELAY), \
(USE_SCHEDULER) ? app_button_evt_schedule : NULL); \
APP_ERROR_CHECK(ERR_CODE); \
} while (0)
The error is
Symbol 'app_button_evt_schedule' could not be resolved
But that function is defined further down in the very same header file, app_button.h:
static __INLINE uint32_t app_button_evt_schedule(app_button_handler_t button_handler,
uint8_t pin_no)
{
app_button_event_t buttons_event;
buttons_event.button_handler = button_handler;
buttons_event.pin_no = pin_no;
return app_sched_event_put(&buttons_event, sizeof(buttons_event), app_button_evt_get);
}
I've tried Project right click -> Index -> Rebuild and Freshen all files, no joy. I'm using Eclipse Kepler SR1 with CDT 8.2.1. Why can't Eclipse see this function?
The first operation of the Makefile is this (this works):
mkdir _build
"/Users/Eliot/dev/gcc-arm/bin/arm-none-eabi-gcc" -DNRF51822_QFAA_CA -mcpu=cortex-m0 -mthumb -mabi=aapcs -DNRF51 -DBOARD_NRF6310 -DNRF51822_QFAA_CA --std=gnu99 -Wall -Werror -mfloat-abi=soft -DDEBUG -g3 -O0 -I"/Users/Eliot/dev/nrf51822/Include/ble" -I"/Users/Eliot/dev/nrf51822/Include/ble/softdevice" -I"/Users/Eliot/dev/nrf51822/Include/app_common" -I"/Users/Eliot/dev/nrf51822/Include/ble/ble_services" -I"../" -I"/Users/Eliot/dev/nrf51822/Include" -I"/Users/Eliot/dev/nrf51822/Include/gcc" -I"/Users/Eliot/dev/nrf51822/Include/ext_sensors" -M ../main.c -MF "_build/main.d" -MT _build/main.o
Screenshots for my CDT project config for includes, symbols and the tool chain are here:
https://dl.dropboxusercontent.com/u/12173473/screenshot_cdt_includes.png
https://dl.dropboxusercontent.com/u/12173473/screenshot_cdt_symbols.png
https://dl.dropboxusercontent.com/u/12173473/screenshot_cdt_toolchain.png
I'm not using a toolchain because my project started out as the sample CDT project from the hardware manufacturer (Nordic Semiconductor) and that project also had no toolchain configured. To be honest, I doubt CDT is finding the right gcc executable.
Your Eclipse project must reflect the same behavior as your makefile.
Match the output of make (i.e. the calls to gcc or whatever compiler and linker you are using) with your Eclipse project settings at Properties > C/C++ Build > Settings. I would start looking at the include paths (-I) and the defined symbols (-D), and then at the other flags.
Unfortunately, Eclipse is not very clever in importing projects from makefiles, nor at resolving compiler and linker settings from external build tools.
Running around without a proper toolchain configured in Eclipse was the problem. For ARM development using cross gcc, this Eclipse plugin fixed my problem and looks promising in general. It gives you Eclipse project settings for the whole toolchain and means you can ditch your makefiles.
http://gnuarmeclipse.github.io
Related
I'm trying to link the c++ library, libraw, into my c program.
windows 10 msys2. Using clion, but also trying to compile from mingw64 terminal using gcc and clang
At first, I was using the version of libraw that i got from msys2 pacman. The issue is that the version in the repo is the latest release, but it is quite old and I need the beta release of libraw to support one of my newer cameras.
I've built the libraries from source (https://github.com/LibRaw/LibRaw) in mingw, and moved the libraw.a file, and .h files into the mingw64/lib and /include folder respectively, just as they appeared when added using pacman.
The issue is that now when I compile, a long list of errors is spit out including things such as undefined references to '__cxa'
I'm wondering what is causing these compile errors and what I can do to fix them, so that I can use libraw in my project. I assume it has something to do with how I'm compiling libraw, since using the version from pacman, the exact same c and cmake code works perfectly.
Here a simplified version of my c program (note that libtiff is working just fine, can can be ignored from the samples):
#include <stdio.h>
#include <tiffio.h>
#include <libraw.h>
int main(void);
int main(void)
{
const char* libtiffVersion;
const char* librawVersion;
libtiffVersion = TIFFGetVersion();
if(libtiffVersion)
printf("%s\n", libtiffVersion);
else
printf("libtiff not found!\n");
librawVersion = libraw_version();
if(librawVersion)
printf("%s\n", librawVersion);
else
printf("libraw not found!\n");
return 0;
}
and my cmake (tried with various c standards from 90 to 23, although i don't think it mattres):
cmake_minimum_required(VERSION 3.23)
project(MyProject C)
set(CMAKE_C_STANDARD 90)
find_library(LIBRAW libraw)
find_library(LIBTIFF libtiff)
add_executable(MyProject main.c)
target_link_libraries(MyProject ${LIBTIFF} ${LIBRAW})
The linker command generated by cmake is:
cmd.exe /C "cd . && C:\msys64\mingw64\bin\gcc.exe -g CMakeFiles/MyProject.dir/main.c.obj -o MyProject.exe -Wl,--out-implib,libMyProject.dll.a -Wl,--major-image-version,0,--minor-image-version,0 C:/msys64/mingw64/lib/libtiff.dll.a C:/msys64/mingw64/lib/libraw.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
I read that what could be causing some of the issue, is that libraw is a c++ library (includes a c wrapper), while I'm trying to compile a c program, but trying to compile from the command line with g++, clang++, gcc with -lsupc++ with no luck. doing it this way gives me different errors, many of them including undefined reference to '__imp'
I've also tried copying the libraw.a file into my source directory compiling with a path to the .a file, with the no success.
I've tried using the binary release of the older version of libraw that I know was working, by copying the libraw.lib file to my source directory and changing my cmake file:
cmake_minimum_required(VERSION 3.23)
project(MyProject C)
set(CMAKE_C_STANDARD 90)
find_library(LIBTIFF libtiff)
add_executable(MyProject main.c)
target_link_libraries(MyProject ${LIBTIFF} ${PROJECT_SOURCE_DIR}/libraw.lib)
This time it compiles, but immediatly segfualts. Might have something to do with the binaries being built for windows using msvc while in using msys2/mingw64
I have a C file, which uses multiple lib files.
I am trying to compile the file in the following way:
gcc -o myprogram main.c list.lib filelib.lib
However, when trying to compile I get a bunch of undefined reference errors of all the lib functions that I'm using.
I came accross a solution on the internet and tried the following:
gcc -o myprogram main.c -l list -l filelib
Now I get the following errors:
cannot find -llist
cannot fint -lfilelib
What am I doing wrong?
Edit:
Both the libs were originally created using Visual Studio 2019, Release mode x64.
I am using Windows 10, 64 bits architecture.
In the folder I'm running gcc from I have the following files:
main.c
list.lib (copied from VS)
list.h (copied form VS)
filelib.lib (copied from VS)
filelib.h (copied from VS)
In my lib code in VS I made sure the functions have c-linkage:
#ifdef __cplusplus
#define C_LINKAGE extern "C"
#else
#define C_LINKAGE
#endif
(each declared function in both the libs starts with the C_LINKAGE macro)
The .lib files are MSVC specific, gcc can not handle them, gcc can handle .a libraries or dll's (on windows)
If you want to use gcc, rebuild the libraries with gcc, or let MSVC create DLL's.
Or stick to microsoft and use MSVC for everything.
Just put "-l:liblist.lib" instead of "-llist" when the suffix is not ".a". That should solve the "Not found" issue at least.
I would like to give a BIG thanks to #Harkaitz for this hint.
I spent several days to figure out why GCC (arm cross compile on Windows) was not able to find my libs in group. I wish those spelling issues to be more documented somewhere...
Basically the ':' in between '-l' and 'lib.a' was solving the issue, like this:
-L./my_path_to_libs -Xlinker --start-group -l:libmain.a -Xlinker --end-group
Depending on arm gcc verzion, -Xlinker could be -Wl
Work on Ubuntu 16
I used g++ main.cpp -lpq command for compiler my small project. Now I use Clion and wanna do same what I do with g++. But I can't add compiler flags in cmake file and get compile error.
cmake_minimum_required(VERSION 3.5.1)
project(day_g)
set(CMAKE_CXX_FLAGS "-lpq")
add_definitions(-lpq)
message("CMAKE_CXX_FLAGS is ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(day_g ${SOURCE_FILES})
Also I run only cmake file and get CMAKE_CXX_FLAGS with -lpq flag.
CMAKE_CXX_FLAGS is -lpq
-- Configuring done
-- Generating done
How properly add compiler flags to cmake file?
Flag -l is for linker, not for compiler. This flag is used for link with libraries. CMake has special command target_link_libraries for that purpose:
target_link_libraries(day_g pq)
-lq is not a compiler flag (CFLAGS) but a linker flag.
To pass a library in a CMake project you should use:
target_link_libraries(target_name libraries...)
Note that if you specify 'q' as library the project will link with libq.a or, if you are on windows q.dll.
... in your CMakeLists.txt the correct line to add is:
target_link_libraries(day_g pq)
Note also that when you add a CFLAG you should also "remember" the previous ones that may be added by libraries or by your platform, ie:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
To check the exact flags cmake is passing to compiler or linker you can always run, from the build directory, the following command:
make VERBOSE=1
I started experimenting with C/C++ the other day because I needed it for reading level-4 MAT-files without needing to purchase the Matlab editor or compiler. So I found just the library that I needed but I'm not familiar with C or C++ at all so I'm a beginner with those two languages. Anyhow I need to include the 'matio' library. I've tried many things but I've had no luck.
I right clicked on the C/C++ project > properties > C/C++ General > Paths & Symbols > GNU C and added the path to the matio library.
I also went to C/C++ Build > Settings > Tool settings > GCC C Compiler > Includes and added the path there aswell.
Since I'm not any good with makefiles yet I did not specify my own makefile, instead I chose a executable project.
When I try to build my project it complains about a function called 'Mat_Open' in the matio library. When I hover over it, it says "undefined reference to 'Mat_Open'" the header 'matio.h' seems to work fine but it can't refer to 'Mat_Open' for some reason.
How do I solve this?
EDIT:
Here is the whole build console output.
10:42:52 **** Incremental Build of configuration Debug for project Project ****
Info: Internal Builder is used for build
gcc -IC:/matio-1.5.2/src -O0 -g3 -Wall -c -fmessage-length=0 -o CComponent.o "..\\CComponent.c"
gcc -Xlinker -lm -o Project.exe CComponent.o -lC:/matio-1.5.2/src
c:/mingw(x64)/bin/../lib/gcc/x86_64-w64-mingw32/4.8.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lC:/matio-1.5.2/src
collect2.exe: error: ld returned 1 exit status
10:42:53 Build Finished (took 330ms)
This is not necessarily an answer but may be useful for a comparison.
First of all, where did you install it? If your using Linux or Mac OSX you will want to install in the system directories (not sure about Windows). I use OSX so in my makefile (by the way I use Qt):
LIBS += -L/usr/local/lib/ -lmatio
INCLUDEPATH += /usr/local/include
Then of course, in the *.h files of my source I use:
#include "matio.h"
But I assume you have already tried that?
What's the best way to tell CMake to use the LLVM linker llvm-link instead of GNU ld as linker? When configuring a project with
CXX=clang++ cmake <args>
the default linker appears to be untouched, remaining usr/bin/ld (on Linux).
Is this possible without using a separate toolchain file?
This turns out to be unrelated to CMake: clang++ uses the system linker by default. For example,
echo "#include <atomic>\n int main() { return 0; }" \
| clang++ -x c++ -std=c++11 -stdlib=libc++ -
uses /usr/bin/ld to link the application. To change the linker to llvm-link, one needs to first emit LLVM byte code, and then call the linker, e.g.:
echo "#include <atomic>\n int main() { return 0; }" \
| clang++ -x c++ -std=c++11 -stdlib=libc++ -S -emit-llvm -o - - \
| llvm-link -o binary -
This bypasses /usr/bin/ld.
As of 3.4, clang looks for the linker (ld) at GCCInstallation.getParentLibPath() + "/../" + GCCInstallation.getTriple().str() + "/bin" before it looks for ld on the path. You should be able to put your linker in /usr/lib/gcc/<arch><sub>-<vendor>-<sys>-<abi>/<version>/ld and have it called by clang in 1 step. To specify this location manually, use the undocumented -B flag. Unfortunately, I don't believe there is a way to alter the name of the linker that is searched for so using ld.gold or lld is going to require a symlink at the aforementioned location.