issues with linking undefined reference help ! very stuck - c

I am getting a "undefined reference to 'i2c_master_init' " i think this is to do some linking but not to sure how to correct ?
UPDATE :
iv been trying to find the answer for this for a while now. and have noticed a few bit but just not sure what i am doing wrong ! sorry it must be getting hard to read now !
This is from i2c_master.h and give me no issues
static inline void i2c_master_enable(const struct i2c_master_module *const module){
/* Sanity check of arguments */
Assert(module);
Assert(module->hw);
SercomI2cm *const i2c_module = &(module->hw->I2CM);
/* Timeout counter used to force bus state */
uint32_t timeout_counter = 0;
/* Wait for module to sync */
_i2c_master_wait_for_sync(module);
/* Enable module */
i2c_module->CTRLA.reg |= SERCOM_I2CM_CTRLA_ENABLE;
#if I2C_MASTER_CALLBACK_MODE == true
/* Enable module interrupts */
system_interrupt_enable(_sercom_get_interrupt_vector(module->hw));
#endif
/* Start timeout if bus state is unknown */
while (!(i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE(1))) {
timeout_counter++;
if(timeout_counter >= (module->unknown_bus_state_timeout)) {
/* Timeout, force bus state to idle */
i2c_module->STATUS.reg = SERCOM_I2CM_STATUS_BUSSTATE(1);
/* Workaround #1 */
return;
}
This is in the same file and is giving me issues
enum status_code i2c_master_init(struct i2c_master_module *const module,
Sercom *const hw, const struct i2c_master_config *const config);
this is my code.....
#include <asf.h>
void initialize(void)
{
system_init();
delay_init();
ioport_init();
}
//I2c slave address
#define AM2315_ADDRESS 0xB8 //temp and humity sensor
#define DATA_LENGTH 10
#define TIMEOUT 1000 //number of time to try and send the packet before it
fails
static uint8_t write_buffer[DATA_LENGTH] = {0x00, 0x01, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08, 0x09};
static uint8_t read_buffer[DATA_LENGTH];
struct i2c_master_module i2c_master_instance;
void configure_i2c_master(void)
{
/* Initialize config structure and software module. */
struct i2c_master_config config_i2c_master;
i2c_master_get_config_defaults(&config_i2c_master);
/* Change buffer timeout to something longer. */
config_i2c_master.buffer_timeout = 10000;
/* Initialize and enable device with config. */
i2c_master_init(&i2c_master_instance, SERCOM1, &config_i2c_master);
i2c_master_enable(&i2c_master_instance);
}
int main (void)
{
initialize();
configure_i2c_master();
uint8_t timeout = 0 ;
struct i2c_master_packet packet ={
.address = AM2315_ADDRESS,
.data_length = DATA_LENGTH,
.data = write_buffer,
.ten_bit_address = false,
.hs_master_code = 0x0,
};
ioport_set_pin_dir(PIN_PA27, IOPORT_DIR_OUTPUT);
while(1)
{
delay_ms(1000);
ioport_set_pin_level(PIN_PA27, true);
delay_ms(1000);
ioport_set_pin_level(PIN_PA27, false);
//write buffer to slave untill success
while(i2c_master_read_packet_wait(&i2c_master_instance, &packet) !=
STATUS_OK){
if (timeout++ ==TIMEOUT){
break;
}
}
//Read from slave until success.
packet.data = read_buffer;
while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) !=
STATUS_OK){
if (timeout++ ==TIMEOUT){
break;
}
}
}
}
this is my output...
------ Build started: Project: GccBoardProject1, Configuration: Debug ARM --
Build started.
Project "GccBoardProject1.cproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition;
('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "C:\Program Files
(x86)\Atmel\Studio\7.0\Vs\Compiler.targets" from project
"C:\Users\benvo\Documents\Atmel
Studio\7.0\GccBoardProject1\GccBoardProject1\GccBoardProject1.cproj"
(target "Build" depends on it):
Task "RunCompilerTask"
Shell Utils Path C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils
C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils\make.exe all --jobs 4 --
output-sync
C:\Users\benvo\Documents\Atmel
Studio\7.0\GccBoardProject1\GccBoardProject1\src\main.c(35,6): warning: no
previous prototype for 'initialize' [-Wmissing-prototypes]
void initialize(void)
^~~~~~~~~~
C:\Users\benvo\Documents\Atmel
Studio\7.0\GccBoardProject1\GccBoardProject1\src\main.c(58,6): warning: no
previous prototype for 'configure_i2c_master' [-Wmissing-prototypes]
void configure_i2c_master(void)
^~~~~~~~~~~~~~~~~~~~
Building file: ../src/main.c
Invoking: ARM/GNU C Compiler : 6.3.1
"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-
toolchain\bin\arm-none-eabi-gcc.exe" -x c -mthumb -D__SAMD21G18A__ -DDEBUG
-DBOARD=USER_BOARD -DARM_MATH_CM0PLUS=true -DSYSTICK_MODE -
DI2C_MASTER_CALLBACK_MODE=true -I"../src/ASF/common/boards" -
I"../src/ASF/sam0/utils" -I"../src/ASF/sam0/utils/header_files" -
I"../src/ASF/sam0/utils/preprocessor" -
I"../src/ASF/thirdparty/CMSIS/Include" -
I"../src/ASF/thirdparty/CMSIS/Lib/GCC" -I"../src/ASF/common/utils" -
I"../src/ASF/sam0/utils/cmsis/samd21/include" -
I"../src/ASF/sam0/utils/cmsis/samd21/source" -
I"../src/ASF/sam0/drivers/system"
-I"../src/ASF/sam0/drivers/system/clock/clock_samd21_r21_da_ha1" -
I"../src/ASF/sam0/drivers/system/clock" -
I"../src/ASF/sam0/drivers/system/interrupt" -
I"../src/ASF/sam0/drivers/system/interrupt/system_interrupt_samd21" -
I"../src/ASF/sam0/drivers/system/pinmux" -
I"../src/ASF/sam0/drivers/system/power" -
I"../src/ASF/sam0/drivers/system/power/power_sam_d_r_h" -
I"../src/ASF/sam0/drivers/system/reset" -
I"../src/ASF/sam0/drivers/system/reset/reset_sam_d_r_h" -
I"../src/ASF/common2/boards/user_board" -I"../src" -I"../src/config" -
I"../src/ASF/common2/services/delay" -
I"../src/ASF/common2/services/delay/sam0" -
I"../src/ASF/common/services/ioport" -I"../src/ASF/sam0/drivers/sercom" -
I"../src/ASF/sam0/drivers/sercom/i2c" -O1 -fdata-sections -ffunction-
sections -mlong-calls -g3 -Wall -mcpu=cortex-m0plus -c -pipe -fno-strict-
aliasing -Wall -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-
function-declaration -Wpointer-arith -std=gnu99 -ffunction-sections -fdata-
sections -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -Wmain -
Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -
Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wbad-
function-cast -Wwrite-strings -Wsign-compare -Waggregate-return -Wmissing-
declarations -Wformat -Wmissing-format-attribute -Wno-deprecated-
declarations -Wpacked -Wredundant-decls -Wnested-externs -Wlong-long -
Wunreachable-code -Wcast-align --param max-inline-insns-single=500 -MD -MP -
MF "src/main.d" -MT"src/main.d" -MT"src/main.o" -o "src/main.o"
"../src/main.c"
Finished building: ../src/main.c
src/main.o: In function `configure_i2c_master':
C:\Users\benvo\Documents\Atmel
Studio\7.0\GccBoardProject1\GccBoardProject1\src\main.c(69,1): error:
undefined reference to `i2c_master_init'
src/main.o: In function `main':
C:\Users\benvo\Documents\Atmel
Studio\7.0\GccBoardProject1\GccBoardProject1\src\main.c(103,1): error:
undefined reference to `i2c_master_read_packet_wait'
collect2.exe(0,0): error: ld returned 1 exit status
make: *** [GccBoardProject1.elf] Error 1
Building target: GccBoardProject1.elf
Invoking: ARM/GNU Linker : 6.3.1
"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\arm\arm-gnu-
toolchain\bin\arm-none-eabi-gcc.exe" -o GccBoardProject1.elf
src/ASF/sam0/drivers/sercom/sercom.o
src/ASF/sam0/drivers/sercom/sercom_interrupt.o
src/ASF/common2/services/delay/sam0/systick_counter.o
src/ASF/common2/boards/user_board/init.o
src/ASF/common/utils/interrupt/interrupt_sam_nvic.o
src/ASF/sam0/drivers/system/clock/clock_samd21_r21_da_ha1/clock.o
src/ASF/sam0/drivers/system/clock/clock_samd21_r21_da_ha1/gclk.o
src/ASF/sam0/drivers/system/interrupt/system_interrupt.o
src/ASF/sam0/drivers/system/pinmux/pinmux.o
src/ASF/sam0/drivers/system/system.o
src/ASF/sam0/utils/cmsis/samd21/source/gcc/startup_samd21.o
src/ASF/sam0/utils/cmsis/samd21/source/system_samd21.o
src/ASF/sam0/utils/syscalls/gcc/syscalls.o src/main.o -mthumb -Wl,-
Map="GccBoardProject1.map" --specs=nano.specs -Wl,--start-group -
larm_cortexM0l_math -lm -Wl,--end-group -
L"../src/ASF/thirdparty/CMSIS/Lib/GCC" -Wl,--gc-sections -mcpu=cortex-
m0plus -Wl,--entry=Reset_Handler -Wl,--cref -mthumb -
T../src/ASF/sam0/utils/linker_scripts/samd21/gcc/samd21g18a_flash.ld
C:\Users\benvo\Documents\Atmel
Studio\7.0\GccBoardProject1\GccBoardProject1\Debug\Makefile(333,1): error:
recipe for target 'GccBoardProject1.elf' failed
The command exited with code 2.
Done executing task "RunCompilerTask" -- FAILED.
Done building target "CoreBuild" in project "GccBoardProject1.cproj" --
FAILED.
Done building project "GccBoardProject1.cproj" -- FAILED.
Build FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========
TAGS:
Tools, Atmel Software Framework (ASF) and Atmel Start (ASFv4), all
architectures

Related

How to write/read to FLASH on STM32F302

I am making a code using CubeIDE for a STM32F302K8UX and I need a variable to be persistent across resets.
One way I have seen ppl doing it is by making a variable that is saved directly on flash memory (at least this is what I understood of it).
I got it from #Stephan answer on this post:
How to write/read to FLASH on STM32F4, Cortex M4
So I tried following it with a few modifications. On the MEMORY section of STM32F302K8UX_FLASH.ld:
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 63K // subtracted 1kb from original value (64K)
DATA (rx) : ORIGIN = 0x0800FC00, LENGTH = 1K // created new section at the end of previous (0x8000000 + (63 * 1024))
}
Then on the SECTIONS section, I added this at the start:
SECTIONS
{
.user_data (NOLOAD):
{
. = ALIGN(4);
_user_data_start = .; /* create a global symbol at user_data start */
KEEP(*(.user_data))
. = ALIGN(4);
_user_data_end = .; /* create a global symbol at user_data end */
} >DATA
...
Now on my main code I declared the variable as such:
uint8_t persistent_config __attribute__ ((section(".user_data")));
But I get a linker error that I cannot really understand:
14:03:41 **** Incremental Build of configuration Debug for project sonicPlayer ****
make -j12 all
arm-none-eabi-gcc "../Core/Src/main.c" -mcpu=cortex-m4 -std=gnu11 -g3 -DUSE_HAL_DRIVER -DSTM32F302x8 -DDEBUG -c -I../Core/Inc -I../Drivers/STM32F3xx_HAL_Driver/Inc -I../Drivers/STM32F3xx_HAL_Driver/Inc/Legacy -I../Drivers/CMSIS/Device/ST/STM32F3xx/Include -I../Drivers/CMSIS/Include -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage -MMD -MP -MF"Core/Src/main.d" -MT"Core/Src/main.o" --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -o "Core/Src/main.o"
arm-none-eabi-gcc -o "sonicPlayer.elf" #"objects.list" -mcpu=cortex-m4 -T"C:\Users\werne\OwnCloud\Documents\Arquivos\Drive\Projetos\SonicScrewDriver\sonicPlayer\STM32F302K8UX_FLASH.ld" --specs=nosys.specs -Wl,-Map="sonicPlayer.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -Wl,--start-group -lc -lm -Wl,--end-group
c:\st\stm32cubeide_1.4.0\stm32cubeide\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.4.0.202007081208\tools\arm-none-eabi\bin\ld.exe:C:\Users\werne\OwnCloud\Documents\Arquivos\Drive\Projetos\SonicScrewDriver\sonicPlayer\STM32F302K8UX_FLASH.ld:40: syntax error
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:50: sonicPlayer.elf] Error 1
"make -j12 all" terminated with exit code 2. Build might be incomplete.
14:03:42 Build Failed. 2 errors, 0 warnings. (took 598ms)
Description Resource Path Location Type
make: *** [makefile:50: sonicPlayer.elf] Error 1 sonicPlayer C/C++ Problem
make: *** No rule to make target 'clean'. Stop. Firmware C/C++ Problem
syntax error sonicPlayer line 40, external location: c:\st\stm32cubeide_1.4.0\stm32cubeide\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.7-2018-q2-update.win32_1.4.0.202007081208\tools\arm-none-eabi\bin\ld.exe:C:\Users\werne\OwnCloud\Documents\Arquivos\Drive\Projetos\SonicScrewDriver\sonicPlayer\STM32F302K8UX_FLASH.ld C/C++ Problem
How do I fix this?
The error description is pretty cryptic to me and I could find anything on google.
If you could explain what is going on here it would be nice too, I'm. not very experienced in this sort of too specific thing.
edit
I can see a syntax error, but no clue where or what.
edit 2: solution:
To fix the error code, I replaced // comments by /* */ as suggested by #KamilCuk However the code was not complete
With a bit more research based on all the other answers, I got this link: https://os.mbed.com/users/olympux/code/eeprom_flash/
So I scrapped all the above, added both .h and .c to my project, replaced #include "mbed.h" for #include "stm32f3xx_hal.h"
then I changed eeprom_flash.c first function
#include "eeprom_flash.h"
FLASH_EraseInitTypeDef eraseInit = {
FLASH_TYPEERASE_PAGES,
EEPROM_START_ADDRESS, // Memory location (beggining of page)
1 // Number of pages to erase
};
uint32_t pageError;
/*
* Must call this first to enable writing
*/
void enableEEPROMWriting() {
HAL_StatusTypeDef status = HAL_FLASH_Unlock();
HAL_FLASHEx_Erase(&eraseInit, &pageError);
}
That was it! to write to flash memory:
enableEEPROMWriting();
writeEEPROMHalfWord(0x0, var);
disableEEPROMWriting();
and to read
uint16_t var = readEEPROMHalfWord(0x0);

