Our build system is using gcc to generate source file's header dependencies to *.d files, when compiling:
gcc -MD -MF foo.d -c foo.o foo.cc
However, I can't figure out how to produce similar output with llvm clang.
It's exactly the same:
clang -MD -MF foo.d -c foo.o foo.cc
An example:
$ cat example.c
#include <stdio.h>
int main(int argc, char **argv)
{
printf("Hello, world!\n");
return 0;
}
$ clang -MD -MF example-clang.d -c -o example-clang.o example.c
$ gcc -MD -MF example-gcc.d -c -o example-gcc.o example.c
$ cat example-clang.d
example-clang.o: example.c /usr/include/stdio.h /usr/include/_types.h \
/usr/include/sys/_types.h /usr/include/sys/cdefs.h \
/usr/include/machine/_types.h /usr/include/i386/_types.h \
/usr/include/secure/_stdio.h /usr/include/secure/_common.h
$ cat example-gcc.d
example-gcc.o: example.c /usr/include/stdio.h /usr/include/_types.h \
/usr/include/sys/_types.h /usr/include/sys/cdefs.h \
/usr/include/machine/_types.h /usr/include/i386/_types.h \
/usr/include/secure/_stdio.h /usr/include/secure/_common.h
$ diff example-clang.d example-gcc.d
1c1
< example-clang.o: example.c /usr/include/stdio.h /usr/include/_types.h \
---
> example-gcc.o: example.c /usr/include/stdio.h /usr/include/_types.h \
Related
I need to use libcurl with https in my project, so I've built zlib, openssl and libcurl (with mingw32-make mingw32-ssl-zlib) successfully. But after I copied include libcurl.a libcurldll.a libcurl.dll to my project folder, sent a GET request to https://www.google.com it failed with error Unsupported protocol
My OPENSSL_PATH and ZLIB_PATH in my lib/Makefile.m32 src/Makefile.m32 are:
ZLIB_PATH = ../../zlib-1.2.8
OPENSSL_PATH = /c/OpenSSL
and the build log:
Compeador#DESKTOP-QCSNUGN MSYS /e/programming/c/lib/curl-7.74.0
$ mingw32-make mingw32-ssl-zlib
C:/msys64/mingw32/bin/mingw32-make.exe -C lib -f Makefile.m32 CFG=mingw32-ssl-zlib
mingw32-make[1]: Entering directory 'E:/programming/c/lib/curl-7.74.0/lib'
gcc -I. -I../include -I"C:/OpenSSL/include" -I"../../zlib-1.2.8" -g -O2 -Wall -W -fno-strict-aliasing -m32 -DBUILDING_LIBCURL -DUSE_OPENSSL -DHAVE_OPENSSL_PKCS12_H -DOPENSSL_NO_KRB5 -DHAVE_LIBZ -DHAVE_ZLIB_H -c altsvc.c -o altsvc.o
gcc ......
ar cru libcurl.a altsvc.o amigaos.o asyn-ares.o asyn-thread.o base64.o conncache.o connect.o content_encoding.o cookie.o curl_addrinfo.o curl_ctype.o curl_des.o curl_endian.o curl_fnmatch.o curl_get_line.o curl_gethostname.o curl_gssapi.o curl_memrchr.o curl_multibyte.o curl_ntlm_core.o curl_ntlm_wb.o curl_path.o curl_range.o curl_rtmp.o curl_sasl.o curl_sspi.o curl_threads.o dict.o dotdot.o easy.o escape.o file.o fileinfo.o formdata.o ftp.o url.o ftplistparser.o getenv.o getinfo.o gopher.o hash.o hmac.o hostasyn.o hostcheck.o hostip.o hostip4.o hostip6.o hostsyn.o http.o http2.o http_chunks.o http_digest.o http_negotiate.o http_ntlm.o http_proxy.o idn_win32.o if2ip.o imap.o inet_ntop.o inet_pton.o krb5.o ldap.o llist.o md4.o md5.o memdebug.o mime.o mprintf.o mqtt.o multi.o netrc.o non-ascii.o nonblock.o openldap.o parsedate.o pingpong.o pop3.o progress.o psl.o doh.o rand.o rename.o rtsp.o select.o sendf.o setopt.o sha256.o share.o slist.o smb.o smtp.o socketpair.o socks.o socks_gssapi.o socks_sspi.o speedcheck.o splay.o strcase.o strdup.o strerror.o strtok.o strtoofft.o system_win32.o telnet.o tftp.o timeval.o transfer.o urlapi.o version.o warnless.o wildcard.o x509asn1.o dynbuf.o version_win32.o easyoptions.o easygetopt.o hsts.o vauth/cleartext.o vauth/cram.o vauth/digest.o vauth/digest_sspi.o vauth/krb5_gssapi.o vauth/krb5_sspi.o vauth/ntlm.o vauth/ntlm_sspi.o vauth/oauth2.o vauth/spnego_gssapi.o vauth/spnego_sspi.o vauth/vauth.o vtls/bearssl.o vtls/gskit.o vtls/gtls.o vtls/keylog.o vtls/mbedtls.o vtls/mbedtls_threadlock.o vtls/mesalink.o vtls/nss.o vtls/openssl.o vtls/schannel.o vtls/schannel_verify.o vtls/sectransp.o vtls/vtls.o vtls/wolfssl.o vquic/ngtcp2.o vquic/quiche.o vquic/vquic.o vssh/libssh.o vssh/libssh2.o vssh/wolfssh.o
ranlib libcurl.a
strip -g libcurl.a
windres --include-dir=../include -DDEBUGBUILD=0 -O coff -F pe-i386 -i libcurl.rc -o libcurl.res
gcc -s -m32 -shared -o libcurl.dll \
-Wl,--output-def,libcurl.def,--out-implib,libcurldll.a \
altsvc.o amigaos.o asyn-ares.o asyn-thread.o base64.o conncache.o connect.o content_encoding.o cookie.o curl_addrinfo.o curl_ctype.o curl_des.o curl_endian.o curl_fnmatch.o curl_get_line.o curl_gethostname.o curl_gssapi.o curl_memrchr.o curl_multibyte.o curl_ntlm_core.o curl_ntlm_wb.o curl_path.o curl_range.o curl_rtmp.o curl_sasl.o curl_sspi.o curl_threads.o dict.o dotdot.o easy.o escape.o file.o fileinfo.o formdata.o ftp.o url.o ftplistparser.o getenv.o getinfo.o gopher.o hash.o hmac.o hostasyn.o hostcheck.o hostip.o hostip4.o hostip6.o hostsyn.o http.o http2.o http_chunks.o http_digest.o http_negotiate.o http_ntlm.o http_proxy.o idn_win32.o if2ip.o imap.o inet_ntop.o inet_pton.o krb5.o ldap.o llist.o md4.o md5.o memdebug.o mime.o mprintf.o mqtt.o multi.o netrc.o non-ascii.o nonblock.o openldap.o parsedate.o pingpong.o pop3.o progress.o psl.o doh.o rand.o rename.o rtsp.o select.o sendf.o setopt.o sha256.o share.o slist.o smb.o smtp.o socketpair.o socks.o socks_gssapi.o socks_sspi.o speedcheck.o splay.o strcase.o strdup.o strerror.o strtok.o strtoofft.o system_win32.o telnet.o tftp.o timeval.o transfer.o urlapi.o version.o warnless.o wildcard.o x509asn1.o dynbuf.o version_win32.o easyoptions.o easygetopt.o hsts.o vauth/cleartext.o vauth/cram.o vauth/digest.o vauth/digest_sspi.o vauth/krb5_gssapi.o vauth/krb5_sspi.o vauth/ntlm.o vauth/ntlm_sspi.o vauth/oauth2.o vauth/spnego_gssapi.o vauth/spnego_sspi.o vauth/vauth.o vtls/bearssl.o vtls/gskit.o vtls/gtls.o vtls/keylog.o vtls/mbedtls.o vtls/mbedtls_threadlock.o vtls/mesalink.o vtls/nss.o vtls/openssl.o vtls/schannel.o vtls/schannel_verify.o vtls/sectransp.o vtls/vtls.o vtls/wolfssl.o vquic/ngtcp2.o vquic/quiche.o vquic/vquic.o vssh/libssh.o vssh/libssh2.o vssh/wolfssh.o libcurl.res -L"C:/OpenSSL/lib" -lssl -lcrypto -lgdi32 -lcrypt32 -L"../../zlib-1.2.8" -lz -lwldap32 -lws2_32
mingw32-make[1]: Leaving directory 'E:/programming/c/lib/curl-7.74.0/lib'
C:/msys64/mingw32/bin/mingw32-make.exe -C src -f Makefile.m32 CFG=mingw32-ssl-zlib
mingw32-make[1]: Entering directory 'E:/programming/c/lib/curl-7.74.0/src'
windres --include-dir=../include -O coff -DCURL_EMBED_MANIFEST -F pe-i386 -i curl.rc -o curl.res
gcc -I. -I../include -I../lib -I"C:/OpenSSL/include" -I"../../zlib-1.2.8" -g -O2 -Wall -W -fno-strict-aliasing -m32 -DCURL_STATICLIB -DUSE_OPENSSL -DHAVE_LIBZ -DHAVE_ZLIB_H -c slist_wc.c
gcc ......
rm -f curl.exe
gcc -s -m32 -static -o curl.exe curl.res slist_wc.o tool_binmode.o tool_bname.o tool_cb_dbg.o tool_cb_hdr.o tool_cb_prg.o tool_cb_rea.o tool_cb_see.o tool_cb_wrt.o tool_cfgable.o tool_convert.o tool_dirhie.o tool_doswin.o tool_easysrc.o tool_filetime.o tool_formparse.o tool_getparam.o tool_getpass.o tool_help.o tool_helpers.o tool_homedir.o tool_hugehelp.o tool_libinfo.o tool_main.o tool_metalink.o tool_msgs.o tool_operate.o tool_operhlp.o tool_panykey.o tool_paramhlp.o tool_parsecfg.o tool_progress.o tool_strdup.o tool_setopt.o tool_sleep.o tool_urlglob.o tool_util.o tool_vms.o tool_writeout.o tool_writeout_json.o tool_xattr.o strtoofft.o nonblock.o warnless.o curl_ctype.o curl_multibyte.o version_win32.o dynbuf.o -L../lib -lcurl -L"C:/OpenSSL/lib" -lssl -lcrypto -lgdi32 -lcrypt32 -L"../../zlib-1.2.8" -lz -lwldap32 -lws2_32
mingw32-make[1]: Leaving directory 'E:/programming/c/lib/curl-7.74.0/src'
and my code:
#include <iostream>
#include <windows.h>
#include <openssl/ssl.h>
#include <curl/curl.h>
using namespace std;
size_t CurlStrWCallback(char* content, size_t size, size_t nmemb, void *userdata){
auto total = size*nmemb;
((std::string*)userdata)->append((char*)content, total);
return total;
}
int main(){
auto curl = curl_easy_init();
if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK){
std::cout << "Fail to init curl\n";
return 0;
}
if(curl){
std::string buffer;
curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, CurlStrWCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buffer);
auto res = curl_easy_perform(curl);
if(res != CURLE_OK){
std::cout << "failed to perform request: " << curl_easy_strerror(res) << '\n';
}
else{
std::cout << "Response:\n" << buffer << std::endl;
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}
output: failed to perform request: Unsupported protocol
meanwhlie I also tried to run libcurl/src/curl.exe https://www.google.com -k and it sucessed
Turns out I have to compile all source in the same fashion I use in Linux: ./configure && make && make install
here are the commands I use:
zlib:
./configure
make && make install
openssl:
./configure --prefix=$PWD/dist no-idea no-mdc2 no-rc5 shared mingw (or mingw64 for 64 bits)
make && make install
libcurl:
./configure --prefix=$PWD/dist --with-zlib=PATH_TO_COMPILED_ZLIB --with-ssl=PATH_TO_COMPILED_OPENSSL --host=i686-w64-mingw32 (or x86_64-w64-mingw32 for 64 bits)
make && make install
I am trying to compile lex.yy.c and y.tab.c with C++ code, here is the Make status -
(base) rajatkmitra#spider:~/modeler> make
flex ./src/lex.l
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o main.o ./src/main.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o convertFloatToFixed.o ./src/convertFloatToFixed.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o convertProductFloatToFixed.o ./src/convertProductFloatToFixed.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o printer.o ./src/printer.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o vectorToString.o ./src/vectorToString.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o printFixedPointProduct.o ./src/printFixedPointProduct.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o fixedPointFormatter.o ./src/fixedPointFormatter.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o tokenize.o ./src/tokenize.cc
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o y.tab.o y.tab.c
bison -y -d ./src/bison.y
./src/bison.y: warning: 4 shift/reduce conflicts [-Wconflicts-sr]
g++ -I ./ -c -Wall -Wreorder -Wno-write-strings -Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm -c -o lex.yy.o lex.yy.c
###############################################################################
# Building main.o convertFloatToFixed.o convertProductFloatToFixed.o printer.o vectorToString.o
printFixedPointProduct.o fixedPointFormatter.o tokenize.o y.tab.c lex.yy.c
###############################################################################
g++ -Wno-write-strings -I ./ main.o convertFloatToFixed.o convertProductFloatToFixed.o printer.o vectorToString.o printFixedPointProduct.o fixedPointFormatter.o tokenize.o y.tab.c lex.yy.c -o lynx -lm
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: /tmp/cc8jVMLM.o: in function `yylex()':
lex.yy.c:(.text+0x343): undefined reference to `yyerror(char*)'
collect2: error: ld returned 1 exit status
make: *** [Makefile:71: lynx] Error 1
----Makefile----
####################################################################
# Library Paths
####################################################################
####################################################################
#Sources, use vpath and $CC/$LEX/$YACC should have arguments $<
#debug %make --just-print should show simulate make procedure
####################################################################
INCLUDE=-I ./
LEXSRC=lex.l
YACCSRC=bison.y
SRC=main.cc convertFloatToFixed.cc convertProductFloatToFixed.cc \
printer.cc vectorToString.cc printFixedPointProduct.cc fixedPointFormatter.cc \
tokenize.cc y.tab.c lex.yy.c
vpath %cc ./src
vpath %l ./src
vpath %y ./src
#####################################################################
#Compiler Settings
#####################################################################
OBJCC=$(SRC:.cc=.o)
OBJC=$(SRC:.c=.o)
EXE=lynx
DEFINE=#-D _XOPEN_SOURCE
CFLAGS=$(INCLUDE) $(DEFINE) $(LIBPATH) -c -Wall -Wreorder -Wno-write-strings \
-Wno-unused-variable -Wno-unused-function -Wno-sign-compare -g -lm
CXXFLAGS=$(CFLAGS)
CC=g++
LEX=flex
YACC=bison -y -d
######################################################################
#Build Rules
######################################################################
new: all
all:$(SRC) $(EXE)
# These dependency rules indicate that (1) lex.yy.o depends on
# lex.yy.c and y.tab.h and (2) lex.yy.o and y.tab.o depend on calc.h.
# Make uses the dependencies to figure out what rules must be run when
# a file has changed.
lex.yy.o: lex.yy.c y.tab.h
lex.yy.o y.tab.o:
## This rule will use yacc to generate the files y.tab.c and y.tab.h
## from our file $(YACCSRC).y
y.tab.c y.tab.h: $(YACCSRC)
$(YACC) $<
## this is the make rule to use lex to generate the file lex.yy.c from
## our file $(LEXSRC).lex
lex.yy.c: $(LEXSRC)
$(LEX) $<
## for lex.yy.c and y.tab.c
%.c.o:
$(CC) $(CFLAGS) $< -o $#
## all other C++ files
%.cc.o:
$(CC) $(CFLAGS) $< -o $#
$(EXE):$(OBJCC) $(OBJC)
#echo \###############################################################################
#echo \# Building $(OBJCC)
#echo \###############################################################################
$(CC) -Wno-write-strings $(INCLUDE) $(OBJCC) $(LIBPATH) $(LIB) -o $# -lm
clean:
rm -rf $(EXE) *~ *.o lex.yy.c y.tab.h
Okay so here is the grammar file bison.y
%{
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
int yylex();
void yyerror(const char *s);
/*|--------------------------
for global parsing
-----------------------------|*/
unsigned int attributeFlag;
%}
/*Possible types from lexer*/
%union {
int ival;
double fval;
const char *sval;
}
/*Possible tokens*/
%token KWREAL
%token <ival> INTEGER
%token <fval> FLOAT;
%token <sval> VARIABLE
/*associativity*/
%left GE LE EQ NE '>' '<'
%left '+' '-'
%left '*' '/'
%nonassoc UMINUS
/*parse rules*/
%%
description:
description decl_attributes {}
| description stmt_list {}
| description real_variable_decl {}
| decl_attributes {}
| stmt_list {}
| real_variable_decl {}
;
decl_attributes:
attribute {}
| decl_attributes attribute {}
;
attribute:
open_attribute several_attribute_assignments close_attribute
real_variable_decl
{
attributeFlag = 0;
}
;
open_attribute:
'(' '*' {attributeFlag = 1;}
;
close_attribute:
'*' ')' {}
;
several_attribute_assignments:
integer_assignment {}
| continued_attribute_assignments integer_assignment {}
;
continued_attribute_assignments:
integer_assignment ',' {}
| continued_attribute_assignments integer_assignment ',' {}
;
real_variable_decl:
KWREAL VARIABLE ';'
{
}
;
stmt_list:
stmt { }
| stmt_list stmt { }
;
stmt:
VARIABLE '=' expr ';' {printf("%s\n\n",$1); }
| integer_assignment ';' { }
;
integer_assignment:
VARIABLE '=' INTEGER
{
if(attributeFlag==1){
if(strcmp($1, "S")==0){
//attrContainer.isSigned = $3;
}else if(strcmp($1, "IB")==0){
//attrContainer.intBits = $3;
}else if(strcmp($1, "FB")==0){
//attrContainer.fracBits = $3;
}
}
}
;
expr:
VARIABLE { printf("%s\n",$1); }
| FLOAT { printf("%f\n",$1); }
| '-' expr %prec UMINUS { }
| expr '+' expr { }
| expr '-' expr { }
| expr '*' expr { }
| expr '/' expr { }
| expr '<' expr { }
| expr '>' expr { }
| expr GE expr { }
| expr LE expr { }
| expr NE expr { }
| expr EQ expr { }
| '(' expr ')' { }
;
%%
/*|-----------------------------------------------------
Parsing Functions
-----------------------------------------------------|*/
/*Definition of yyerror*/
void yyerror(const char *s)
{
extern int yylineno; // defined and maintained in lex.c
extern char *yytext; // defined and maintained in lex.c
printf("ERROR: %s on line %d\n", yytext, yylineno);
}
and the lexer -
%{
#include <stdlib.h>
#include <stdio.h>
#include "y.tab.h"
void yyerror(char *);
%}
%%
"real" return KWREAL;
[a-zA-Z][a-zA-Z]* {
//yylval.sval= *yytext - 'a';
yylval.sval = strdup(yytext);
return VARIABLE;
}
0 {
yylval.ival = atoi(yytext);
return INTEGER;
}
[1-9][0-9]* {
yylval.ival = atoi(yytext);
return INTEGER;
}
(([0-9]*\.[0-9]*)([eE][-+]?[0-9]+)?) {
yylval.fval = atof(yytext);
return FLOAT;
}
[-()<>=+*/;,{}.] {
return *yytext;
}
">=" return GE;
"<=" return LE;
"==" return EQ;
"!=" return NE;
#[^\n]* { /* Discard preprocessor comments. */ }
"//"[^\n]* { /* Discard c99 comments. */ }
[ \t\n]+ ; /* ignore whitespace */
. yyerror("Unknown character");
%%
int yywrap(void) {
return 1;
}
This is the main routine main.cc
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
/*------------------------------------------------
Front end parser
------------------------------------------------*/
extern void yyparse(void);
extern FILE *yyin;
int main(int argc, char **argv)
{
/*------------------------
parse the file
------------------------*/
/*open file handle to a file of interest*/
if(argc < 2){
printf("Usage: main <filename> \n");
exit(-1);
}
yyin = fopen(argv[1],"r");
if(yyin==NULL){
printf("Could not open file !\n");
exit(-1);
}
/*Parse the design*/
do{
yyparse();
}while(!feof(yyin));
}
So there you go! I have added the Minimal Reproducable Example. When I compile everything with g++ I end up getting a linker error that does not find the yyerror() routine in yylex()
g++ -Wno-write-strings -I ./ y.tab.o lex.yy.o main.o -o lynx -lm -lfl -
std=c++11
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld:
lex.yy.o: in function yylex()': /home/rajatkmitra/modeler/minimal/lex.l:46: undefined reference to yyerror(char*)'
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld:
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../lib64/libfl.so: undefined
reference to `yylex'
collect2: error: ld returned 1 exit status
make: *** [Makefile:68: lynx] Error 1
Changes Made to get this environment to work -
(1) Compile ALL sources including the output from lex and yacc with g++
(2) yyerror arguments are (char *s) and NOT (const char *s)
(2) do not link with -lfl as this is not not required with g++
Here's a minimal example which shows the problem:
file: yyerror.c
#include <iostream>
void yyerror(const char* msg) {
std::cout << msg;
}
file: main.c
void yyerror(char* msg);
int main(void) {
char* msg[] = "Hello, world";
yyerror(msg);
}
Try to build
$ g++ -Wall -o main main.c yyerror.c
/tmp/cc4xbjus.o: In function `main':
main.c:(.text+0x5f): undefined reference to `yyerror(char*)'
collect2: error: ld returned 1 exit status
Note that the declaration of yyerror in main.c is different from the definition of yyerror in yyerror.c. Since you're compiling these files as C++, this matters: in C++, function names can be overloaded with different argument types, and const char* is a different argument type than char*. So the two files cannot be successfully linked: the overload of yyerror declared in main.c is not defined anywhere.
Although you don't show the declaration of yyerror you placed in your lexer file, I'm assuming that it is the same as my example, based on the error message generated by the compiler. The error message indicates the complete name (including argument types) of the function which cannot be linked.
I have created a project:
// func.h :
#ifndef FUNCS_H_
#define FUNCS_H_
int addInts(int i, int j);
#endif /* FUNCS_H_ */
// func.cpp
#include "func.h"
int addInts(int i, int j) {
return i + j;
}
// main.cpp
#include "func.h"
#include <iostream>
int main() {
std::cout << addInts(5, 7) << std::endl;
return 0;
}
//makefile
OBJS := \
main.o \
func.o
CXX := g++
CXX_FLAGS := -Wall -Werror -Wextra -std=c++11
all: main_prj
main_prj: $(OBJS)
$(CXX) $(OBJS) -lm -o main
-include $(OBJS:.o=.d)
%.o: %.cpp
$(CXX) -c $(CXX_FLAGS) $*.cpp -o $*.o
clean:
rm -f main $(OBJS)
And I created also a test (boost test) for that function:
// test/main_test.cpp
#define BOOST_TEST_MODULE main_test
#include <boost/test/included/unit_test.hpp>
//____________________________________________________________________________//
// FIXTURES ...
//____________________________________________________________________________//
// test/addInts/addInts_test.cpp
#include <boost/test/unit_test.hpp>
#include "../../func.h"
BOOST_AUTO_TEST_CASE(addInts_5_7) {
int addInts_5_7 = 5 + 7;
BOOST_CHECK_EQUAL(addInts_5_7, addInts(5, 7));
}
// test/makefile
OBJS_TEST := \
main_test.o \
addInts/addInts_test.o \
../func.o
CXX_TEST := g++
CXX_FLAGS_TEST := -Wall -Werror -Wextra -std=c++11
all_test: main_test_prj
main_test_prj: $(OBJS_TEST)
$(CXX_TEST) $(OBJS_TEST) -lm -o main_test
-include $(OBJS_TEST:.o=.d)
%.o: %.cpp
$(CXX_TEST) -c $(CXX_FLAGS_TEST) $*.cpp -o $*.o
clean_test:
rm -f main_test $(OBJS_TEST)
Now, the make commands work, so they clean all the created files, or create the o files and the executables. When I run the main file, the output is correct: 12 ; but when I run the main_test file, the output is a little strange:
Running 1 test case...
*** No errors detected
I would expect the output with running tests and OK/KO, or pass/not pass... I cannot figure what am I doing wrong. Can anyone help me, please?
You have one test.
The output says that one test was run, and that no errors were found.
This output appears to be as documented.
There is no problem here.
Though, sadly, the documentation on how to change this output is rather lacking…
I'm using makefile to compile my simple application. Here it is:
CURRDIR = `basename $(PWD)`
MAINAPP = main
SECTION = section
POINT = point
FIGURE = figure
CIRCLE = circle
TRIANGLE = triangle
RECTANGLE = rectangle
MAINSRC = $(MAINAPP).cpp
SECTIONSRC = $(SECTION).cpp
CIRCLESRC = $(CIRCLE).cpp
TRIANGLESRC = $(TRIANGLE).cpp
RECTANGLESRC = $(RECTANGLE).cpp
MAINKOM = $(MAINAPP).o
SECTIONKOM = $(SECTION).o
CIRCLEKOM = $(CIRCLE).o
TRIANGLEKOM = $(TRIANGLE).o
RECTANGLEKOM = $(RECTANGLE).o
SECTIONHEADER = $(SECTION).h
POINTHEADER = $(POINT).h
CIRCLEHEADER = $(CIRCLE).h
TRIANGLEHEADER = $(TRIANGLE).h
RECTANGLEHEADER = $(RECTANGLE).h
FIGUREHEADER = $(FIGURE).h
MAINEXE = $(MAINAPP).x
COMPILER = g++
COMPILERCOPTIONS = -Wall -c
LINKER = $(COMPILER)
LINOP = -Wall
BIBSTAT = libfigures.a
BIBKOM = section.o triangle.o rectangle.o circle.o
AR = ar
AROP = rv
$(BIBSTAT): $(BIBKOM)
$(AR) $(AROP) $# $?
all: $(MAINEXE)
$(SECTIONKOM): $(SECTIONSRC)
$(COMPILER) $(COMPILERCOPTIONS) $(SECTIONSRC)
$(CIRCLEKOM): $(CIRCLESRC)
$(COMPILER) $(COMPILERCOPTIONS) $(CIRCLESRC)
$(TRIANGLEKOM): $(TRIANGLESRC)
$(COMPILER) $(COMPILERCOPTIONS) $(TRIANGLESRC)
$(RECTANGLEKOM): $(RECTANGLESRC)
$(COMPILER) $(COMPILERCOPTIONS) $(RECTANGLESRC)
$(MAINKOM): $(MAINSRC) $(SECTIONHEADER) $(POINTHEADER) $(CIRCLEHEADER) $(TRIANGLEHEADER) $(RECTANGLEHEADER) $(FIGUREHEADER)
$(COMPILER) $(COMPILERCOPTIONS) $(MAINSRC)
$(MAINEXE): $(MAINKOM) $(SECTIONKOM) $(CIRCLEKOM) $(TRIANGLEKOM) $(RECTANGLEKOM) $(BIBSTAT)
$(LINKER) -o $# $(LINOP) $^ $(MAINEXE) $(MAINKOM) $(SECTIONKOM) $(CIRCLEKOM) $(TRIANGLEKOM) $(RECTANGLEKOM)
run: $(MAINEXE)
./$(MAINEXE)
clean:
rm -f a.out *~ *.o *.x
tar: clean
(cd ..; tar cvzf $(CURRDIR).tar.gz $(CURRDIR); ls -altr)
However, it seems that I have a problem with linking static library. This is my output after executing make all:
$ make all
g++ -Wall -c main.cpp
g++ -Wall -c section.cpp
g++ -Wall -c circle.cpp
g++ -Wall -c triangle.cpp
g++ -Wall -c rectangle.cpp
ar rv libfigures.a section.o triangle.o rectangle.o circle.o
ar: creating libfigures.a
a - section.o
a - triangle.o
a - rectangle.o
a - circle.o
g++ -o main.x -Wall main.o section.o circle.o triangle.o rectangle.o libfigures.a main.x main.o section.o circle.o triangle.o rectangle.o
g++: error: main.x: No such file or directory 1
make: *** [main.x] Error 1
Any ideas what am I doing wrong with this makefile?
Your final command is
g++ -o main.x -Wall main.o section.o circle.o triangle.o rectangle.o \
libfigures.a main.x main.o section.o circle.o triangle.o \
rectangle.o
There's too much going on here: you (1) repeat each object twice (2) use both objects and a library built from them (3) use the output file in the list of input files.
It should be
g++ -o main.x main.o libfigures.a
You probably need to modify the makefile rule like this:
$(MAINEXE): $(MAINKOM) $(BIBSTAT)
$(LINKER) -o $# $^
For some reason I am getting undefined symbols for MD5 and RAND_bytes in this one particular C++ file. OpenSSL has installed itself (libssl and libcrypto) to /usr/lib and /usr/include/openssl/.
libtool: link: (cd ".libs" && rm -f "libeapgpsk.so.1" && ln -s "libeapgpsk.so.1.0.0" "libeapgpsk.so.1")
libtool: link: (cd ".libs" && rm -f "libeapgpsk.so" && ln -s "libeapgpsk.so.1.0.0" "libeapgpsk.so")
libtool: link: ar cru .libs/libeapgpsk.a eap-gpsk/eap_gpsk_fsm.o
libtool: link: ranlib .libs/libeapgpsk.a
libtool: link: ( cd ".libs" && rm -f "libeapgpsk.la" && ln -s "../libeapgpsk.la" "libeapgpsk.la" )
depbase=`echo tests/md5_test.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\
g++ -DPACKAGE_NAME=\"OpenDiameter\" -DPACKAGE_TARNAME=\"opendiameter\" -DPACKAGE_VERSION=\"1.0.7-i\" -DPACKAGE_STRING=\"OpenDiameter\ 1.0.7-i\" -DPACKAGE_BUGREPORT=\"vfajardo#tari.toshiba.com\" -DPACKAGE_URL=\"\" -DPACKAGE=\"opendiameter\" -DVERSION=\"1.0.7-i\" -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_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DHAVE_IFADDRS_H=1 -DHAVE_SHADOW_H=1 -DHAVE__BOOL=1 -DHAVE_STDBOOL_H=1 -DHAVE_GETIFADDRS=1 -I. -Wall -I/usr -I/usr -fno-strict-aliasing -I../include -I../libeap/include -DOS_LINUX -I/usr/include/openssl -I/usr/include/openssl -MT tests/md5_test.o -MD -MP -MF $depbase.Tpo -c -o tests/md5_test.o tests/md5_test.cxx &&\
mv -f $depbase.Tpo $depbase.Po
In file included from ../include/aaa_dictionary_api.h:45:0,
from ../include/aaa_parser_api.h:38,
from ../libeap/include/eap.hxx:54,
from tests/md5_test.cxx:45:
../include/framework.h:1653:7: warning: ‘typedef’ was ignored in this declaration [enabled by default]
In file included from ../include/aaa_parser_api.h:38:0,
from ../libeap/include/eap.hxx:54,
from tests/md5_test.cxx:45:
../include/aaa_dictionary_api.h:58:1: warning: ‘typedef’ was ignored in this declaration [enabled by default]
tests/md5_test.cxx: In constructor ‘EapTask::EapTask()’:
tests/md5_test.cxx:71:45: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
tests/md5_test.cxx: In constructor ‘PeerApplication::PeerApplication(EapTask&, ACE_Semaphore&)’:
tests/md5_test.cxx:418:72: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
tests/md5_test.cxx: In constructor ‘StandAloneAuthApplication::StandAloneAuthApplication(EapTask&, ACE_Semaphore&)’:
tests/md5_test.cxx:460:80: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
tests/md5_test.cxx: In constructor ‘BackendAuthApplication::BackendAuthApplication(EapTask&, ACE_Semaphore&, bool)’:
tests/md5_test.cxx:514:58: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
tests/md5_test.cxx: In constructor ‘PassThroughAuthApplication::PassThroughAuthApplication(EapTask&, ACE_Semaphore&, bool)’:
tests/md5_test.cxx:576:62: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
/bin/bash ../libtool --tag=CXX --mode=link g++ -I/usr/include/openssl -L/usr/lib -o md5_test tests/md5_test.o -ldl -lssl -lcrypto -lACE_SSL -lACE -lACEXML_Parser -lACEXML -lpthread -lboost_system -lboost_thread -lboost_system -lboost_thread -lACEXML -lACEXML_Parser -ldl -lssl -lcrypto ../libeap/libeap.la ../libeap/libeaparchie.la ../libeap/libeapgpsk.la -lboost_system -lboost_thread -lACEXML -lACEXML_Parser -ldl -lssl -lcrypto
libtool: link: g++ -I/usr/include/openssl -o .libs/md5_test tests/md5_test.o -L/usr/lib /usr/lib/libACE_SSL.so /usr/lib/libACE.so -lpthread ../libeap/.libs/libeap.so ../libeap/.libs/libeaparchie.so ../libeap/.libs/libeapgpsk.so -lboost_system -lboost_thread /usr/lib/libACEXML.so /usr/lib/libACEXML_Parser.so -ldl -lssl -lcrypto
../libeap/.libs/libeap.so: undefined reference to `MD5#OPENSSL_1.0.0'
../libeap/.libs/libeap.so: undefined reference to `RAND_bytes#OPENSSL_1.0.0'
collect2: ld returned 1 exit status
Here is the Makefile.am responsible for this:
## Process this file with automake to produce Makefile.in
srcdir = #srcdir#
VPATH = #srcdir#
AM_CPPFLAGS = #L_CPPFLAGS# \
-I#top_srcdir#/include \
-I#top_srcdir#/libeap/include \
-D#HOST_OS#
AM_LDFLAGS = #L_LDFLAGS#
if compile_EAPTLS
CORE_SRC = eapcore/eap_fsm.cxx \
eapcore/eap_peerfsm.cxx \
eapcore/eap_authfsm.cxx \
eapcore/eap_standalone_authfsm.cxx \
eapcore/eap_backend_authfsm.cxx \
eapcore/eap_passthrough_authfsm.cxx \
eapcore/eap_identity.cxx \
eapcore/eap_method_registrar.cxx \
eapcore/eap_policy.cxx \
eapcore/eap_notification.cxx \
eapcore/eap_md5.cxx
CORE_HDR = include/eap_api.h \
include/eap.hxx \
include/eap_authfsm.hxx \
include/eap_fsm.hxx \
include/eap_identity.hxx \
include/eap_log.hxx \
include/eap_md5.hxx \
include/eap_method_registrar.hxx \
include/eap_notification.hxx \
include/eap_parser.hxx \
include/eap_peerfsm.hxx \
include/eap_policy.hxx \
include/eap_archie_crypto.hxx \
include/eap_archie_fsm.hxx \
include/eap_archie_parser.hxx \
include/eap_archie.hxx \
include/eap_gpsk_crypto.hxx \
include/eap_gpsk_fsm.hxx \
include/eap_gpsk_parser.hxx \
include/eap_gpsk.hxx \
include/eap_tls.hxx \
include/eap_tls_mng.hxx \
include/eap_tls_session.hxx \
include/eap_tls_parser.hxx \
include/eap_tls_fsm.hxx \
include/eap_tls_xml_data.hxx \
include/eap_tls_xml_parser.hxx \
include/eap_tls_data_defs.hxx
else
CORE_SRC = eapcore/eap_fsm.cxx \
eapcore/eap_peerfsm.cxx \
eapcore/eap_authfsm.cxx \
eapcore/eap_standalone_authfsm.cxx \
eapcore/eap_backend_authfsm.cxx \
eapcore/eap_passthrough_authfsm.cxx \
eapcore/eap_identity.cxx \
eapcore/eap_method_registrar.cxx \
eapcore/eap_policy.cxx \
eapcore/eap_notification.cxx \
eapcore/eap_md5.cxx
CORE_HDR = include/eap_api.h \
include/eap.hxx \
include/eap_authfsm.hxx \
include/eap_fsm.hxx \
include/eap_identity.hxx \
include/eap_log.hxx \
include/eap_md5.hxx \
include/eap_method_registrar.hxx \
include/eap_notification.hxx \
include/eap_parser.hxx \
include/eap_peerfsm.hxx \
include/eap_policy.hxx \
include/eap_archie_crypto.hxx \
include/eap_archie_fsm.hxx \
include/eap_archie_parser.hxx \
include/eap_archie.hxx \
include/eap_gpsk_crypto.hxx \
include/eap_gpsk_fsm.hxx \
include/eap_gpsk_parser.hxx \
include/eap_gpsk.hxx
endif
ARCHIE_SRC = eap-archie/eap_archie_fsm.cxx
GPSK_SRC = eap-gpsk/eap_gpsk_fsm.cxx
if compile_EAPTLS
TLS_SRC = eap-tls/eap_tls_mng.cxx \
eap-tls/eap_tls_crypto.cxx \
eap-tls/eap_tls_fsm.cxx \
eap-tls/eap_tls_xml_data.cxx \
eap-tls/eap_tls_xml_parser.cxx
endif
includedir = $(prefix)/include/opendiameter/eap
include_HEADERS = $(CORE_HDR)
sysconfdir = $(prefix)/etc/opendiameter/eap
sysconf_DATA = config/client.eap-tls.xml \
config/server.eap-tls.xml
if compile_EAPTLS
lib_LTLIBRARIES = libeap.la libeaparchie.la libeapgpsk.la libeaptls.la
else
lib_LTLIBRARIES = libeap.la libeaparchie.la libeapgpsk.la
endif
libeap_la_SOURCES = $(CORE_SRC) $(CORE_HDR)
libeaparchie_la_SOURCES = $(ARCHIE_SRC)
libeapgpsk_la_SOURCES = $(GPSK_SRC)
if compile_EAPTLS
libeaptls_la_SOURCES = $(TLS_SRC)
endif
libeap_la_LIBADD = -ldl -lssl -lcrypto
libeap_la_LDFLAGS = -version-info 1:0:0 -lssl -lcrypto
libeap_la_AR = $(AR) -qcs
libeaparchie_la_LDFLAGS = -version-info 1:0:0
libeaparchie_la_AR = $(AR) -qcs
libeapgpsk_la_LDFLAGS = -version-info 1:0:0
libeapgpsk_la_AR = $(AR) -qcs
if compile_EAPTLS
libeaptls_la_LDFLAGS = -version-info 1:0:0
libeaptls_la_AR = $(AR) -qcs
LDADD = #L_LIBS# \
$(top_builddir)/libeap/libeap.la \
$(top_builddir)/libeap/libeaparchie.la \
$(top_builddir)/libeap/libeapgpsk.la \
$(top_builddir)/libeap/libeaptls.la \
$(top_builddir)/libdiamparser/libdiamparser.la
else
LDADD = #L_LIBS# \
$(top_builddir)/libeap/libeap.la \
$(top_builddir)/libeap/libeaparchie.la \
$(top_builddir)/libeap/libeapgpsk.la
endif
if compile_EAPTLS
noinst_PROGRAMS = md5_test archie_test gpsk_test tls_test
else
noinst_PROGRAMS = md5_test archie_test gpsk_test
endif
md5_test_SOURCES = tests/md5_test.cxx -lssl -lcrypto
archie_test_SOURCES = tests/archie_test.cxx
gpsk_test_SOURCES = tests/gpsk_test.cxx
if compile_EAPTLS
tls_test_SOURCES = tests/tls_test.cxx
endif
EXTRA_DIST = config
I suspect autotools isn't doing something because I haven't specified it to do so. Inside of the file md5_test.c, but it still errors.
#include <openssl/md5.h>
#include <openssl/rand.h>
Any help would be greatly appreciated.
Edit:
I dug into the libraries to see if there was versioning information and it led me to this very interesting predicament - openssl 1.0.0m when compiled with this command: ./config --prefix=/usr --openssldir=/etc/ssl --libdir=lib shared
Generates two sets of shared objects located in:
/usr/lib/x86_64-linux-gnu/
/usr/lib
The shared objects in /usr/lib/x86_64-linux-gnu/ Produce a version (used objdump -T)
00000000001546b0 g DF .text 0000000000000108 OPENSSL_1.0.0 PKCS7_to_TS_TST_INFO
The shared objects in /usr/lib produce this:
000000000012ee20 g DF .text 000000000000000c Base BIO_new_CMS
How would one fix this because this seems highly unstandard....?
Remove -lssl -lcrypto from the LDFLAGS for your libraries; the way the link editor works, LDFLAGS are passed before the object files, and that means they are discarded; in at least some version of the link editor, the libraries passed before object files are also "blacklisted", or to be precise, they get ignored when passed again.
You're passing -lssl -lcrypto twice in both LDFLAGS and LIBADD so you may be triggering that behaviour.