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)\\\"
Related
How can i suppress this warning?
maybe some #pragma GCC diagnostic ignored in code or CFLAG in makefile?
If you had posted the full warning message it should show the specific warning [-Wdiscarded-qualifiers]. Like other warnings, just prefix with no- to suppress it.
From the gcc manual
-Wno-discarded-qualifiers (C and Objective-C only)
Do not warn if type qualifiers on pointers are being discarded. Typically, the compiler warns if a const char * variable is passed to a function that takes a char * parameter. This option can be used to suppress such a warning.
$ cat test.c
#include <stdio.h>
int a;
volatile int *p = &a;
int main (void)
{
int *q = p;
return 0;
}
$ gcc test.c
test.c: In function ‘main’:
test.c:8:11: warning: initialization discards ‘volatile’ qualifier from pointer target type [-Wdiscarded-qualifiers]
int *q = p;
^
$ gcc -Wno-discarded-qualifiers test.c
$
Although you probably already know it is a bad programming tactic, you can disable warnings in general when compiling and not only the one that bugs you.
Add -w option when compiling
I also attach you the documentation on Warnings Options.
http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Hope i helped!
ok thanks guys. -Wdiscarded-qualifiers not really helped me.
actually ive tried to find it in gcc docs, but i am not good at this.
here`s my cflags in project
CFLAGS ?= -g0 -O3 -Wno-discarded-qualifiers -Wshadow -Wmaybe-uninitialized -Wall -Wextra -Wno-unused-function -Wno-error=strict-prototypes -Wpointer-arith -fno-strict-aliasing -Wno-error=cpp -Wuninitialized -Wmaybe-uninitialized -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default -Wno-switch-enum -Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-error=pedantic -Wno-sign-compare -Wno-error=missing-prototypes -Wdouble-promotion -Wclobbered -Wdeprecated -Wempty-body -Wtype-limits -Wno-unused-value -Wno-unused-parameter -Wno-missing-field-initializers -Wuninitialized -Wmaybe-uninitialized -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wpointer-arith -Wno-cast-qual -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-sign-compare
LDFLAGS ?= -lm
and the reason that i am using discard volatile qualifiers is that i dont want to add volatile in function prototypes and dont want to cast it in function call, because some of variables works fine without volatile key, and others - not.
(its some common variables and also thread_t types)
so code works fine, also when ive tried to cast volatile types in function call - there some glitches happened, and now all works fine. Thanks for help i appreciate that!
now with that key i have
"discards 'volatile' qualifier from pointer target type"
its pointers that sometimes get optimizated by compiler.
I wrote a simple printf C code and made a simple makefile.
When I run make with CFLAGS, CPPFLAGS and LDFLAGS, the values of the variables goes into a cc execution, followed by a gcc execution without those values, like this:
$ CFLAGS="-I." CPPFLAGS="-D TESTEDEFINE" CXXFLAGS="TESTECXXFLAGS" LDFLAGS="-L." LFLAGS="TESTELFLAGS" make
cc -I. -D TESTEDEFINE -L. teste.c -o teste
gcc -o teste teste.c
When I run the built program, the define isn't defined since it gives me the printf of the not defined #else.
teste.c
#include <stdio.h>
int main()
{
#if defined(TESTEDEFINE)
printf("TESTEDEFINE!!!");
#else
printf("!!!");
#endif
return 0;
}
Makefile
all: teste
gcc -o teste teste.c
The variables are for consistency, readability, and ease of use. Neither your compile nor your makefile reference them. The compiler does not automatically reference those variables.
Try this instead:
$ export CFLAGS="-I." CPPFLAGS="-D TESTEDEFINE" CXXFLAGS="TESTECXXFLAGS" LDFLAGS="-L." LFLAGS="TESTELFLAGS"
$ gcc $CFLAGS $CPPFLAGS $CXXFLAGS $LDFLAGS $LFLAGS -o teste teste.c
You would also need to define them in your makefile and reference them in the compiler line.
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 have multiple C and H files
In main.c I defined a macro, and in ws_driver.c I want to use it.
ws_driver.h is included in main.c.
main.c
#define WS_PORT PORT_D8
#define WS_BIT D8
#define WS_DDR DDR_D8
#include "ws_driver.h"
In ws_dirver.c I have two checks:
ws_driver.c
#include "ws_driver.h"
#ifndef WS_PORT
# error "WS_PORT not defined!"
#endif
#ifndef WS_BIT
# error "WS_BIT not defined!"
#endif
Both are failing.
$ avr-gcc -std=gnu99 -mmcu=atmega328p -DF_CPU=16000000UL -Os -I. -I -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wno-main -Wno-strict-prototypes -Wno-comment -g2 -ggdb -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax -std=gnu99 main.c ws_driver.c --output main.elf
ws_driver.c:10:3: error: #error "WS_PORT not defined!"
# error "WS_PORT not defined!"
^
ws_driver.c:14:3: error: #error "WS_BIT not defined!"
# error "WS_BIT not defined!"
^
ws_driver.c: In function 'ws_show':
ws_driver.c:23:20: error: 'WS_PORT' undeclared (first use in this function)
#define bus_low() (WS_PORT) &= ~(1 << WS_BIT)
^
ws_driver.c:37:2: note: in expansion of macro 'bus_low'
bus_low();
^
ws_driver.c:23:20: note: each undeclared identifier is reported only once for each function it appears in
#define b......
What am I doing wrong? Please ask if you want to see some other part of the code.
You have to define the macros in a header file, not in the .c file if you want to use them in multiple places.
When the compiler compiles ws_driver.c it only includes ws_driver.h and the macro is not there. It does not include main.c. Each .c file is compiled separately.
Move the macro definitions in say config.h and include it everywhere you need it.
You can also use the compiler's define -DWS_BIT=123 -DOTHER=SMTH. The value you pass will be in the generated object file and can not be changed without recompiling.
If you want to compile only once, then pass these as parameters or create a configure_my_library() function...
value *= pow(10, 3); // this one compiles
value *= pow(10, aVar); // this one produces this error:
//Number.c:(.text+0x469): undefined reference to `pow'
aVar is an int variable.
What could it be?
I'm using a makefile.
I'm excecuting "make lexanc"
My makefile looks like this:
lexanc: lexandr.o lexanc.o scanner.o printtoken.o token.h lexan.h Number.o
cc -o lexanc -lm lexandr.o lexanc.o scanner.o printtoken.o Number.o
...
Number.o: Number.c Number.h lexan.h
cc -c Number.c
lexanc.o: lexanc.c token.h lexan.h Number.h
cc -c lexanc.c
...
My cc version is:
laygr#xxx$ cc --version
cc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Libraries should come after all the objects in the compiling option. Change it to:
lexanc: lexandr.o lexanc.o scanner.o printtoken.o token.h lexan.h Number.o
cc -o lexanc lexandr.o lexanc.o scanner.o printtoken.o Number.o -lm
Note -lm has been moved to the end.
Are you including math.h? Try adding -Wall -ansi -pedantic as command line arguments to the C compiler. There is usually a definition of CFLAGS somewhere for this purpose.
EDIT
This is actually a common problem that I had completely forgotten about. Move the -lm to the end of the parameter list. More specifically, it needs to be after all of the objects. Take a look at answers to this question for more details.