Its a long time since I've used C but now I'm trying to compile a short script that gets server-stats from the Apache-Portable-Runtime (APR).
Header files located at /usr/include/apr-1/apr*.h and libs are located at /usr/lib64/libapr-1.*
Source files can be found on the official APR site http://apr.apache.org/docs/apr/1.3/files.html.
/* test.c */
#include <stdio.h>
#include <stdlib.h>
#include <apr_general.h>
#include <apr_time.h>
int main(int argc, const char *argv[])
{
apr_time_t t;
t = apr_time_now();
printf("The current time: %" APR_TIME_T_FMT "[us]\n", t);
return 0;
}
When I try and compile I get the following error (which I believe is a linking issue):
~> gcc -Wall $(apr-1-config --cflags --cppflags --includes --link-ld) test.c -o test.bin
/tmp/cc4DYD2W.o: In function `main':
test.c:(.text+0x10): undefined reference to `apr_time_now'
collect2: ld returned 1 exit status
My environment is gentoo:
~> uname -a
Linux alister 2.6.32.21-grsec-gt-r2 #1 SMP Tue Sep 7 23:54:49 PDT 2010\
x86_64 Intel(R) Xeon(R) CPU L5640 # 2.27GHz GenuineIntel GNU/Linux`
~> gcc -v
gcc version 4.3.4 (Gentoo 4.3.4 p1.1, pie-10.1.5)
~> emerge --search "%#^dev-lib.*apr"
* dev-libs/apr
Latest version installed: 1.3.9
* dev-libs/apr-util
Latest version installed: 1.3.9
Does anyone with more experience with C on Linux have any suggestions for me to get this working?
As always thanks in advance.
gcc -Wall -I/usr/include/apr-1 -L/usr/lib64 -lapr-1 test.c -o test.bin
-l specifies which shared library to link to, while -L specifies where to look for shared libraries.
APR provides a tool to make this easier, apr-1-config. Something like this should work:
gcc -Wall $(apr-1-config --cflags --cppflags --includes --link-ld) test.c -o test.bin
I finally got around to looking into this.
gcc mentions -l twice in different contexts:
Linker Options
object-file-name -llibrary ...
Directory Options
... -Idir -Ldir ...
so I moved the -llib after the object name (to get the 2nd context) and it compiled!
APR_CFG=$(apr-1-config --cflags --cppflags --includes --link-ld)
gcc -Wall test.c -o test.bin $APR_CFG
./test.bin
The current time: 1332999950442660[us]
I'm not fully sure I understand the linking order and why it didn't work before (if someone could shed some light on that it would be fantastic) but for now I have enough to continue.
Related
I've tried to use <filesystem> in my CLion project on Fedora 29 environment.
When compiling directly from terminal it works smoothly, but when i try to compile from CLion there is a Linker issue about filesystem. I'm not shure what else I can do. Any suggestions?
g++ (GCC) 8.3.1 20190223 (Red Hat 8.3.1-2)
clang version 7.0.1
(Fedora 7.0.1-6.fc29)
Here is what i have already tried:
I've added the flag -lstdc++fs:
set(CMAKE_CXX_FLAGS -lstdc++fs)
but i didn't worked. I've verified if this flag is in use by:
set( CMAKE_VERBOSE_MAKEFILE on )
and it seems it is:
[ 50%] Building CXX object CMakeFiles/untitled.dir/main.cpp.o
/usr/bin/g++ -lstdc++fs -g -std=gnu++17 -o
CMakeFiles/untitled.dir/main.cpp.o -c
/home/patryk/CLionProjects/untitled/main.cpp
[100%] Linking CXX executable untitled
/home/patryk/clion-2018.3.4/bin/cmake/linux/bin/cmake -E
cmake_link_script CMakeFiles/untitled.dir/link.txt --verbose=1
/usr/bin/g++ -lstdc++fs -g CMakeFiles/untitled.dir/main.cpp.o -o
untitled
/usr/bin/ld: CMakeFiles/untitled.dir/main.cpp.o: in function
`std::filesystem::__cxx11::path::path<char [2],
std::filesystem::__cxx11::path>(char const (&) [2],
std::filesystem::__cxx11::path::format)':
/usr/include/c++/8/bits/fs_path.h:184: undefined reference to
`std::filesystem::__cxx11::path::_M_split_cmpts()'
collect2: error: ld returned 1 exit status
I've tried also to use clang compiler with exact same results.
main.cpp
#include <iostream>
#include <filesystem>
int main() {
std::filesystem::path p("D");
return 0;
}
CMake use target_link_libraries to add -l linker flags.
target_link_libraries(your_executable stdc++fs)
Why set(CMAKE_CXX_FLAGS -lstdc++fs) not working: -l option must be set after your source or object file.
c++ -lstdc++fs some_object.o -o executable # not working
c++ some_object.o -o executable -lstdc++fs # should work
I do not know gcc and c well. In my /home/pi/Desktop/intern/adis16227_generic directory I have following 5 files.
ADIS16227.c
ADIS16227.h
Communication.c
Communication.h
main.c
main.c
#include<stdio.h>
#include "Communication.h" // Communication definitions.
int main() {
printf("hello!!\n");
unsigned char status = 0;
status = SPI_Init(0, 1000000, 1, 1);
printf("%u", status);
return 0;
}
Run command:
$ sudo gcc -L /home/pi/Desktop/intern/adis16227_generic main.c -lCommunication
Error:
/usr/bin/ld: cannot find -lCommunication
collect2: error: ld returned 1 exit status
Question:
What I am missing here?
What do I need to run the code?
-l is for libraries, and you never built a library from your Communication.c. The simplest solution is just add Communication.c to your compiler command line.
For larger projects, compile each translation unit separately with the -c switch like this:
gcc -c -Wall -Wextra -pedantic -omain.o main.c
gcc -c -Wall -Wextra -pedantic -oCommunication.o Communication.c
and so on ... (as a suggestion, I added some common warning options here, they help you spot errors)
The resulting .o files are object code. That's already compiled machine code, but with meta-information needed for a linker to link it with other object code into a complete executable.
Then link them all with one command:
gcc -oprogram main.o Communication.o
If you actually want a library from -- say -- Communication.c and ADIS16227.c, you could compile both to object code:
gcc -c -Wall -Wextra -pedantic -oCommunication.o Communication.c
gcc -c -Wall -Wextra -pedantic --oADIS16227.o ADIS16227.c
and then use ar to create a static library from them:
ar rcs libCommunication.a Communication.o ADIS16227.o
Then your initial compiler command would work (with the -lCommunication switch).
Final piece of advice: Never compile as root. This is completely unnecessary. So remove your sudo here.
those options:
-L /home/pi/Desktop/intern/adis16227_generic -lCommunication
suggest that the linker should find libCommunication.a (or .so) in the /home/pi/Desktop/intern/adis16227_generic directory.
But there are only sources in this directory. The linker won't build the sources of your "Communication" library for you.
So you could build the library and link with it:
gcc -c ADIS16227.c Communication.c
ar r libCommunication.a ADIS16227.o Communication.o
but maybe the fastest & quickest way to achieve a successful build would be:
sudo gcc -o main *.c
so it compiles all the files of the directory into the executable called main
Of course, it makes compilation times longer, but maybe it's not noticeable.
First move into the /home/pi/Desktop/intern/adis16227_generic directory:
cd /home/pi/Desktop/intern/adis16227_generic
Then, compile the source:
gcc ADIS16227.c Communication.c main.c -I .
You can now run your compiled program (called by default a.out):
./a.out
You have to compile separatedly files and then compile main with related obj file.
gcc -c Communication.c Communication.h
gcc main.c Communication.o -o main
I am trying to compile a simple dll following the cygwin tutorial. I have been able to successfully do all but the last step. When I execute the command:
gcc -o myprog myprog.c -L./ -lmydll
I get an error saying that hello() is not declared in that scope. I followed the tutorial verbatim, yet I am still not able to compile the simple project and am lost as to why.
The code for the individual files are as follows:
(myprog.c)
int main(void){
hello();
}
(mydll.c)
#include <stdio.h>
int hello(){
printf("Hello World!\n");
return 0;
}
The example is working fine for me in my Cygwin
armathew#3NJ2VQ1 /cygdrive/d/userdata/armathew/Desktop/WWWW
$ ls
mydll.c myprog.c
armathew#3NJ2VQ1 /cygdrive/d/userdata/armathew/Desktop/WWWW
$ gcc -c mydll.c
armathew#3NJ2VQ1 /cygdrive/d/userdata/armathew/Desktop/WWWW
$ gcc -shared -o mydll.dll mydll.o
armathew#3NJ2VQ1 /cygdrive/d/userdata/armathew/Desktop/WWWW
$ gcc -o myprog myprog.c -L./ -lmydll
armathew#3NJ2VQ1 /cygdrive/d/userdata/armathew/Desktop/WWWW
$ ./myprog.exe
Hello World!
What is the Cygwin version you are using? Mine is 1.7.5
armathew#3NJ2VQ1 /cygdrive/d/userdata/armathew/Desktop/WWWW
$ uname -r
1.7.5(0.225/5/3)
well, the statement for linking library may be incorrect.
It should be
-L<library path> -lyoulibrarymane
as there is no "./" after the library path.
here is an example that I used, it may be helpful. the -I/usr/local/include is the header file path
gcc -o hello-world helloopencv.c -I/usr/local/include -L/usr/local/lib -lopencv_highgui -lopencv_core -lopencv_imgproc
You need to add a declaration at the top of myprog.c:
int hello(void);
Or you could put this in a new mydll.h and #include that in myprog.c.
The GMP docs say that static linking may provide a small performance improvement.
I am having a problem getting it to staticly link libgmp on my Linux systems. I've narrowed down the issue I'm having to a tiny test case.
gmptest.c
#include <gmp.h>
int main(int argc, char** argv) {
mpz_t foo;
mpz_init(foo);
return 0;
}
Makefile:
all: clean gmptest static
clean:
rm -f *.s
rm -f *.o
rm -f gmptest
rm -f static-gmptest
gmptest: Makefile gmptest.c
gcc -std=c99 -O3 -lgmp gmptest.c -o gmptest
static: clean Makefile gmptest.c
gcc -std=c99 -O3 -static /usr/lib/libgmp.a gmptest.c -o static-gmptest
The non-static binary is compiled and linked without any issues, but 'Make static' produces:
gcc -std=c99 -O3 -static /usr/lib/libgmp.a gmptest.c -o static-gmptest
/tmp/ccWSFke9.o: In function `main':
gmptest.c:(.text+0x8): undefined reference to `__gmpz_init'
collect2: ld returned 1 exit status
make: *** [static] Error 1
The library does exist:
chris#vostro:~/Dropbox/static$ ls -lA /usr/lib/libgmp.a
-rw-r--r-- 1 root root 1041666 2010-02-26 13:20 /usr/lib/libgmp.a
I have also tried -lgmp for the static linking, but the error is the same.
This is all on Ubuntu 10.04 and 10.10 AMD64.
Can some enlighten me as to the obvious error I'm making?
Thanks,
Chris.
Try
gcc -std=c99 -O3 -static gmptest.c -lgmp -o static-gmptest
since libraries should always be linked in the good order, and after the program or object files using them.
Here, in GMP 6.1.2 / MINGW and assuming certain portability, I find that the header "gmp.h" has fix link mode, as configured with GMP build parameters.
/* Instantiated by configure. */
#if ! defined (__GMP_WITHIN_CONFIGURE)
#define _LONG_LONG_LIMB 1
#define __GMP_LIBGMP_DLL 0
#endif
As with this the compiler will never generate static object decorations, and so the linker will never match the static libgmp, I conditioned the define __GMP_LIBGMP_DLL
/* Added link switch GMP_STATIC */
#if ! defined (__GMP_WITHIN_CONFIGURE)
#define _LONG_LONG_LIMB 1
#ifndef GMP_STATIC // SGR 2021-12-30
#define __GMP_LIBGMP_DLL 1
#endif
#endif
Now, with defined GMP_STATIC the static libgmp.a is successfully attracted and without GMP_STATIC the dynamic libgmp.dll.a.
I'm trying to compile a C project I've been working on on a remote server that runs OS X. The project depends, in part, on libcurl. I only have access to the machine through my administrator account remotely.
When I attempt to make the project I keep getting errors relating to libcurl functions and constants not being defined. I conclude that libcurl is not being properly included by the compiler.
I'm using fink to install opensource software for all the dependencies ( postgres, curl, a few others ) and all the dependencies appear to work except curl.
My compiler command looks like:
gcc -ggdb -ansi -Wall -D_GNU_SOURCE -L `/sw/bin/pg_config --libdir` `/sw/bin/curl-config --cflags` -I `/sw/bin/pg_config --includedir` -lpq -lcurl -lpthread -lm `/sw/bin/curl-config --libs` -c Client.c
If I make a test file like so:
/sw/bin/curl http://www.google.com/ --libcurl test.c
And then attempt to compile it with:
gcc test.c `/sw/bin/curl-config --cflags` `/sw/bin/curl-config --libs` -o test.o
It also fails. Can anyone help me shed some light on this problem?
One compilation line is:
gcc -ggdb -ansi -Wall -D_GNU_SOURCE -L `/sw/bin/pg_config --libdir` \
`/sw/bin/curl-config --cflags` -I `/sw/bin/pg_config --includedir` \
-lpq -lcurl -lpthread -lm `/sw/bin/curl-config --libs` -c Client.c
This will take Client.c and generate Client.o, an object file. It doesn't need the library information; there is no linking taking place because of the -c option.
The other compilation line is:
gcc test.c `/sw/bin/curl-config --cflags` `/sw/bin/curl-config --libs` -o test.o
It is aconventional to end the names of executables with '.o'; it leads to confusion. However, if test.c only references functions from the standard libraries and libcurl, it should 'work'.
On my Mac, there is a copy of curl-config in /usr/bin.
Try this test program:
$ cat curltest.c
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
if (curl_global_init(0) == CURLE_OK)
{
printf("CURL version %s\n", curl_version());
curl_global_cleanup();
}
else
fprintf(stderr, "Failed to initialize CURL\n");
return 0;
}
$ cc -o curltest $(curl-config --cflags) curltest.c $(curl-config --libs)
$ file curltest
curltest: Mach-O 64-bit executable x86_64
$ otool -L curltest
curltest:
/usr/lib/libcurl.4.dylib (compatibility version 6.0.0, current version 6.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
$ curltest
CURL version libcurl/7.19.7 OpenSSL/0.9.8r zlib/1.2.3
$
This is on MacOS X 10.6.8.