use extern structure variable defined in a library, config with cmake - c

main.c
#include "test.h"
extern struct test_struct my_test_str; // defined in my_test_lib.a
int main(int argc, char *argv[]) {
return 0;
}
here is the my_test_my library file of test.h and test.c
compiled as my_test_lib.a
test.h
#ifndef TEST_MY
#define TEST_MY
struct test_struct {
double d1;
double d2;
double d3;
};
void ddd(void);
#endif
test.c
struct test_struct my_test_str;
void ddd(void) {
int a = 0;
int c = 1;
c = a + c;
}
write CMakeLists.txt , use cmake to generated Makefile
cmake_minimum_required(VERSION 2.6)
project(Tutorial)
add_library(my_test_my test.c)
add_executable(Tutorial main.c)
target_link_libraries (Tutorial my_test_my)
after generate Makefiles in a out directory, execute the make
192:out jerryw$ make
[ 25%] Building C object CMakeFiles/my_test_my.dir/test.c.o
[ 50%] Linking C static library libmy_test_my.a
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libmy_test_my.a(test.c.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: libmy_test_my.a(test.c.o) has no symbols
warning: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: warning for library: libmy_test_my.a the table of contents is empty (no object file members in the library define global symbols)
[ 50%] Built target my_test_my
[ 75%] Building C object CMakeFiles/Tutorial.dir/main.c.o
[100%] Linking C executable Tutorial
Undefined symbols for architecture x86_64:
"_ddd", referenced from:
_main in main.c.o
"_my_test_str", referenced from:
_main in main.c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Tutorial] Error 1
make[1]: *** [CMakeFiles/Tutorial.dir/all] Error 2
make: *** [all] Error 2
why this happened ?

Related

Can't use "get_int" in libcs50 for C

So I'm currently new to C right now, and I just downloaded the cs50 library. I tried to make an input by using get_int(), but it's not working. Here's my code:
#include <cs50.h>
#include <stdio.h>
int main(void)
{
int i = get_int("Input: ");
printf("Output: %i\n", i);
}
This is the error that I got
cc calculator.c -o calculator
Undefined symbols for architecture x86_64:
"_get_int", referenced from:
_main in calculator-225c65.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [calculator] Error 1

how to solve this problem compiler error that linker command failed in VSCODE

