I'm running into a weird syntax error when I try to compile tests using the check unit testing framework with the -std=c99 flag.
So, I'm trying to compile the example.c:
#include <check.h>
START_TEST(example) {
fail();
} END_TEST
int main(int argc, char** argv){ return 0; }
using autotools, with Makefile.am:
check_PROGRAMS = example
example_SOURCES = example.c
example_CFLAGS = #CHECK_CFLAGS# -Wall -pedantic -std=c99
example_LDADD = #CHECK_LIBS#
and configure.ac:
AC_PREREQ([2.61])
AC_INIT([example], [1.0.0], [noreply#here.com])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
AC_CONFIG_SRCDIR([example.c])
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_RANLIB
PKG_CHECK_MODULES([CHECK], [check >= 0.9.5])
AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h string.h unistd.h])
AC_C_CONST
AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_UINT32_T
AC_FUNC_FORK
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_FUNC_STAT
AC_CHECK_FUNCS([memset])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
However I get this weird error:
% make check
make example
gcc -DPACKAGE_NAME=\"example\" -DPACKAGE_TARNAME=\"example\" -DPACKAGE_VERSION=\"1.0.0\" -DPACKAGE_STRING=\"example\ 1.0.0\" -DPACKAGE_BUGREPORT=\"noreply#here.com\" -DPACKAGE=\"example\" -DVERSION=\"1.0.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_UNISTD_H=1 -DHAVE_FORK=1 -DHAVE_VFORK=1 -DHAVE_WORKING_VFORK=1 -DHAVE_WORKING_FORK=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_STDLIB_H=1 -DHAVE_REALLOC=1 -DHAVE_MEMSET=1 -I. -I/opt/local/include -std=c99 -g -O2 -MT example-example.o -MD -MP -MF .deps/example-example.Tpo -c -o example-example.o `test -f 'example.c' || echo './'`example.c
example.c: In function 'example':
example.c:3: error: parse error before ',' token
make[1]: *** [example-example.o] Error 1
make: *** [check-am] Error 2
So it's finding a syntax error in fail() (which I suppose check implements as a macro). If I remove the -std=c99 flag, the syntax error goes away, and it works fine.
Is there a way I can fix this? I definitely want -std=c99 so that my use (and check.h's use) of variadic macros is ok'd by the compiler.
The basic tutorial on that site always shows the fail called between START_TEST and END_TEST macros. They most likely set some things up for these macros. Done.
Now all you need to get that to compile is give fail() an argument.
It's defined like this:
#define fail(...) _fail_unless(0, __FILE__, __LINE__, "Failed" , ## __VA_ARGS__, NULL)
Which will have a stray , if no argument is given.
Related
I have a github repo representing my exercise folder. Upon running make all the compiler throws error messages saying (Ubuntu):
cc -g -O2 -Wall -Wextra -Isrc -DNDEBUG -fPIC -c -o src/libex29.o src/libex29.c
src/libex29.c: In function ‘fail_on_purpose’:
src/libex29.c:36:33: warning: unused parameter ‘msg’ [-Wunused-parameter]
int fail_on_purpose(const char* msg)
^~~
ar rcs build/libex29.a src/libex29.o
ranlib build/libex29.a
cc -shared -o build/libex29.so src/libex29.o
cc -g -Wall -Wextra -Isrc test/ex29_test.c -o test/ex29_test
/tmp/cc7dbqDt.o: In function `main':
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:21: undefined reference to `dlopen'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:22: undefined reference to `dlerror'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:25: undefined reference to `dlsym'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:26: undefined reference to `dlerror'
/home/givi/Desktop/lcthw_dir/29/test/ex29_test.c:33: undefined reference to `dlclose'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'test/ex29_test' failed
make: *** [test/ex29_test] Error 1
i spent quite a lot trying to figure out how to fix undefined references. dlfcn.h is included, everything seems to be ok. Am i missing something? Please help
You must add following option when linking code using dlopen(3) :
-ldl
Here is a demo for Ubuntu 18:
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
$ cat dl.c
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
void *r;
r = dlopen("", RTLD_LAZY);
if (r != NULL)
printf("r is not null \n");
return 0;
}
$ gcc -o dl -Wall -pedantic -std=c11 dl.c -ldl
$ echo $?
0
Here is a very simple Makefile(note position of -ldl) and related make commands:
$ cat Makefile
CFLAGS=-g -O2 -Wall -Wextra -Isrc -DNDEBUG $(OPTFLAGS) $(OPTLIBS)
dl.o :dl.c
$(CC) -c $< $(CFLAGS)
dl :dl.o
$(CC) -o $# $^ $(CFLAGS) -ldl
clean :
rm -f dl dl.o
$ make clean
rm -f dl dl.o
$ make dl
cc -c dl.c -g -O2 -Wall -Wextra -Isrc -DNDEBUG
dl.c: In function ‘main’:
dl.c:5:14: warning: unused parameter ‘argc’ [-Wunused-parameter]
int main(int argc, char **argv)
^~~~
dl.c:5:27: warning: unused parameter ‘argv’ [-Wunused-parameter]
int main(int argc, char **argv)
^~~~
cc -o dl dl.o -g -O2 -Wall -Wextra -Isrc -DNDEBUG -ldl
$ ./dl
r is not null
Usually the references you're missing can be resolved by adding linker flag -ldl.
You didn't mention which operating system you're using.
In case you're on Windows you'll need this library: https://github.com/dlfcn-win32/dlfcn-win32
I am trying to compile the following source file using gcc -g -Wall -Wextra -pedantic -std=c99 -o main -lm.
source.h
void simple_sum(void)
source.c
#include "source.h"
#include <stdio.h>
void simple_sum(void)
{
int a, b;
scanf("%d %d", &a, &b);
printf("%d + %d = %d\n",a, b, a + b);
}
main.c
#include "source.h"
#include <stdio.h>
int main(void)
{
printf("\n");
simple_sum();
return 0;
}
I get following error:
gcc -g -Wall -Wextra -pedantic -std=c99 -o main -lm
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function _start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'main' failed
make: *** [main] Error 1
Could someone please suggest how to fix this?
Edit
I get the following error when I run using gcc -g -Wall main.c -o main
/tmp/ccEAL4iG.o: In functionmain':
/home/a/aalto_university/functions/calculation/main.c:7: undefined reference to simple_sum'
collect2: error: ld returned 1 exit status
Compile with
gcc -g -Wall -Wextra -pedantic -std=c99 source.c main.c -o myprog -lm
(actually, -lm is not needed, you don't use <math.h> functions; but keeping -lm should not harm)
Later, learn to write your Makefile to do these things in several steps:
First, get the source.o object file with
gcc -g -Wall -Wextra -pedantic -std=c99 -c source.c
then get the main.o object file with
gcc -g -Wall -Wextra -pedantic -std=c99 -c main.c
At last, link both of them
gcc -g source.o main.o -lm -o myprog
Here
gcc -g -Wall -Wextra -pedantic -std=c99 -o main -lm
you are not providing source file name to linker, hence it throw error like
undefined reference to `main'
While compiling provide source file main.c and source.c. For e.g first run this
gcc -g -Wall -Wextra -pedantic -std=c99 -c main.c source.c -lm
to create the object.o files & then create the executable by running
gcc source.o main.o -o my_exe
And finally run the executable. Also declaration of simple_sum() missing ; it should be
void simple_sum(void); /* you miss ;*/
Also learn how to use Makefile for compilation as #Basile pointed, there you don't have to create .o file manually, your Makefile will create .o file & compile if it's written correctly.
In the openwrt package that I'm working on, I defined a new config flag by adding following bloc to the Config.in file:
config VENDOR_PREFIX
string "Vendor Prefix"
default "X_Custom_SE_"
The flag is well added in the menuconfig:
I want that the value of this config flag is viewed in my C code as a macro. So I defined a macro CUSTOM_PREFIX in the Makefile of the package and assigned to it the value of the defined flag with this way:
TARGET_CFLAGS += -DCUSTOM_PREFIX=\"$(CONFIG_VENDOR_PREFIX)\"
and then I tried to use my macro in my C code by calling it in a structure variable initiation like that:
struct parameter_struct param1= {CUSTOM_PREFIX"param1", 4};
After that I tried to compile it. But I got this compilation error:
/home/user/openwrt//staging_dir/toolchain-mips_mips32_gcc-5.5.0_musl/usr/include -I/home/user/openwrt/staging_dir/toolchain-mips_mips32_gcc-5.5.0_musl/include/fortify -I/home/user/openwrt/staging_dir/toolchain-mips_mips32_gcc-5.5.0_musl/include -I/home/user/openwrt/staging_dir/target-mips_mips32_musl/usr/include -I/home/user/openwrt/staging_dir/target-mips_mips32_musl/usr/include -I/home/user/openwrt/staging_dir/target-mips_mips32_musl/usr/include -DCWMP_VERSION=\"3.0.0\" -I../inc/ -I../dm/ -I../dm/dmtree/ -I../dm/dmtree/common -I../dm/dmtree/tr098 -I../dm/dmtree/tr181 -I../dm/dmtree/upnp -Os -pipe -mips32 -mtune=mips32 -fno-caller-saves -DCONFIG_TARGET_iopsys_brcm63xx_mips -g3 -fno-caller-saves -fno-plt -fhonour-copts -Wno-error=unused-but-set-variable -Wno-error=unused-result -msoft-float -iremap/home/user/openwrt/build_dir/target-mips_mips32_musl/icwmp-curl/icwmp-4.0-2018-03-21:icwmp-4.0-2018-03-21 -Wformat -Werror=format-security -fstack-protector -D_FORTIFY_SOURCE=1 -Wl,-z,now -Wl,-z,relro -DCUSTOM_PREFIX=X_CUSTOM1_SE_ -D_GNU_SOURCE -D_AADJ -MT ../dm/dmtree/common/libdatamodel_la-deviceinfo.lo -MD -MP -MF ../dm/dmtree/common/.deps/libdatamodel_la-deviceinfo.Tpo -c ../dm/dmtree/common/deviceinfo.c -fPIC -DPIC -o ../dm/dmtree/common/.libs/libdatamodel_la-deviceinfo.o
^
../dm/dmtree/common/deviceinfo.c: At top level:
<command-line>:0:15: error: 'X_CUSTOM1_SE_' undeclared here (not in a function)
../dm/dmtree/common/deviceinfo.c:28:2: note: in expansion of macro 'CUSTOM_PREFIX'
{CUSTOM_PREFIX"param1", 4}
struct parameter_struct param1= {CUSTOM_PREFIX"param1", 4};
seems like that the c program doesn't accept it as a string.
Is there something wrong in my macro definition?
As I expected and I noted in the my post title the mistake is in the definition of the macro in the Makefile. In Openwrt Makefile the definition of the Macro should be like that:
TARGET_CFLAGS += -DCUSTOM_PREFIX=\\\"$(CONFIG_VENDOR_PREFIX)\\\"
I have the next code :
test.c
#include "a1.h"
int main() {
int a = 8;
foo(a);
return a;
}
a1.h
void foo (int a);
a1.c
int f = 0;
void foo (int a, int b){
f=5+a+b;
return;
}
Pay attention that in a1.c foo has 1 more parameter than the prototype defined in a1.h.
The compiler isn't issue a warning or an error and so as coverity :
make all
Building file: ../src/a1.c
Invoking: GCC C Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/a1.d" -MT"src/a1.d" -o "src/a1.o" "../src/a1.c"
Finished building: ../src/a1.c
Building file: ../src/test.c
Invoking: GCC C++ Compiler
gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/test.d" -MT"src/test.d" -o "src/test.o" "../src/test.c"
Finished building: ../src/test.c
Building target: test
Invoking: GCC C++ Linker
gcc -o "test" ./src/a1.o ./src/test.o
Finished building target: test
How can I defend myself in those cases ? I know that if I will add #include "a1.h" in the a1.c file I will get an error but is there a way to get an error without the "include " ?
Compiler isn't issuing a warning because it does not know that foo(int) from a1.h header and foo(int,int) from a1.c file is the same function. C++ allows functions to be overloaded, so both functions could potentially coexist. That is why C++ compiler cannot detect this problem, so you need to wait until the linking stage.
If you were compiling using C, not C++, you could have the compiler detect this condition simply by including a1.h at the top of a1.c file.
You're overloading foo. The version with only one parameter is never defined, hence you should get a linker error when using it.
How can I defend myself in those cases ?
You can't defend yourself from function overloading. Just make sure that you've got the same signature in both the header as the source file.
I am trying to add Mersenne twister random library inside a Freeswitch module but when I try to compile and link I get:
making all mod_svbilling
Compiling /usr/src/freeswitch-1.2.12/src/mod/applications/mod_svbilling/mod_svbilling.c...
Compiling /usr/src/freeswitch-1.2.12/src/mod/applications/mod_svbilling/mod_svbilling.c ...
Creating mod_svbilling.so...
mtwist.o: In function `mts_lrand':
mtwist.c:(.text+0x0): multiple definition of `mts_lrand'
.libs/mod_svbilling.o:/usr/src/freeswitch-1.2.12/src/mod/applications/mod_svbilling/./mtwist/mtwist.h:417: first defined here
mtwist.o: In function `mts_llrand':
mtwist.c:(.text+0x6d): multiple definition of `mts_llrand'
.libs/mod_svbilling.o:/usr/src/freeswitch-1.2.12/src/mod/applications/mod_svbilling/./mtwist/mtwist.h:446: first defined here
mtwist.o: In function `mts_drand':
mtwist.c:(.text+0x189): multiple definition of `mts_drand'
.libs/mod_svbilling.o:/usr/src/freeswitch-1.2.12/src/mod/applications/mod_svbilling/./mtwist/mtwist.h:488: first defined here
mtwist.o: In function `mts_ldrand':
mtwist.c:(.text+0x210): multiple definition of `mts_ldrand'
.libs/mod_svbilling.o:/usr/src/freeswitch-1.2.12/src/mod/applications/mod_svbilling/./mtwist/mtwist.h:507: first defined here
mtwist.o: In function `mt_lrand':
mtwist.c:(.text+0x349): multiple definition of `mt_lrand'
.libs/mod_svbilling.o:/usr/src/freeswitch-1.2.12/src/mod/applications/mod_svbilling/./mtwist/mtwist.h:555: first defined here
mtwist.o: In function `mt_llrand':
mtwist.c:(.text+0x3d7): multiple definition of `mt_llrand'
.libs/mod_svbilling.o:/usr/src/freeswitch-1.2.12/src/mod/applications/mod_svbilling/./mtwist/mtwist.h:575: first defined here
mtwist.o: In function `mt_drand':
mtwist.c:(.text+0x55c): multiple definition of `mt_drand'
.libs/mod_svbilling.o:/usr/src/freeswitch-1.2.12/src/mod/applications/mod_svbilling/./mtwist/mtwist.h:618: first defined here
mtwist.o: In function `mt_ldrand':
mtwist.c:(.text+0x604): multiple definition of `mt_ldrand'
.libs/mod_svbilling.o:/usr/src/freeswitch-1.2.12/src/mod/applications/mod_svbilling/./mtwist/mtwist.h:636: first defined here
collect2: ld returned 1 exit status
gcc -I. -I./svblic -I./mtwist -fPIC -DVERSION= -DSVN_REV=108M -I/usr/src/freeswitch-1.2.12/libs/curl/include -I/usr/src/freeswitch-1.2.12/src/include -I/usr/src/freeswitch-1.2.12/src/include -I/usr/src/freeswitch-1.2.12/libs/libteletone/src -I/usr/src/freeswitch-1.2.12/libs/stfu -fPIC -Werror -fvisibility=hidden -DSWITCH_API_VISIBILITY=1 -DHAVE_VISIBILITY=1 -g -ggdb -DHAVE_OPENSSL -g -O2 -Wall -std=c99 -pedantic -Wdeclaration-after-statement -D_GNU_SOURCE -shared -o .libs/mod_svbilling.so -shared -Wl,-x .libs/mod_svbilling.o aes.o lic.o md5.o sysinfo.o mtwist.o -lsqlite3 -lm /usr/src/freeswitch-1.2.12/.libs/libfreeswitch.so -L/usr/src/freeswitch-1.2.12/libs/apr-util/xml/expat/lib -lpq /usr/src/freeswitch-1.2.12/libs/apr-util/xml/expat/lib/.libs/libexpat.a /usr/src/freeswitch-1.2.12/libs/apr/.libs/libapr-1.a -lpthread -L/usr/src/freeswitch-1.2.12/libs/srtp -lcrypt -lrt -lssl -lcrypto -ldl -lz -lncurses -ljpeg -lodbc -Wl,--rpath -Wl,/usr/local/freeswitch/lib -Wl,--rpath -Wl,/usr/local/freeswitch/mod
make[4]: *** [mod_svbilling.so] Error 1
make[3]: *** [all] Error 1
make[2]: *** [mod_svbilling-all] Error 1
make[1]: *** [mod_svbilling] Error 2
make: *** [mod_svbilling] Error 2
Makefile I am using looks like:
BASE=../../../..
SVN_REV=$(shell svnversion -n .)
SVB_LIB_FLAGS = -lm -lpthread -lsqlite3
SVB_CFLAGS = -I. -I./svblic -I./mtwist -fPIC
MOD_CFLAGS=$(SVB_LIB_FLAGS) $(SVB_CFLAGS) -DVERSION=$(VERSION) -DSVN_REV=$(SVN_REV)
LOCAL_OBJS=aes.o lic.o md5.o sysinfo.o mtwist.o
local_depend: $(LOCAL_OBJS)
sysinfo.o: ./svblic/sysinfo.c
gcc $(SVB_CFLAGS) -c ./svblic/sysinfo.c
aes.o: ./svblic/aes.c
gcc $(SVB_CFLAGS) -c ./svblic/aes.c
md5.o: ./svblic/md5.c
gcc $(SVB_CFLAGS) -c ./svblic/md5.c
lic.o: ./svblic/lic.c
gcc $(SVB_CFLAGS) -c ./svblic/lic.c
mtwist.o: ./mtwist/mtwist.c
gcc $(SVB_CFLAGS) -c ./mtwist/mtwist.c
include $(BASE)/build/modmake.rules
I only added following header to my module source code:
#include "./mtwist/mtwist.h"
I don't know why it sais those functions are already defined. mtwist.h has one define in order to avoid redefine those functions
Any idea?
Regards