I have 2 c files (& their header files). I have included the function "put" in the corresponding header, but I still have the following errors, when I input "gcc -o main main.c" in the terminal.
main.c:(.text+0x389): undefined reference to `put' collect2: error: ld
returned 1 exit status
may I know the reason? How should I modify my code?
I tried to change the linking order in makefile but failed. Any advice is appreciated, thanks!
CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
project(Demo)
set(CMAKE_CXX_STANDARD 14)
include_directories(.)
add_executable(Demo
main.c main.h KeyValueStore.c KeyValueStore.h )
main.c
#include "main.h"
...
int main() {
...
if (strcmp("PUT", tokens[0]) == 0) {
put(tokens[1], tokens[2]);
...
}
main.h
...
#include "KeyValueStore.h"
...
KeyValueStore.c
#include "KeyValueStore.h"
#define BUFSIZE 1024
typedef struct KeyValueStore {
char key[BUFSIZE];
char value[BUFSIZE];
} KV_Store;
KV_Store kvStore[BUFSIZE];
...
int put(char* key, char* value){
...
}
KeyValueStore.h
...
typedef struct KeyValueStore;
int put(char* key, char* value);
...
Check to see if you have any .o files in that folder and delete them if you do. It's possible the compiler failed at some point while compiling which left *.o files that aren't linked properly
EDIT: I misread the question because for some reason it came up as a c++17 question for me. I'm not sure if what I said still applies to C though I do know it works with C++. Sorry about that to everyone that read my answer before I edited it
Not 100% sure if this is why you are having the error, though you need to put all .c files in the compiler.
So you currently are trying to "gcc -o main main.c" where instead you want to do something more like "gcc -o main main.c keyValueStore.c".
If you do not give the compiler every .c file, it won't have all the definitions and you will get an error similar to what you have.
I also don't really think you need main.h, assuming there isn't any more code in there, it really isn't worth having a whole extra file and instead just putting the #include in main.c.
Related
Trying to use CreateSolidBrush to change a window background color.
I've included wingdi.h, I believe I've linked gdi32.lib ( however I converted gdi32.lib to a gdi32.a by using LIB2A, and I wonder if this may be an issue? ).
I wouldn't mind using another function but I worry this could be come a re-occuring issue if I'm not able to find a solution.
Some relevant code:
#include <stdio.h>
#include <windows.h>
#include <wingdi.h>
#include <main.h>
DWORD CreateMainWindow(void)
{
.............
WNDCLASSEXA WindowClass = { 0 };
WindowClass.hbrBackground = CreateSolidBrush(RGB(200, 200, 200));
.............
}
I use a function to easily compile
int Compile()
{
................
int result = 0;
char *include = "C:\\Users\\Coding\\C\\src\\include";
char *link = "C:\\Users\\Coding\\C\\src\\lib";
char command[256];
if(snprintf(
command,
sizeof(command),
"gcc -o main -I%s -l gdi32 -L%s main.c", include, link) >= sizeof(command))
{
//exception catching and handling
}
else
{
system(command);
}
return result;
}
I have no reason to believe the file isn't being linked as I'm not receiving an error.
Also I'm only using Notepad++, mingw64, and command prompt.
The error is a linker error, because it can't find the shared library symbol CreateSolidBrush.
All that is needed is linker flag -lgdi32, so it links with MinGW's libgdi32.a.
Don't try to generate this file by converting it from some other file you found which is probably built with a totally different compiler. If you already experimented with that make sure to clean up any lingering gdi32 .a or .lib files from your previous attempts.
Well the answer was extremely simple, linkages and includes must come after the file.
C:\User> gcc main.c -lgdi32 -I<include path> -o main
If this was obvious then I apologize, hopefully this helps another confused individual
I have a project that I recently split up into headers + sources, and now clang-tidy wont "actually" check my test files that include these headers. Below is an example of the situation:
File Structure:
src/
main.c
a.h
a.c
test/
test.c
Code:
// src/main.c
#include "src/a.h"
int main(void) {
a();
return 0;
}
// src/a.h
void a(void);
// src/a.c
#include <stdlib.h>
#include "src/a.h"
void a(void) {
malloc(1); // obvious memory leak
}
// test/test.c
#include "src/a.h"
int main(void) {
// do test stuff
a();
return 0;
}
Compile src: cc src/*.c -I. -o main
Compile test: cc src/a.c test/test.c -I. -o test
Running does nothing, but the code does compile.
Then, I run the code through clang-tidy:
clang-tidy src/* -- -I.
This works:
1 warning generated.
1 warning generated.
1 warning generated.
/src/a.c:8:1: warning: Potential memory leak [clang-analyzer-unix.Malloc]
}
^
/src/a.c:7:2: note: Memory is allocated
malloc(1);
^
/src/a.c:8:1: note: Potential memory leak
}
^
But if I do:
clang-tidy test/test.c -- -I.
Nothing is outputed (ive tried to add the header-filter flag as well).
I pressume that the headers are being included, and the test code has no knowledge of the source. So, how can I make sure my tests are actually being checked if this is the case? These headers and sources are in my project, so it would only make sense that clang-tidy would be able to pick up on this?
Edit:
I can do the following, and it seems to only partially fix the problem:
// test/test.c
#include "src/a.h"
#include "src/a.c" //added this line
int main(void) {
// do test stuff
a();
return 0;
}
Now, clang-tidy picks up on the actual .c file, and thus finds the issue. But, now I cant compile my code. There is supposed to be a __clang_analyzer__ define that gets set when the code is being analyzed, but it seems to just ignore it:
#ifdef __clang_analyzer__
#include "src/a.c" // doesnt include file, thus the malloc() call is never detected
#endif
clang-tidy is only a static analyser tool, said differently a linter. It does not try to build or run an executable: it just analyses the C source files it has been given after processing the include parts.
Static analysis and testing are different parts of a quality assurance process:
the former only reads source files searching for common errors and runs nothing
the latter runs (parts of) a code base with known inputs and controls that outputs have expected values
That means that clang-tidy is expected to be run on your main sources, not only on the test ones.
To be clear, it can make sense to pass test sources to the linter, because they could contain problems that clang-tidy would detect. But only running clang-tidy on the test folder will not detect problem in main folder, whatever the coverage.
I am trying to make a C program using libmbus, which I have installed on my raspberry pi. In my /usr/lib directory I have the file libmbus.so and in my /usr/include directory I have the the file ./mbus/mbus.h.
The program looks like this:
#include <stdio.h>
#include <mbus/mbus.h>
int main(void)
{
mbus_handle* MbusHandle;
MbusHandle = mbus_connect_serial("/dev/ttyS1");
return 0;
}
When I try to run "gcc main.cpp -lmbus" I get:
main.cpp:(.text+0xe): undefined reference to `mbus_connect_serial(char const*)'
I tried to run
nm -D /usr/lib/libmbus.so
which among others gives
00009930 T mbus_connect_serial
So it appears that the function mbus_connect_serial is part of libmbus.so.
In the header file the function mbus_connect_serial is defined like this:
mbus_handle * mbus_connect_serial(const char * device);
I can't seem to figure out what is wrong. Can anyone guide me in the right direction?
If you're really trying to create a c program, rename main.cpp to main.c
Im working on a project for stm32f4 to my school. Im using CooCox IDE.
I wanted to add new files "przerwania.c" and "przerwania.h" to write some functions there - not in "main.c". But I have no idea why CooCox is showing me errors.
Earlier I wanted to move some of functions from main.c to pwm.c and them work! But I would like to make a new files couse i have more functions.
Errors in CooCox look like this:
[mkdir] Created dir: D:\CooCox\CoIDE\workspace\testowy2\testowy2\Debug\obj
[cc] 12 total files to be compiled.
[cc] arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -Wall -ffunction-sections -g -O0 -c -DSTM32F407VG -DSTM32F4XX -DUSE_STDPERIPH_DRIVER -D__ASSEMBLY__ -ID:\CooCox\CoIDE\workspace\testowy2 -ID:\CooCox\CoIDE\workspace\testowy2\cmsis_boot -ID:\CooCox\CoIDE -ID:\CooCox\CoIDE\workspace\testowy2\cmsis_lib\include -ID:\CooCox\CoIDE\workspace\testowy2\cmsis -ID:\CooCox\CoIDE\workspace\testowy2\cmsis_lib -ID:\CooCox\CoIDE\workspace D:\CooCox\CoIDE\workspace\testowy2\cmsis_lib\source\stm32f4xx_syscfg.c D:\CooCox\CoIDE\workspace\testowy2\pwm.c D:\CooCox\CoIDE\workspace\testowy2\dupa.c D:\CooCox\CoIDE\workspace\testowy2\cmsis_boot\startup\startup_stm32f4xx.c D:\CooCox\CoIDE\workspace\testowy2\main.c D:\CooCox\CoIDE\workspace\testowy2\cmsis_lib\source\stm32f4xx_rcc.c D:\CooCox\CoIDE\workspace\testowy2\cmsis_lib\source\stm32f4xx_adc.c D:\CooCox\CoIDE\workspace\testowy2\cmsis_lib\source\stm32f4xx_gpio.c D:\CooCox\CoIDE\workspace\testowy2\cmsis_boot\system_stm32f4xx.c D:\CooCox\CoIDE\workspace\testowy2\cmsis_lib\source\stm32f4xx_exti.c D:\CooCox\CoIDE\workspace\testowy2\cmsis_lib\source\misc.c D:\CooCox\CoIDE\workspace\testowy2\cmsis_lib\source\stm32f4xx_tim.c
[cc] Starting link
[cc] arm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -g -nostartfiles -Wl,-Map=testowy2.map -O0 -Wl,--gc-sections -LD:\CooCox\CoIDE\configuration\ProgramData\testowy2 -Wl,-TD:\CooCox\CoIDE\configuration\ProgramData\testowy2/arm-gcc-link.ld -g -o testowy2.elf ..\obj\stm32f4xx_syscfg.o ..\obj\pwm.o ..\obj\dupa.o ..\obj\startup_stm32f4xx.o ..\obj\main.o ..\obj\stm32f4xx_rcc.o ..\obj\stm32f4xx_adc.o ..\obj\stm32f4xx_gpio.o ..\obj\system_stm32f4xx.o ..\obj\stm32f4xx_exti.o ..\obj\misc.o ..\obj\stm32f4xx_tim.o
[cc] ..\obj\main.o: In function `main':
[cc] D:\CooCox\CoIDE\workspace\testowy2/main.c:336: undefined reference to `Nowafunkcja'
[cc] collect2.exe: error: ld returned 1 exit status
main.c is quite long becouse i have some definitions of few long functions there, so I paste here only a part
#include "stm32f4xx.h"
#include "misc.h"
#include "stm32f4xx_syscfg.h"
#include "stm32f4xx_adc.h"
#include "stm32f4xx_exti.h"
#include "przerwania.h"//here is the problem
#include "pwm.h"
int main(void)
{
SystemInit();
//IniDiody();
//TimConfig();
//NVIC_Config();
//IniDiodyPWM();
LEDInit();
EXTILine0_Config();
PWM2();//wiwo
GPIO();//wiwo
Nowafunkcja();//PROBLEM
RCC_Konfiguracja_Adc12();
GPIO_Configuration_Adc1();
ADC1_Configuration();
GPIO_Configuration_Adc1();
GPIO_Configuration_Adc2();
ADC2_Configuration();
IniDiody(GPIO_Pin_14);
IniTimerPrzerwanie1();
while(1)
{
ADC_SoftwareStartConv(ADC1);
ADC_SoftwareStartConv(ADC2);
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
wynikADC1 = (float)ADC_GetConversionValue(ADC1);
while(ADC_GetFlagStatus(ADC2, ADC_FLAG_EOC) == RESET);
wynikADC2 = (float)ADC_GetConversionValue(ADC2);
wartosc = (int)(wynikADC2 * 15);
//doPWM=(((float)ADCResult) / 41);
//wartosc = (int) doPWM;
//TIM2->CCR3 = (int) doPWM;
TIM3->CCR2 = 65535;
TIM3->CCR1 = wartosc;//(int)(wynikADC2 * 15);
wartoscPrescalera=(int)SystemCoreClock;
}
}
and files:
przerwania.h
#ifndef __przerwaniah
#define __przerwaniah
void Nowafunkcja(void);
#endif
przerwania.c
#include "przerwania.h"
void Nowafunkcja(void)
{
//nothing here - just for test
}
Do you have any idea what is the problem? I'm thinking about this since yesterday and its wird :/
I'll appreciate your help!
Take a look at the line under [cc] 12 total files to be compiled.
When you added pwm.c, you also informed the compiler to include this file. You'll see it listed there. przerwania.c is not.
If you add przerwania the same way you added pwm, your IDE will take care of making sure it is included in the build.
I'm not sure what your current file/folder structure looks like:
http://www.coocox.org/CoIDE/Project_management_config.html can help you determine how to pull those new files into the build.
FWIW:
The (anthropomorphized) compiler step says: Is this valid code? So it looks though your main.c, sees that you included przerwania.h, and comes to the conclusion that you correctly used the Nowafunkcja function (just matched the signature). Even though at this point, it has NOT looked into przerwania.c to find out what it does. The compiler goes on to do this for all of your files and keeps track of what functions are defined in each file. Note that it never found the definition Nowafunkcja, because the compiler never compiled przerwania.c. It did however find the declaration in the .h (because main.c told it exactly where to find the .h)
The linker then gets this stuff from the compiler, including what functions have been defined in all your .c files. That's the first point where something tries to answer the question "Now what code do I actually need to run when he asked me to Nowafunkcja()?". So that's the first point in the build when the tools realized, I never found code for Nowafunkcja in any of the .c files I was looking in.
So, I think that roughly answers "Why", but we need to know more about your project organization to give you a "fix" to make it work.
I install libjpeg-dev and all files are in the include folder
/usr/include/jerror.h
/usr/include/jmorecfg.h
/usr/include/jpegint.h
/usr/include/jpeglib.h
/usr/include/turbojpeg.h
/usr/include/x86_64-linux-gnu
/usr/include/x86_64-linux-gnu/jconfig.h
And when I try this simple code to decompress a jpeg image I got the error as in title.
here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <jpeglib.h>
int main(void){
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
return 0;
}
The same problem has buged me for about two days!
my solution is use:
gcc your_code.c -ljpeg
instead of:
gcc -ljpeg your_code.c
to compile your code.
here is the explanation:Why does the order in which libraries are linked sometimes cause errors in GCC?
hope this will help.
That sounds like a linking error.
You are probably not linking to the library code; just including the header is not enough, that's not how C works.
Add something like -ljpeg last on your command line.