How do I unit-test a dynamic library using gcov?

I am building a dynamically-linked library, and am setting up a simple test suite. I want to use gcov to generate a static code analysis coverage report.
My library is a C file containing function implementations and a header file containing function prototypes. My test suite is simply an application that calls the functions in various ways and confirms the validity of the output.
I am compiling both the library and the test suite with the -fprofile-arcs and -ftest-coverage flags, as described on GNU's guide to GCOV. I am also including the -O0 flag to disable compiler optimization and the -g flag to enable debug symbols. The executable generated from the test suite is linked dynamically to the library.
All files compile cleanly and without warning, but it fails to link the test suite to the library -- citing a "hidden symbol __gcov_merge_add". If I compile without the -fprofile-arcs and -ftest-coverage flags, the linking succeeds and I am able to run the test suite executable.
So I have a few questions which still aren't resolved after reading the GNU guide to GCOV.
Why is the linking failing? How can I resolve this?
Do I need to include the profile and coverage flags when compiling both the library and the test suite?
Here is my inc/mylib.h file:
#ifndef __MYLIB_H__
#define __MYLIB_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
int
foo (int a);
int
bar (int a);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __MYLIB_H__ */
Here is my src/mylib.c file:
#include <stdio.h>
#include "mylib.h"
int foo(int a) {
if (a > 5) {
return 5;
}
return a;
}
int bar(int a) {
if (a < 0) {
return 0;
}
return a;
}
Here is my test/unittests.c file:
#include <stdio.h>
#include "mylib.h"
void run_foo_tests() {
int inputs[] = {3, 6};
int expected_results[] = {3, 5};
int i, actual_result;
for ( i = 0; i < sizeof(inputs) / sizeof(int); i++ ) {
actual_result = foo(inputs[i]);
if (actual_result == expected_results[i]) {
printf("Test %d passed!\n", i + 1);
} else {
printf("Test %d failed!\n", i + 1);
printf(" Expected result: %d\n", expected_results[i]);
printf(" Actual result: %d\n", actual_result);
}
}
}
void run_bar_tests() {
int inputs[] = {3, -1};
int expected_results[] = {3, 0};
int i, actual_result;
for ( i = 0; i < sizeof(inputs) / sizeof(int); i++ ) {
actual_result = bar(inputs[i]);
if (actual_result == expected_results[i]) {
printf("Test %d passed!\n", i + 1);
} else {
printf("Test %d failed!\n", i + 1);
printf(" Expected result: %d\n", expected_results[i]);
printf(" Actual result: %d\n", actual_result);
}
}
}
int main(int argc, char *argv[]) {
run_foo_tests();
run_bar_tests();
return 0;
}
Here is my Makefile:
CC=gcc
CFLAGS=-Wall -std=c89 -g -O0 -Iinc -fprofile-arcs -ftest-coverage
all: clean build run_tests
build:
$(CC) $(CFLAGS) -fPIC -c src/*.c -o lib/mylib.o
$(CC) -shared lib/mylib.o -o lib/libmylib.so
$(CC) $(CFLAGS) test/*.c -o bin/unittests -Llib -lmylib
run_tests:
LD_LIBRARY_PATH=lib bin/unittests
gcov src/*.c
clean:
rm -f *.gcda *.gcno *.gcov
rm -rf bin lib ; mkdir bin lib
When I run make, I am presented with this output:
rm -f *.gcda *.gcno *.gcov
rm -rf bin lib ; mkdir bin lib
gcc -Wall -std=c89 -g -O0 -Iinc -fprofile-arcs -ftest-coverage -fPIC -c src/*.c -o lib/mylib.o
gcc -shared lib/mylib.o -o lib/libmylib.so
gcc -Wall -std=c89 -g -O0 -Iinc -fprofile-arcs -ftest-coverage test/*.c -o bin/unittests -Llib -lmylib
/usr/bin/ld: bin/unittests: hidden symbol `__gcov_merge_add' in /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcov.a(_gcov_merge_add.o) is referenced by DSO
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
make: *** [build] Error 1
You need to give the command line argument -lgcov for the linker (normally -ftest-coverage implies -lgcov, but you have a separate linking step where -ftest-coverage is not given as a command line argument). Alternatively, you can just use the --coverage command line argument, which is a shortcut also for -fprofile-arcs and -ftest-coverage, as explained here: http://www.univ-orleans.fr/sciences/info/ressources/webada/doc/gnat/gcc_3.html:
--coverage
This option is used to compile and link code instrumented for
coverage analysis. The option is a synonym for `-fprofile-arcs'
`-ftest-coverage' (when compiling) and `-lgcov' (when linking). See
the documentation for those options for more details.
At the same place, btw., it is also explained that you don't have to compile all files with these options, which hopefully answers your question 2.

Undefined reference to... when linking library header

I'm trying to compile a C program that uses libvncserver but no matter what I do I keep getting undefined reference errors, the library I'm having troubles with is rfb/rfb.h.
vnc.c code (copied from here):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rfb/rfb.h>
#define WIDTH 640
#define HEIGHT 480
#define BPP 4
/* 15 frames per second (if we can) */
#define PICTURE_TIMEOUT (1.0/15.0)
/*
* throttle camera updates
*/
int TimeToTakePicture() {
static struct timeval now={0,0}, then={0,0};
double elapsed, dnow, dthen;
gettimeofday(&now,NULL);
dnow = now.tv_sec + (now.tv_usec /1000000.0);
dthen = then.tv_sec + (then.tv_usec/1000000.0);
elapsed = dnow - dthen;
if (elapsed > PICTURE_TIMEOUT)
memcpy((char *)&then, (char *)&now, sizeof(struct timeval));
return elapsed > PICTURE_TIMEOUT;
}
/*
* simulate grabbing a picture from some device
*/
int TakePicture(unsigned char *buffer)
{
static int last_line=0, fps=0, fcount=0;
int line=0;
int i,j;
struct timeval now;
/*
* simulate grabbing data from a device by updating the entire framebuffer
*/
for(j=0;j<HEIGHT;++j) {
for(i=0;i<WIDTH;++i) {
buffer[(j*WIDTH+i)*BPP+0]=(i+j)*128/(WIDTH+HEIGHT); /* red */
buffer[(j*WIDTH+i)*BPP+1]=i*128/WIDTH; /* green */
buffer[(j*WIDTH+i)*BPP+2]=j*256/HEIGHT; /* blue */
}
buffer[j*WIDTH*BPP+0]=0xff;
buffer[j*WIDTH*BPP+1]=0xff;
buffer[j*WIDTH*BPP+2]=0xff;
}
/*
* simulate the passage of time
*
* draw a simple black line that moves down the screen. The faster the
* client, the more updates it will get, the smoother it will look!
*/
gettimeofday(&now,NULL);
line = now.tv_usec / (1000000/HEIGHT);
if (line>HEIGHT) line=HEIGHT-1;
memset(&buffer[(WIDTH * BPP) * line], 0, (WIDTH * BPP));
/* frames per second (informational only) */
fcount++;
if (last_line > line) {
fps = fcount;
fcount = 0;
}
last_line = line;
fprintf(stderr,"%03d/%03d Picture (%03d fps)\r", line, HEIGHT, fps);
/* success! We have a new picture! */
return (1==1);
}
/*
* Single-threaded application that interleaves client servicing with taking
* pictures from the camera. This way, we do not update the framebuffer
* while an encoding is working on it too (banding, and image artifacts).
*/
int main(int argc,char** argv)
{
long usec;
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,WIDTH,HEIGHT,8,3,BPP);
if(!server)
return 0;
server->desktopName = "Live Video Feed Example";
server->frameBuffer=(char*)malloc(WIDTH*HEIGHT*BPP);
server->alwaysShared=(1==1);
/* Initialize the server */
rfbInitServer(server);
/* Loop, processing clients and taking pictures */
while (rfbIsActive(server)) {
if (TimeToTakePicture())
if (TakePicture((unsigned char *)server->frameBuffer))
rfbMarkRectAsModified(server,0,0,WIDTH,HEIGHT);
usec = server->deferUpdateTime*1000;
rfbProcessEvents(server,usec);
}
return(0);
}
Compiler output:
sudo gcc -g -Wall -Wextra -O2 vnc.c
/tmp/cc7dpMCs.o: In function `main':
/home/arcm/Projects/c/vnc.c:77: undefined reference to `rfbGetScreen'
/home/arcm/Projects/c/vnc.c:84: undefined reference to `rfbInitServerWithPthreadsAndZRLE'
/home/arcm/Projects/c/vnc.c:91: undefined reference to `rfbProcessEvents'
/home/arcm/Projects/c/vnc.c:86: undefined reference to `rfbIsActive'
/home/arcm/Projects/c/vnc.c:89: undefined reference to `rfbMarkRectAsModified'
collect2: error: ld returned 1 exit status
I've got libvncserver0 and libvncserver-dev installed and i'm using ubuntu 14.04.
I tried:
sudo gcc -g -Wall -Wextra -O2 vnc.c -lm
sudo gcc -g -Wall -Wextra -O2 vnc.c -ldl
sudo gcc -g -Wall -Wextra -O2 -ldl vnc.c
sudo gcc -g -Wall -Wextra -O2 -I/usr/include/rfb -L/usr/include/rbf/rfb.h vnc.c
sudo gcc -g -Wall -Wextra -O2 -I/usr/include/rfb vnc.c
sudo gcc -g -Wall -Wextra -O2 -L/usr/include/rbf/rfb.h vnc.c
sudo gcc -g -Wall -Wextra -O2 /usr/include/rbf/rfb.h vnc.c
sudo gcc -g -Wall -Wextra -O2 -L/usr/include/rbf/rfb.h -ldl vnc.c
But I get the same errors everytime. What am I doing wrong and how can I fix it?
You don't "link" a library header, you include it so the compiler sees the library's declarations at compile time and knows that rfbGetScreen() is a function that takes so-and-so many arguments of this-and-that type and returns a rfbScreenInfoPtr. How it does this (the definition of the function) is not important to the compiler. It just adds a reference to that function, which is left for the linker to resolve. (Note the vocabulary here.)
You link your compiled code to the library binary. This is done by the linker, in a different (and later) step that just happens to be supported by the same frontend as compiling your source (gcc). In this step, any of the library functions that your code actually uses (references) are resolved by linking them in from the specified libraries.
This here...
sudo gcc -g -Wall -Wextra -O2 vnc.c
...links only the standard library and runtime, as there are no specific linking instructions in there.
This here...
-L/usr/include/rbf/rfb.h
...is nonsense, as -L is for giving directories where library binaries should be looked for (and is not necessary if the library in question is installed in the standard location).
The actual link instruction is -l. If you state -lfoo, then the library libfoo is searched for any undefined references.
This here...
-ldl
...is linking libdl, and from that you should be able to deduce that...
-lvncserver
...is what you're looking for (assuming that <rfb/rfb.h> actually does refer to libvncserver, which I don't know).
Note that the linker is processing libraries in the sequence they are given on the command line, so you need to state -lvncserver after vnc.c, because only then does the linker know which undefined references it ought to be looking for in libvncserver.
And never, ever run a compiler as sudo. Why in {.....}'s name do you think this would be necessary?