I wrote some C code on VSCODE like that.
The code is divided into three files: the header, the function, and main in same project folder.
But when I started compile, files are can't compile and error. like terminal text.
Maybe I think this error is linking error..
How to solve this problem..?
[source code]
mysqrt.c
#include "mysqrt.h"
#include <stdio.h>
#include <math.h>
double mysqrt(double a, double b){
double result = sqrt(pow(a,2)+pow(b,2));
return result;
}
mysqrt.h
#include <stdio.h>
double mysqrt(double a, double b);
mysqrtTest.c
#include <stdio.h>
#include <math.h>
#include "mysqrt.h"
void main(void){
double sum = mysqrt(3,4);
printf("%.2f\n",sum);
}
[terminal text]
/Users/kim_donggyun/Desktop/My File/MyFile/VSCodeWorkFolder/2019_2_finalExam/mysqrtTest.c:5:1: warning:
return type of 'main' is not 'int' [-Wmain-return-type]
void main(void){
^
/Users/kim_donggyun/Desktop/My File/MyFile/VSCodeWorkFolder/2019_2_finalExam/mysqrtTest.c:5:1: note: change
return type to 'int'
void main(void){
^~~~
int
1 warning generated.
Undefined symbols for architecture x86_64:
"_mysqrt", referenced from:
_main in mysqrtTest-45c3c1.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
[OS]: macOS Mojave 10.14.6
to resolve your linking issue you need to compile all your c file, as dependencies are not automatically resolved ( header files could be name separately from code file so .h files and .c files are independant ).
# assuming that gcc is your compiler
gcc -Wall -Wextra -Werror -pedantic -o mysqrtTest mysqrtTest.c mysqrt.c -lm
Although I would recommend you to learn about separate compilation, and using a build system, like make
Example of Makefile
mysqrtTest: mysqrtTest.o mysqrt.o
${CC} -o $# $^ -lm
then use make to build your binary

How do I compile with external header file in sublime text in C?

I use one header named header.h in main.c.
The function test is announced in header.h and defined in test.c.
However, it says words below even though I use build system as C.
clang: warning: treating 'c' input as 'c++' when in C++ mode, this behavior is deprecated
Undefined symbols for architecture x86_64:
"test(int)", referenced from:
_main in main-a4d82e.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
[Finished in 0.6s with exit code 1]
[cmd: ['bash', '-c', 'g++ -Wall -std=c++11 -O2 \'/Users/hanlock/Documents/CODE/TEST/TEST/main.c\' -o \'/Users/hanlock/Documents/CODE/TEST/TEST/main\' && osascript -e \'tell application "Terminal" to activate do script " cd \\"/Users/hanlock/Documents/CODE/TEST/TEST\\" &&start_ms=$(ruby -e \\"puts (Time.now.to_f * 1000).to_i\\")&&clear&&\\"/Users/hanlock/Documents/CODE/TEST/TEST/main\\" &&elapsed_ms=$(($(ruby -e \\"puts (Time.now.to_f * 1000).to_i\\") - start_ms))&& read -p \\"Press Enter to exit($elapsed_ms ms).\\"&&exit"\'']]
[dir: /Users/hanlock/Documents/CODE/TEST/TEST]
[path: /usr/bin:/bin:/usr/sbin:/sbin]
I've read similar questions about this in C++. However, it seems not working in my case.
So, here comes the problem. How can I use external header file with sublime in language C?
Here is the code:
main.c
#include <stdio.h>
#include "./Header.h"
int main(int argc, const char * argv[]) {
test(1);
return 0;
}
header.h
#ifndef Header_h
#define Header_h
int test(int);
#endif
test.c
#include <stdio.h>
int test(int i){
printf("%d\n",i);
return 0;
}
In test.c:
#include "header.h"
In your shell:
gcc -I [dir] test.c
This will include any external header named header.h located in dir.
I hope this answers your question.

Link tidylib library to C application

I am trying to use the tidylib library within my C application. When compiling, I get the following errors:
$ make
rm -f sbo-export
cc sbo-export.c safarilib.c -L/usr/local/lib -lcurl -L/usr/local/Cellar/libtidy/lib -I/usr/local/Cellar/libtidy/include -o sbo-export
Undefined symbols for architecture x86_64:
"_tidyCreate", referenced from:
_safari_init_session in safarilib-c7ab6a.o
"_tidyParseString", referenced from:
_safari_init_session in safarilib-c7ab6a.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [default] Error 1
safarilib.c:
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <tidy/tidy.h>
#include <tidy/buffio.h>
#include <curl/curl.h>
#include "safarilib.h"
void usage( char *username, char *password )
{
TidyDoc tdoc = tidyCreate();
char *input = "<html><body><h1>Hello World!</h1></body></html>";
tidyParseString( tdoc, input );
}
Any suggestions?
Further Infos:
For installing libtidy, I did the following:
Downloaded libtidy from http://tidy.sourceforge.net and then
followed the instructions form the file tidy/build/readme.txt
My library is installed here:
/usr/local/Cellar/libtidy
/usr/local/Cellar/libtidy/bin
/usr/local/Cellar/libtidy/bin/tab2space
/usr/local/Cellar/libtidy/bin/tidy
/usr/local/Cellar/libtidy/include
/usr/local/Cellar/libtidy/include/buffio.h
/usr/local/Cellar/libtidy/include/platform.h
/usr/local/Cellar/libtidy/include/tidy.h
/usr/local/Cellar/libtidy/include/tidyenum.h
/usr/local/Cellar/libtidy/lib
/usr/local/Cellar/libtidy/lib/libtidy-0.99.0.dylib
/usr/local/Cellar/libtidy/lib/libtidy.a
/usr/local/Cellar/libtidy/lib/libtidy.dylib
/usr/local/Cellar/libtidy/lib/libtidy.la
From compiler option it's look you have not specified tidylib.
cc sbo-export.c safarilib.c -L/usr/local/lib -lcurl -L/usr/local/Cellar/libtidy/lib -I/usr/local/Cellar/libtidy/include -o sbo-export
Here you need to add -ltidy and probably path by -L .
Some additional info about linking.

C can't compile - symbol(s) not found for architecture x86_64

Having a serious problem with my C code, I just don't seem to be able to get it to compile and I really can't figure out why.
I have tried researching online and can't find a solution to the problem, do you have any idea?
Thanks for your time!
Undefined symbols for architecture x86_64:
"_Insert", referenced from:
_InsertNode in part1.o
(maybe you meant: _InsertNode)
"_Create", referenced from:
_findShortestPaths in part1.o
"_DeleteMin", referenced from:
_findShortestPaths in part1.o
"_decreaseKey", referenced from:
_findShortestPaths in part1.o
"_GetMin", referenced from:
_findShortestPaths in part1.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [part1] Error 1
Snippits from part1.c
#include "limits.h"
#include "pegBinaryHeap.h"
void InsertNode(int distance, Node* node, PriorityQueue PQ) {
...
Insert(*item, PQ);
}
...
int* findShortestPaths(Graph *graph, int start) {
...
//Priority queue ordered by distance
PriorityQueue pq = Create(graph->MaxSize);
for(int i = 0; i < graph->MaxSize; i++) {
...
}
//While the queue isn't empty:
while((currentPqItem=GetMin(pq)) != NULL) {
...
DeleteMin(pq);
//for each node accesable from currentNode
List *currentNeighbour = currentNode.outlist;
while(currentNeighbour!=NULL) {
...
decreaseKey(currentNode.id, newDistance, pq);
} // end for
}// end while
}
int main(int argc,char *argv[])
{
Graph mygraph;
return 0;
}
And the .h file that it appears to be complaining about
#include "graph.h"
struct HeapStruct;
typedef struct HeapStruct *PriorityQueue;
typedef struct {
int distance;
Node *node;
} QueueType;
PriorityQueue Create( int MaxSize );
void Destroy( PriorityQueue H );
int Insert( QueueType Item, PriorityQueue H );
QueueType DeleteMin( PriorityQueue H );
QueueType* GetMin( PriorityQueue H );
void decreaseKey(int nodeId, int value, PriorityQueue H);
You can compile, but you cannot link.
part1.o is using the functions you defined in your last .h file and the implementations cannot be found. When you link your program, you need to make sure you're linking in the object file(s) (or libraries) that contain the implementations of those functions. You've likely done something like:
gcc part1.c -o myapp
and so the linker doesn't have all the pieces to the puzzle.
If you want to compile in parts, you need to:
gcc -c part1.c -o part1.o
gcc -c implementations.c -o implementations.o
gcc implementations.o part1.o -o myapp
Here, all the .c files are compiled into object (.o) files separately, and then linked together into an executable. Or you could do everything at once:
gcc part1.c implementations.c -o myapp
If the implementations are in a library (libimplementations.a):
gcc part1.c -Lpath/to/libs -limplementations -o myapp
I would like to add I was getting a similar compilation error. See below.
Undefined symbols for architecture x86_64:
"_add", referenced from:
_load in file.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [all] Error 1
I solved this issue by implementing the add() functions prototype that I had created in my header file. Once implemented I did not receive this error anymore. May help someone else.
I'd try creating a minimalistic example that shows the same error. We are missing too much information to help you diagnose this. The code in the other files and the actual compilation commands (not just a part of a Makefile but the actual commands) might be the source of this problem.
(yes, this should be a comment rather than an answer, but I'm not able to comment on questions for some reason)

Resources