I defined some constants in flag.h so link.c and linkedlist.h can use it.
But when I compile with:
clang -Wall main.c link.c linkedlist.c
I get the following
/tmp/linkedlist-o2mcAI.o:(.rodata+0x0): multiple definition of `VARIABLE_NAME'
/tmp/link-oXhyfE.o:(.rodata+0x0): first defined here
for all variables from flag.h used in link.c and linkedlist.c, and at the end:
clang: error: linker command failed with exit code 1 (use -v to see invocation)
A example code of main.c, flag.h, link.h, link.c, linkedlist.h and linkedlist.c:
main.c
#include <stdio.h>
#include "linkedlist.h"
int main(void) {
LinkedList* list = LinkedList_new();
}
flag.h
#ifndef FLAG_H_
#define FLAG_H_
#include <limits.h>
#define FALSE 0
#define TRUE 1
const int OK = 1;
const int ERROR = -1;
const int FLAG = 0;
// other constants
#endif
link.h
#ifndef LINK_H_
#define LINK_H_
typedef struct Link {
int value;
struct Link* next;
} Link;
Link* Link_new(int value);
int useExample(int value);
// other methods
#endif
link.c
#include <stdio.h>
#include <stdlib.h>
#include "link.h"
#include "flag.h"
Link* Link_new(int value)
{
Link* link = malloc(sizeof(Link));
link->value = value;
link->next = NULL;
return link;
}
useExample(int value)
{
if (value == 0) {
return OK; // defined in flag.h
} else {
return FLAG; // defined in flag.h
}
}
// other methods
linkedlist.h
#ifndef LINKEDLIST_H_
#define LINKEDLIST_H_
#include "link.h"
typedef struct LinkedList {
Link* first;
unsigned int size;
} LinkedList;
LinkedList* LinkedList_new();
int anotherUseExample(int value);
// other methods
#endif
linkedlist.c
#include <stdio.h>
#include <stdlib.h>
#include "linkedlist.h"
#include "flag.h"
LinkedList* LinkedList_new() {
LinkedList* list = malloc(sizeof(LinkedList));
list->first = NULL;
list->size = 0;
return list;
}
anotherUseExample(int value)
{
if (value == 0) {
return FLAG; // defined in flag.h
} else {
return ERROR; // defined in flag.h
}
}
// other methods
So how can I use flag.h in link.c and linkedlist.c without occur multiple definition?
And...
The way I'm coding header files and compiling is correct?
The complete output with -v:
clang version 3.3 (tags/RELEASE_33/rc3)
Target: i386-redhat-linux-gnu
Thread model: posix
"/usr/bin/clang" -cc1 -triple i386-redhat-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name main.c -mrelocation-model static -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -fuse-init-array -target-cpu pentium4 -target-linker-version 2.23.52.0.1 -v -resource-dir /usr/bin/../lib/clang/3.3 -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.3/include -internal-externc-isystem /usr/include -internal-externc-isystem /usr/lib/gcc/i686-redhat-linux/4.8.1/include -Wall -fdebug-compilation-dir /home/jharvard/Desktop/Code/LinkedList -ferror-limit 19 -fmessage-length 80 -mstackrealign -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -o /tmp/main-JmZTmN.o -x c main.c
clang -cc1 version 3.3 based upon LLVM 3.3 default target i386-redhat-linux-gnu
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/bin/../lib/clang/3.3/include
/usr/include
/usr/lib/gcc/i686-redhat-linux/4.8.1/include
End of search list.
"/usr/bin/clang" -cc1 -triple i386-redhat-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name link.c -mrelocation-model static -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -fuse-init-array -target-cpu pentium4 -target-linker-version 2.23.52.0.1 -v -resource-dir /usr/bin/../lib/clang/3.3 -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.3/include -internal-externc-isystem /usr/include -internal-externc-isystem /usr/lib/gcc/i686-redhat-linux/4.8.1/include -Wall -fdebug-compilation-dir /home/jharvard/Desktop/Code/LinkedList -ferror-limit 19 -fmessage-length 80 -mstackrealign -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -o /tmp/link-FtygcZ.o -x c link.c
clang -cc1 version 3.3 based upon LLVM 3.3 default target i386-redhat-linux-gnu
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/bin/../lib/clang/3.3/include
/usr/include
/usr/lib/gcc/i686-redhat-linux/4.8.1/include
End of search list.
"/usr/bin/clang" -cc1 -triple i386-redhat-linux-gnu -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name linkedlist.c -mrelocation-model static -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -fuse-init-array -target-cpu pentium4 -target-linker-version 2.23.52.0.1 -v -resource-dir /usr/bin/../lib/clang/3.3 -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/clang/3.3/include -internal-externc-isystem /usr/include -internal-externc-isystem /usr/lib/gcc/i686-redhat-linux/4.8.1/include -Wall -fdebug-compilation-dir /home/jharvard/Desktop/Code/LinkedList -ferror-limit 19 -fmessage-length 80 -mstackrealign -fobjc-runtime=gcc -fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics -backend-option -vectorize-loops -o /tmp/linkedlist-n0zF1a.o -x c linkedlist.c
clang -cc1 version 3.3 based upon LLVM 3.3 default target i386-redhat-linux-gnu
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/bin/../lib/clang/3.3/include
/usr/include
/usr/lib/gcc/i686-redhat-linux/4.8.1/include
End of search list.
"/usr/bin/ld" --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o a.out /usr/lib/gcc/i686-redhat-linux/4.8.1/../../../crt1.o /usr/lib/gcc/i686-redhat-linux/4.8.1/../../../crti.o /usr/lib/gcc/i686-redhat-linux/4.8.1/crtbegin.o -L/usr/lib/gcc/i686-redhat-linux/4.8.1 -L/usr/lib/gcc/i686-redhat-linux/4.8.1/../../.. -L/lib -L/usr/lib /tmp/main-JmZTmN.o /tmp/link-FtygcZ.o /tmp/linkedlist-n0zF1a.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/i686-redhat-linux/4.8.1/crtend.o /usr/lib/gcc/i686-redhat-linux/4.8.1/../../../crtn.o
/tmp/linkedlist-n0zF1a.o:(.rodata+0x4): multiple definition of `ERROR_indexOutOfBounds'
/tmp/link-FtygcZ.o:(.rodata+0x4): first defined here
/tmp/linkedlist-n0zF1a.o:(.rodata+0x8): multiple definition of `ERROR_invalidArgument'
/tmp/link-FtygcZ.o:(.rodata+0x8): first defined here
/tmp/linkedlist-n0zF1a.o:(.rodata+0x10): multiple definition of `FLAG_notFound'
/tmp/link-FtygcZ.o:(.rodata+0x10): first defined here
/tmp/linkedlist-n0zF1a.o:(.rodata+0xc): multiple definition of `FLAG_undefined'
/tmp/link-FtygcZ.o:(.rodata+0xc): first defined here
/tmp/linkedlist-n0zF1a.o:(.rodata+0x0): multiple definition of `OK'
/tmp/link-FtygcZ.o:(.rodata+0x0): first defined here
clang: error: linker command failed with exit code 1 (use -v to see invocation)
The #include directive in C simply copies the text from the header file. That means that when you compile both link.c and linkedlist.c, the constant definitions from flag.h gets copied into both, and all these constants are now defined in both link.o and linkedlist.o`. When you link the program you get a name you get a multiple definition error.
You need to split the declaration from the definition, and create a flag.c file where you define const int OK = 1; etc., and at flag.h you'll stay with const int OK; etc. That way, the constants will be compiled into a single object file - flag.o - and you won't get a multiple definition error when you link.
Since you don't need these constants as objects, you should just use a different feature to define them, enumerations.
enum { OK = 1, ERROR = -1, FLAG = 0, ONE = 1, };
These are of type int and will never give rise to multiple symbol errors. Their advantage is that they can remain inside the .h file. Thereby there value is visible to all functions that use them and can better be optimized.
As can be seen in the example above, values don't have to appear in order and the same value may appear several times.
flag.h:
extern const int OK, ERROR, FLAG;
flag.c:
const int OK = 1;
const int ERROR = -1;
const int FLAG = 0;
#Idan Arye and #Jens Gustedt gave two solutions. Both have advantages and disadvantages.
One main advantage with enum is that we need not assign any values to elements and compiler will automatically assign values. There is less chance for duplicate entries and we can add or remove new elements safely.
Disadvantage with enum is that it is int by default. If we need uint8_t in memory constrained systems like embedded programming, we may face problems. But some compilers support -fshort-enums compiler option which allows the compiler to set the size of an enumeration type to the smallest data type that can hold all enumerator values. But we have to set these options specifically.
Also Forward declaration of enumerated type of variable is not possible in C
With const usage in header file and in source file, again we need to copy all consts to both the files.
Also values may get duplicated (Dangerous in case values have to be unique).
Another main disadvantage with const is that they cannot be used for initializing static or global variables. They are not treated as compile time constants instead they are treated as read-only variables.
Related
I am trying to cross compile for linux on macOS. It appears that clang is not respecting the sysroot I set.
Program
#include <stdio.h>
int main() {
printf("Hello World!\n");
return 0;
}
Commands
CC=/Users/user/Development/com/prog/site_scons/builders/darwin/clang+llvm-9.0.0-x86_64-darwin-apple/bin/clang
${CC} -v -c main.c -target x86_64-pc-linux-elf -o main.o\
-isysroot /Users/zrgorak/Development/com/prog/site_scons/builders/linux/sysroot
${CC} -v -o main -target x86_64-pc-linux-elf main.o \
-isysroot /Users/zrgorak/Development/com/prog/site_scons/builders/linux/sysroot
Output
% make
/Users/user/Development/com/prog/site_scons/builders/darwin/clang+llvm-9.0.0-x86_64-darwin-apple/bin/clang -v -c -target x86_64-pc-linux-elf main.c -o main.o \
-isysroot /Users/user/Development/com/prog/site_scons/builders/linux/sysroot
clang version 9.0.0 (git://github.com/llvm/llvm-project.git 0399d5a9682b3cef71c653373e38890c63c4c365)
Target: x86_64-pc-linux-elf
Thread model: posix
InstalledDir: /Users/user/Development/com/prog/site_scons/builders/darwin/clang+llvm-9.0.0-x86_64-darwin-apple/bin
"/Users/user/Development/com/prog/site_scons/builders/darwin/clang+llvm-9.0.0-x86_64-darwin-apple/bin/clang-9" -cc1 -triple x86_64-pc-linux-elf -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name main.c -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -target-linker-version 512.4 -v -coverage-notes-file /Users/user/Development/testlinker/main.gcno -resource-dir /Users/user/Development/com/prog/site_scons/builders/darwin/clang+llvm-9.0.0-x86_64-darwin-apple/lib/clang/9.0.0 -isysroot /Users/user/Development/com/prog/site_scons/builders/linux/sysroot -internal-isystem /usr/local/include -internal-isystem /Users/user/Development/com/prog/site_scons/builders/darwin/clang+llvm-9.0.0-x86_64-darwin-apple/lib/clang/9.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /Users/user/Development/testlinker -ferror-limit 19 -fmessage-length 128 -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -faddrsig -o main.o -x c main.c
clang -cc1 version 9.0.0 based upon LLVM 9.0.0 default target x86_64-apple-darwin19.0.0
ignoring nonexistent directory "/include"
ignoring nonexistent directory "/usr/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/Users/user/Development/com/prog/site_scons/builders/darwin/clang+llvm-9.0.0-x86_64-darwin-apple/lib/clang/9.0.0/include
End of search list.
main.c:1:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
^~~~~~~~~
1 error generated.
make: *** [target] Error 1
My sysroot is /usr and /lib copied from Ubuntu 19.x
% ll /Users/user/Development/com/prog/site_scons/builders/linux/sysroot/usr/include/stdio.h
-rw-r--r--# 1 user staff 29949 Sep 16 10:56 /Users/user/Development/com/prog/site_scons/builders/linux/sysroot/usr/include/stdio.h
This even happens when I use crosstool-ng and use their sysroot.
It's like clang doesn't look in the sysroot I set?
I've been starting a small project in C with the purpose to create a library of my own to use single linked lists without hassle.
I use three files for the project: the main file (main.c), a header (with a header guard, sll.h) and it's declaration + definition file "sll.c"
However, I ran into three errors when trying to compile the C program in this state:
FILE 1 main.c
#include <stdio.h>
#include <stdlib.h>
#include "sll.h"
int main(){
return 0;
}
FILE 2 sll.h
#ifndef SLL_H_11_14_2019
#define SLL_H_11_14_2019
typedef struct Node {
int data;
struct Node * next;
} Node;
typedef struct List {
int size;
Node * head;
} List;
List createSLList();
void appendSLList(List list);
int searchSLList(List list, int key);
void popSLList(List list);
void removekeySLList(List list, int key);
void removeSLList(List list, int index);
void deleteList(List list);
#endif
FILE 3 sll.c
#include <stdio.h>
#include <stdlib.h>
#include "sll.h"
/* Contains source code for sll.h. Should not be used standalone without sll.h to avoid duplication issues. */
/* This library provides definition for functions to create and manipulate a single linked list. */
List createSLList(){
List list;
list.size = 0;
list.head = NULL;
return list;
}
void appendSLList(List list);
int searchSLList(List list, int key);
void popSLList(List list);
void removekeySLList(List list, int key);
void removeSLList(List list, int index);
void deleteList(List list);
The errors:
sll.o In function `createSLList':
7 sll.c multiple definition of `createSLList'
main.o sll.c:17: first defined here
collect2.exe [Error] ld returned 1 exit status
25 Makefile.win recipe for target 'sll.exe' failed
I'm honestly baffled; createSLList is only defined once. I looked and (obviously) stdio.h and stdlib.h should not be throwing any errors, considering they've got header guards of their own, so what's the catch?
Edit: Compiled with GCC 4.9.2 64-bit Debug
with Language Standard C99 & all warnings enabled + making them fatal errors.
Edit2: In hindsight, I did #include "sll.h". Edited and posted the new code, yet the error remains. Posted makefile.win too.
//makefile.win
# Project: single linked list
# Makefile created by Dev-C++ 5.11
CPP = g++.exe -D__DEBUG__
CC = gcc.exe -D__DEBUG__
WINDRES = windres.exe
OBJ = main.o sll.o
LINKOBJ = main.o sll.o
LIBS = -L"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib" -L"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/lib" -static-libgcc -g3
INCS = -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include"
CXXINCS = -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/x86_64-w64-mingw32/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include" -I"C:/Program Files (x86)/Dev-Cpp/MinGW64/lib/gcc/x86_64-w64-mingw32/4.9.2/include/c++"
BIN = sll.exe
CXXFLAGS = $(CXXINCS) -std=c99 -Wall -Werror -g3
CFLAGS = $(INCS) -std=c99 -Wall -Werror -g3
RM = rm.exe -f
.PHONY: all all-before all-after clean clean-custom
all: all-before $(BIN) all-after
clean: clean-custom
${RM} $(OBJ) $(BIN)
$(BIN): $(OBJ)
$(CC) $(LINKOBJ) -o $(BIN) $(LIBS) //ERROR IS HERE
main.o: main.c
$(CC) -c main.c -o main.o $(CFLAGS)
sll.o: sll.c
$(CC) -c sll.c -o sll.o $(CFLAGS)
The problem was Dev-C++ initially compiled my program as a C++ program, even though I had "picked" C as the default language. As a result, this had destructive consequences.
For anyone facing similar problems, what worked for me was deleting all the files created by the compiler and restarting the IDE. Please note that you should manually set what compiler to use under "project settings".
I am confused about how to inline functions in c (C99 onwards). In section 18.6 of "C programming, a modern approach" (K.N. King, 2nd edition), or for example 3 in this tutorial (under "Strategies for using inline functions"), the definition of an inline function is given in the header (.h) file, then the function is again listed as extern in a source (.c) file.
For example, what I am doing: in a header "stencil.h"
#ifindef _STENCIL_H
#define _STENCIL_H
inline double D1_center_2ndOrder(double vp1, double vm1, double dr)
{
return (vp1-vm1) / (2.0 * dr) ;
}
#endif
Then in a matching source file "stencil.c" one defines
#include "stencil.h"
extern double D1_center_2ndOrder(double vp1, double vm1, double dr) ;
I did this, and then in a file "main.c" I called average:
#include <stdio.h>
#include <stdlib.h>
#include "stencil.h"
int main(int argc, char *argv[])
{
double vp1 = 1 ;
double vp2 = 2 ;
dr = 0.1 ;
double der_v = D1_center_2ndOrder(vp1, vm1, dr) ;
printf("der_v\t%f\n", der_v) ;
return 0 ;
}
I compile everything with the following makefile
CC = gcc
CFLAGS = -Wall -lm -std=gnu11
OBJECTS = main.o stencil.o
DEPS_MAIN = stencil.h
test: $(OBJECTS)
$(CC) -o collapse $(OBJECTS) $(CFLAGS)
main.o: main.c $(DEPS_MAIN)
$(CC) -c main.c
stencil.o: stencil.c stencil.h
$(CC) -c stencil.c
And I then get the following compiler error:
gcc -c main.c
gcc -c stencil.c
gcc -o test main.o stencil.o -Wall -lm -std=gnu11
stencil.o: In function `D1_center_2ndOrder':
stencil.c:(.text+0x0): multiple definition of `D1_center_2ndOrder'
main.o:main.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [collapse] Error 1
When I define the function in the .c source file "stencil.c" and declare it in the header file I do not get the above error. The version of gcc I am using is
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28).
My questions are:
(1) Why then does "C programming, a modern approach" and the tutorials on inlining functions that I find online suggest defining the function in the header file and listing it again as extern in a source file? Doing so for the above gives me a compiler error.
(2) When I declare the inline function in a header file then define as extern in a source file, will the compiler still inline my function?
You are using a portable strategy based on standard C99 (and more recent), which is entirely correct.
It is failing because you invoke gcc with its default -std setting, which for GCC 4.8.5 effectively tells it to use its legacy semantics and not standard C11 semantics. The default value for -std was gnu90 in version 4.8.5. In version 5, it was changed to gnu11, which implements C99/C11 inline semantics.
You're using default settings because your Makefile does not include $(CFLAGS) in the compile recipes; only in the final link recipe. (You can see that in the commands printed out by make).
While -std=gnu11 should work, it would be better to use -std=c11 instead. And consider upgrading to a more recent GCC version.
You need to pass the standard-version flag while compiling. It's not doing any good when you pass it in the linking stage.
So your makefile should be something like:
CC = gcc
CFLAGS = -Wall -std=gnu11
LDFLAGS = -lm
OBJECTS = main.o stencil.o
DEPS_MAIN = stencil.h
test: $(OBJECTS)
$(CC) -o collapse $(OBJECTS) $(LDFLAGS)
main.o: main.c $(DEPS_MAIN)
$(CC) -c main.c $(CFLAGS)
stencil.o: stencil.c stencil.h
$(CC) -c stencil.c $(CFLAGS)
I've tested your example with this shellscript:
#!/bin/sh -eu
cat > stencil.h <<EOF
#ifndef _STENCIL_H
#define _STENCIL_H
inline double D1_center_2ndOrder(double vp1, double vm1, double dr)
{
return (vp1-vm1) / (2.0 * dr) ;
}
#endif
EOF
cat > stencil.c <<EOF
#include "stencil.h"
extern double D1_center_2ndOrder(double vp1, double vm1, double dr) ;
EOF
cat > main.c <<EOF
#include <stdio.h>
#include <stdlib.h>
#include "stencil.h"
int main(int argc, char *argv[])
{
double vp1 = 1 ;
double vp2 = 2 ;
double dr = 0.1 ;
double vm1 = 0;
double der_v = D1_center_2ndOrder(vp1, vm1, dr) ;
printf("der_v\t%f\n", der_v) ;
return 0 ;
}
EOF
: ${CC:=gcc}
set -x
gcc -c main.c -std=c99
gcc -c stencil.c -std=c99
gcc -o test main.o stencil.o -lm
and gcc 4.6.4 and it's working fine, as long as the compilations (rather than the linking command) get at least -std=c99 (It's not working with 4.6.4's defaults).
(Side note: the header guard shouldn't start with an underscore and an uppper-case letter.)
I have some code utilizing TEMP_FAILURE_RETRY and I cannot build it. I have defined _GNU_SOURCE and included unistd.h in that order.
Running gcc -Wall -v archunix5a_2.c -o archunix5a_2 gives the following output:
Apple LLVM version 8.0.0 (clang-800.0.42.1)
Target: x86_64-apple-darwin16.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
"/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.12.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name archunix5a_2.c -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu penryn -target-linker-version 274.2 -v -dwarf-column-info -debugger-tuning=lldb -resource-dir /Library/Developer/CommandLineTools/usr/bin/../lib/clang/8.0.0 -Wall -fdebug-compilation-dir /Users/mateuszsadowski/Documents/programowanie/nauka/C/SOP/4 -ferror-limit 19 -fmessage-length 59 -stack-protector 1 -fblocks -fobjc-runtime=macosx-10.12.0 -fencode-extended-block-signature -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/fp/qqgmt88x247bd712wbbw8wh80000gn/T/archunix5a_2-7cb96f.o -x c archunix5a_2.c
clang -cc1 version 8.0.0 (clang-800.0.42.1) default target x86_64-apple-darwin16.3.0
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/Library/Developer/CommandLineTools/usr/bin/../lib/clang/8.0.0/include
/Library/Developer/CommandLineTools/usr/include
/usr/include
/System/Library/Frameworks (framework directory)
/Library/Frameworks (framework directory)
End of search list.
archunix5a_2.c:113:13: warning: implicit declaration of
function 'TEMP_FAILURE_RETRY' is invalid in C99
[-Wimplicit-function-declaration]
if (TEMP_FAILURE_RETRY(fsync(fd)) == -1)
^
1 warning generated.
"/Library/Developer/CommandLineTools/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.12.0 -o archunix5a_2 /var/folders/fp/qqgmt88x247bd712wbbw8wh80000gn/T/archunix5a_2-7cb96f.o -lSystem /Library/Developer/CommandLineTools/usr/bin/../lib/clang/8.0.0/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"_TEMP_FAILURE_RETRY", referenced from:
_cleanup in archunix5a_2-7cb96f.o
_main in archunix5a_2-7cb96f.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: *** [archunix5a_2] Error 1
I'd appreciate any help.
As i said earlier mac osx doesn't support most of the glib libraries. if you want to use TEMP_FAILURE_RETRY you can try the following
don't forget to include unistd. read more from here
here with this macro
#include <unistd.h> // for TEMP_FAILURE_RETRY
#ifndef TEMP_FAILURE_RETRY
#define TEMP_FAILURE_RETRY(exp) \
({ \
decltype(exp) _rc; \
do { \
_rc = (exp); \
} while (_rc == -1 && errno == EINTR); \
_rc; \
})
#endif
i hope this helps
I've been having some trouble with the installed version of libsasl2 (Cyrus SASL).
In particular, it seems that the local headers and sasl_version report version 2.1.26, but no symbol is provided for the global function sasl_client_done.
I'm pretty sure I'm supposed to have that symbol because:
It's there in the provided sasl/sasl.h header
The cyrsus sasl NEWS file lists "Implemented sasl_client_done()/sasl_server_done()" as a 2.1.24 feature
It's there everywhere that provides 2.1.26 outside of Yosemite
For a reproduction:
note that the sample below prints
"impl: 'Cyrus SASL', version: 33619994, major: 2, minor: 1, step: 26"
the sample compiles and executes on a linux install with the same library version after uncommenting the code
the uncommented code produces a link error on yosemite
Undefined symbols for architecture x86_64:
"_sasl_client_done", referenced from:
_main in foo-072675.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
invoking the compiler with:
clang -Wall -Werror -lsasl2 -o foo foo.c -v
with clang -v of:
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.10.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name foo.c -mrelocation-model pic -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 241.9 -v -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -Wall -Werror -fdebug-compilation-dir /Users/jcarey/work -ferror-limit 19 -fmessage-length 0 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.10.0 -fencode-extended-block-signature -fdiagnostics-show-option -vectorize-slp -o /var/folders/wq/jypwqgv976n0db5l5qxw900r0000gq/T/foo-92054e.o -x c foo.c
clang -cc1 version 6.0 based upon LLVM 3.5svn default target x86_64-apple-darwin14.0.0
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/local/include"
ignoring nonexistent directory "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/Library/Frameworks"
#include "..." search starts here:
#include <...> search starts here:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/include
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/usr/include
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk/System/Library/Frameworks (framework directory)
End of search list.
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -dynamic -arch x86_64 -macosx_version_min 10.10.0 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk -o foo -lsasl2 /var/folders/wq/jypwqgv976n0db5l5qxw900r0000gq/T/foo-92054e.o -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.0/lib/darwin/libclang_rt.osx.a
Undefined symbols for architecture x86_64:
"_sasl_client_done", referenced from:
_main in foo-92054e.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
And the code in question:
#include <sasl/sasl.h>
#include <stdio.h>
#include <stdint.h>
int main(int argc, char ** argv) {
const char *impl;
int version;
uint32_t buf;
uint16_t major;
uint8_t minor;
uint8_t step;
sasl_version(&impl, &version);
buf = version;
major = buf >> 24;
minor = (buf << 8) >> 24;
step = (buf << 24) >> 24;
printf("impl: '%s', version: %d, major: %d, minor: %d, step: %d\n", impl, version, major, minor, step);
/*
{
int (* scd)(void);
scd = &sasl_client_done;
printf("sasl_client_done: %p\n", scd);
}
*/
return 0;
}
I'm thinking that something's screwy with the way cyrus sasl got packaged for Yosemite (using a symbol list from Mavericks perhaps?).
As a matter of interest, I just checked with 10.10.4 and I see the symbol is now there:
$ nm /usr/lib/libsasl2.dylib |grep sasl_client_done
000000000000724a T _sasl_client_done
The sample code now works fine (with the commented section now uncommented). The same Cyrus SASL version is still returned though:
impl: 'Cyrus SASL', version: 33619994, major: 2, minor: 1, step: 26
sasl_client_done: 0x7fff8e3dc24a