Matlab 2013b generated code produces Undefined symbols for architecture x86_64 error in mex

I have a C-Code generated by the Simulink Coder that I need to use in a C S-function.
This may sound a bit strange but I need this Code to be executed multiple times within the s-function before writing the outputs of the s-function (it's an evolutionary algorithm that needs to simulate a prediction for a lot of individuals before evaluation and ranking...but those details do not really matter).
The Problem is that I seem to have a problem with the 64bit instruction set when trying to mex my code.
I am taking the generated erg_main.c as an example on how to interact with the generated code:
/*
* File: ert_main.c
*
* Code generated for Simulink model 'Peltier_model'.
*
* Model version : 1.14
* Simulink Coder version : 8.5 (R2013b) 08-Aug-2013
* C/C++ source code generated on : Thu Apr 3 18:01:46 2014
*
* Target selection: ert.tlc
* Embedded hardware selection: 32-bit Generic
* Emulation hardware selection:
* Differs from embedded hardware (MATLAB Host)
* Code generation objective: Debugging
* Validation result: Passed (0), Warning (1), Error (0)
*/
#include <stdio.h> /* This ert_main.c example uses printf/fflush */
#include "Peltier_model.h" /* Model's header file */
#include "rtwtypes.h"
/*
* Associating rt_OneStep with a real-time clock or interrupt service routine
* is what makes the generated code "real-time". The function rt_OneStep is
* always associated with the base rate of the model. Subrates are managed
* by the base rate from inside the generated code. Enabling/disabling
* interrupts and floating point context switches are target specific. This
* example code indicates where these should take place relative to executing
* the generated code step function. Overrun behavior should be tailored to
* your application needs. This example simply sets an error status in the
* real-time model and returns from rt_OneStep.
*/
void rt_OneStep(void)
{
static boolean_T OverrunFlag = 0;
/* Disable interrupts here */
/* Check for overrun */
if (OverrunFlag) {
rtmSetErrorStatus(Peltier_model_M, "Overrun");
return;
}
OverrunFlag = TRUE;
/* Save FPU context here (if necessary) */
/* Re-enable timer or interrupt here */
/* Set model inputs here */
/* Step the model */
Peltier_model_step();
/* Get model outputs here */
/* Indicate task complete */
OverrunFlag = FALSE;
/* Disable interrupts here */
/* Restore FPU context here (if necessary) */
/* Enable interrupts here */
}
/*
* The example "main" function illustrates what is required by your
* application code to initialize, execute, and terminate the generated code.
* Attaching rt_OneStep to a real-time clock is target specific. This example
* illustates how you do this relative to initializing the model.
*/
int_T main(int_T argc, const char *argv[])
{
/* Unused arguments */
(void)(argc);
(void)(argv);
/* Initialize model */
Peltier_model_initialize();
/* Attach rt_OneStep to a timer or interrupt service routine with
* period 0.01 seconds (the model's base sample time) here. The
* call syntax for rt_OneStep is
*
* rt_OneStep();
*/
printf("Warning: The simulation will run forever. "
"Generated ERT main won't simulate model step behavior. "
"To change this behavior select the 'MAT-file logging' option.\n");
fflush((NULL));
while (rtmGetErrorStatus(Peltier_model_M) == (NULL)) {
/* Perform other application tasks here */
}
/* Disable rt_OneStep() here */
/* Terminate model */
Peltier_model_terminate();
return 0;
}
/*
* File trailer for generated code.
*
* [EOF]
*/
For now I am just trying to initialize my model using the Peltier_model_initialize(); and including those headers from the erg_main.c
trying to mex this results in the following:
**************************************************************************
Warning: Neither -compatibleArrayDims nor -largeArrayDims is selected.
Using -compatibleArrayDims. In the future, MATLAB will require
the use of -largeArrayDims and remove the -compatibleArrayDims
option. For more information, see:
http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html
**************************************************************************
-> mexopts.sh sourced from directory (DIR = $PREF_DIR)
FILE = /Users/JoachimSA/.matlab/R2013b/mexopts.sh
----------------------------------------------------------------
-> MATLAB = /Applications/MATLAB_R2013b.app
-> CC = xcrun -sdk macosx10.9 clang
-> CC flags:
CFLAGS = -fno-common -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -fexceptions
CDEBUGFLAGS = -g
COPTIMFLAGS = -O2 -DNDEBUG
CLIBS = -L/Applications/MATLAB_R2013b.app/bin/maci64 -lmx -lmex -lmat -lstdc++
arguments = -DMX_COMPAT_32
-> CXX = xcrun -sdk macosx10.9 clang++
-> CXX flags:
CXXFLAGS = -fno-common -fexceptions -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9
CXXDEBUGFLAGS = -g
CXXOPTIMFLAGS = -O2 -DNDEBUG
CXXLIBS = -L/Applications/MATLAB_R2013b.app/bin/maci64 -lmx -lmex -lmat -lstdc++
arguments = -DMX_COMPAT_32
-> FC = gfortran
-> FC flags:
FFLAGS = -fexceptions -m64 -fbackslash
FDEBUGFLAGS = -g
FOPTIMFLAGS = -O
FLIBS = -L/Applications/MATLAB_R2013b.app/bin/maci64 -lmx -lmex -lmat -L -lgfortran -L -lgfortranbegin
arguments = -DMX_COMPAT_32
-> LD = xcrun -sdk macosx10.9 clang
-> Link flags:
LDFLAGS = -arch x86_64 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -bundle -Wl,-exported_symbols_list,/Applications/MATLAB_R2013b.app/extern/lib/maci64/mexFunction.map
LDDEBUGFLAGS = -g
LDOPTIMFLAGS = -O
LDEXTENSION = .mexmaci64
arguments =
-> LDCXX =
-> Link flags:
LDCXXFLAGS =
LDCXXDEBUGFLAGS =
LDCXXOPTIMFLAGS =
LDCXXEXTENSION =
arguments =
----------------------------------------------------------------
-> xcrun -sdk macosx10.9 clang -c -I/Applications/MATLAB_R2013b.app/rtw/c/src -I/Users/JoachimSA/Documents/WICHTIG/Diplomarbeit/Matlab_FIles/Peltier_Codegen/Peltier_model_ert_rtw -I/Applications/MATLAB_R2013b.app/extern/include -I/Applications/MATLAB_R2013b.app/simulink/include -DMATLAB_MEX_FILE -fno-common -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -fexceptions -DMX_COMPAT_32 -O2 -DNDEBUG "CC_IMEA.c"
-> xcrun -sdk macosx10.9 clang -c -I/Applications/MATLAB_R2013b.app/rtw/c/src -I/Users/JoachimSA/Documents/WICHTIG/Diplomarbeit/Matlab_FIles/Peltier_Codegen/Peltier_model_ert_rtw -I/Applications/MATLAB_R2013b.app/extern/include -I/Applications/MATLAB_R2013b.app/simulink/include -DMATLAB_MEX_FILE -fno-common -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -fexceptions -DMX_COMPAT_32 -O2 -DNDEBUG "CC_Opt_Objectives.c"
-> xcrun -sdk macosx10.9 clang -c -I/Applications/MATLAB_R2013b.app/rtw/c/src -I/Users/JoachimSA/Documents/WICHTIG/Diplomarbeit/Matlab_FIles/Peltier_Codegen/Peltier_model_ert_rtw -I/Applications/MATLAB_R2013b.app/extern/include -I/Applications/MATLAB_R2013b.app/simulink/include -DMATLAB_MEX_FILE -fno-common -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -fexceptions -DMX_COMPAT_32 -O2 -DNDEBUG "CC_System_Utils.c"
-> xcrun -sdk macosx10.9 clang -c -I/Applications/MATLAB_R2013b.app/rtw/c/src -I/Users/JoachimSA/Documents/WICHTIG/Diplomarbeit/Matlab_FIles/Peltier_Codegen/Peltier_model_ert_rtw -I/Applications/MATLAB_R2013b.app/extern/include -I/Applications/MATLAB_R2013b.app/simulink/include -DMATLAB_MEX_FILE -fno-common -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -fexceptions -DMX_COMPAT_32 -O2 -DNDEBUG "CC_Opt_SystemCabin.c"
-> xcrun -sdk macosx10.9 clang -c -I/Applications/MATLAB_R2013b.app/rtw/c/src -I/Users/JoachimSA/Documents/WICHTIG/Diplomarbeit/Matlab_FIles/Peltier_Codegen/Peltier_model_ert_rtw -I/Applications/MATLAB_R2013b.app/extern/include -I/Applications/MATLAB_R2013b.app/simulink/include -DMATLAB_MEX_FILE -fno-common -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -fexceptions -DMX_COMPAT_32 -O2 -DNDEBUG "CC_Optimiser.c"
-> xcrun -sdk macosx10.9 clang -O -arch x86_64 -Wl,-syslibroot,/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk -mmacosx-version-min=10.9 -bundle -Wl,-exported_symbols_list,/Applications/MATLAB_R2013b.app/extern/lib/maci64/mexFunction.map -o "CC_Optimiser.mexmaci64" CC_IMEA.o CC_Opt_Objectives.o CC_System_Utils.o CC_Opt_SystemCabin.o CC_Optimiser.o -L/Applications/MATLAB_R2013b.app/bin/maci64 -lmx -lmex -lmat -lstdc++
Undefined symbols for architecture x86_64:
"_Peltier_model_initialize", referenced from:
_CC_Opt_SystemCabin in CC_Opt_SystemCabin.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
mex: link of ' "CC_Optimiser.mexmaci64"' failed.
Unable to complete successfully.
Error in build_mex_files (line 6)
mex -v ...
Error in run (line 63)
evalin('caller', [script ';']);
Do I really have a problem with my 6bit version or am I just not handling the code right ?
Thanks a lot for the help !
The OP discovered that all source files need to be specified on the mex command.
This can cause compilation to succeed, but linking to fail, if all the necessary declarations are included by the main source file.
Here is some additional information from the Linking Multiple Files section of "Building MEX-Files" on the MathWorks website:
You can combine multiple source files, object files, and file libraries to build a binary MEX-file. To do this, list the additional files, with their file extensions, separated by spaces. The name of the MEX-file is the name of the first file in the list.
The following command combines multiple files of different types into a binary MEX-file called circle.ext, where ext is the extension corresponding to the current platform:
mex circle.c square.obj rectangle.c shapes.lib
As it says above, put the file with mexFunction as the first in the list so that the MEX-file gets the name from that file.
The mex help page has a section "Build MEX-File from Multiple Source Files" with a similar example, although with Fortran source:
mex -largeArrayDims fulltosparse.F loadsparse.F
The MEX-file name is fulltosparse because fulltosparse.F is the first file on the command line.

Unable to link to ncurses in shared object

For some reason I have having an issue compiling a shared object that uses ncurses. Even though I include and link with -lncurses, compiling the .so file fails. Please advise.
#include <string.h>
#include "../include/mod_curse.h" /* Includes ncurses.h and friends */
int OnConsoleCmd(McapiS *API, ArgS *CmdArgs) /* Just ignore these, they're included in mod_curse.h */
{
if(!strcmp(CmdArgs->Data, "help"))
{
API->BPrintf(STD, "\n-- mod_curse.so --\n");
return 0;
}
}
int OnLoad(McapiS *API, va_list Args)
{
initscr(); /* These are the problems */
}
/* Time to clean up and unload the module */
int OnDeload(McapiS *API, va_list Args)
{
endwin();
}
Here is the Makefile:
CC = clang
CFLAGS = -Wall -fPIC
# Object Files
OBJ = mod_curse.o
# Header Files
INCLUDE = include/mod_curse.h
# Main Module
mod_setup.so: $(OBJ) $(INCLUDE)
$(CC) -shared -Wl,-soname,mod_curse.so,--no-undefined -o ../../mod_curse.so -lncurses $(OBJ)
# Source Files
mod_curse.o: src/mod_curse.c $(INCLUDE)
$(CC) $(CFLAGS) -c src/mod_curse.c
clean:
rm $(OBJ)
Here are the errors:
3 warnings generated.
clang -shared -Wl,-soname,mod_curse.so,--no-undefined -o ../../mod_curse.so -lncurses mod_curse.o
mod_curse.o: In function `OnLoad':
src/mod_curse.c:(.text+0x81): undefined reference to `initscr'
mod_curse.o: In function `OnDeload':
src/mod_curse.c:(.text+0xb1): undefined reference to `endwin'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mod_setup.so] Error 1
I needed to change my make command to have -lncurses appear after $(OBJ).

Resources