Creating Shared Libraries [Mac][c++]

Discussion in 'Mac Programming' started by birchy, Aug 6, 2010.

  1. birchy macrumors newbie

    birchy

    Joined:
    Aug 6, 2010
    Location:
    Canada
    #1
    Hi there,

    I'm trying to create and use a simple shared library on Mac OS X.
    I realize that the procedure is different for Linux/Mac OS X, and I have used Google to get to the point where I can create the dylib, but when I try and link it in from another application I get the error message "ld: library not found for -lbLib". I'm probably doing something really small wrong:

    Here is my lib Makefile:
    Code:
    # Common Variables...
    ECHO = @/bin/echo
    SRCDIR = src
    OBJDIR = obj
    INCDIR = include
    
    # Specify compiler and compile options
    CC = g++
    LDCC = g++
    
    LIBNAME=bLib
    LIBVER=1.0.0
    LIBEXT=dylib
    LIBFULLNAME=$(LIBNAME).$(LIBEXT)
    LIB_INSTALL_PATH=/usr/local/lib
    
    # Create object files first and show all warnings
    CFLAGS = -fPIC -g -c -Wall
    LDFLAGS = -dynamiclib -current_version $(LIBVER) -install_name $(LIB_INSTALL_PATH)/$(LIBFULLNAME)
    
    # Look for headers in the following dirs
    #  Please ln -s to your appropriate versions (of gtk, glib)
    LOCAL_INCLUDE = -I $(INCDIR)
    CPOSTFLAGS = $(LOCAL_INCLUDE)
    
    # Figure out which .o files should exist
    HEADERS=$(shell ls $(INCDIR)/*.h 2> /dev/null)
    SOURCES=$(shell ls $(SRCDIR)/*.cpp 2> /dev/null)
    OBJECTS=$(shell ls $(SRCDIR)/*.cpp 2> /dev/null | sed -e 's/$(SRCDIR)\(.*\)\.cpp/\$(OBJDIR)\1.o/g')
    LIBRARY=$(LIBFULLNAME)
    
    ifeq ($(shell uname),Darwin)
        OS_LDPF = -framework Cocoa
    
        CFLAGS += -x objective-c++
    endif
    
    # Search for the specified libraries when linking
    LDPOSTFLAGS = $(OS_LDPF)
    
    # Remove the default suffixes and define our own suffix list
    .SUFFIXES:
    .SUFFIXES: .cpp .c .o
    
    # Default target
    all: $(LIBRARY)
    
    # Link the binary using new object files
    $(LIBRARY): $(OBJECTS)
    	$(LDCC) $(LDFLAGS) $(OBJECTS) $(MAINO) $(LDPOSTFLAGS) -o $@
    
    # Create .o files for each .cpp file in $(SRCDIR) and move it to $(OBJDIR)
    $(OBJDIR)/%.o : $(SRCDIR)/%.cpp $(INCDIR)/%.h
    	$(CC) $(CFLAGS) $< $(CPOSTFLAGS) -o $@
    
    # Remove (RM = rm -f) all .o files and the executable
    clean:
    	$(ECHO) -n "Cleaning... "
    	@$(RM) $(LIBRARY)
    	@$(RM) $(OBJDIR)/*.o
    	$(ECHO) Done.
    
    install: all
    	sudo mv $(LIBRARY) $(LIB_INSTALL_PATH)/$(LIBRARY)

    Here is the output of a compile/link:
    Code:
    birchy-mac: make install
    g++ -fPIC -g -c -Wall -x objective-c++ src/bPath.cpp -I include -o obj/bPath.o
    g++ -dynamiclib -current_version 1.0.0 -install_name /usr/local/lib/bLib.dylib obj/bPath.o  -framework Cocoa -o bLib.dylib
    sudo mv bLib.dylib /usr/local/lib/bLib.dylib
    birchy-mac: ls /usr/local/lib | grep bLib
    -rwxr-xr-x  1 birchy  staff     10016  7 Aug 00:28 bLib.dylib
    birchy-mac: otool -D /usr/local/lib/bLib.dylib 
    /usr/local/lib/bLib.dylib:
    /usr/local/lib/bLib.dylib

    Here is the other Makefile for another app that needs to use the .dylib library I have created. Notice the "-L/usr/local/lib -lbLib"
    Code:
    # Common Variables...
    ECHO = @/bin/echo
    SRCDIR = src
    OBJDIR = obj
    BINDIR = bin
    INCDIR = include
    
    # Specify compiler and compile options
    CC = g++
    LDCC = g++
    
    # Create object files first and show all warnings
    CFLAGS = -c -Wall -g
    LDFLAGS =
    
    # Look for headers in the following dirs
    #  Please ln -s to your appropriate versions (of gtk, glib)
    LOCAL_INCLUDE = -I $(INCDIR)
    BLIB_INCLUDE = -I /usr/local/include/bLib
    CPOSTFLAGS = $(LOCAL_INCLUDE) $(BLIB_INCLUDE)
    
    # Figure out which .o files should exist
    HEADERS=$(shell ls $(INCDIR)/*.h 2> /dev/null)
    SOURCES=$(shell ls $(SRCDIR)/*.cpp 2> /dev/null)
    OBJECTS=$(shell ls $(SRCDIR)/*.cpp 2> /dev/null | sed -e 's/$(SRCDIR)\(.*\)\.cpp/\$(OBJDIR)\1.o/g')
    MAINSRC=main.cpp
    MAINO=$(OBJDIR)/main.o
    EXECUTABLE=$(BINDIR)/d
    
    ifeq ($(shell uname),Darwin)
        OS_LDPF = -framework Cocoa
    
        CFLAGS += -x objective-c++
    endif
    
    # Search for the specified libraries when linking
    BLIB_LIBS = -lbLib
    BLIB_LDPF = -L/usr/local/lib $(BLIB_LIBS)
    LDPOSTFLAGS = $(OS_LDPF) $(BLIB_LDPF)
    
    # Remove the default suffixes and define our own suffix list
    .SUFFIXES:
    .SUFFIXES: .cpp .c .o
    
    # Default target
    all: $(EXECUTABLE)
    
    # Link the binary using new object files
    $(EXECUTABLE): $(OBJECTS) $(MAINO)
    	$(LDCC) $(LDFLAGS) $(OBJECTS) $(MAINO) $(LDPOSTFLAGS) -o $@
    
    # Remake main.o whenever main.cpp or a header changes
    $(MAINO): $(MAINSRC) $(HEADERS)
    	$(CC) $(CFLAGS) $< $(CPOSTFLAGS) -o $@
    
    # Create .o files for each .cpp file in $(SRCDIR) and move it to $(OBJDIR)
    $(OBJDIR)/%.o : $(SRCDIR)/%.cpp $(INCDIR)/%.h
    	$(CC) $(CFLAGS) $< $(CPOSTFLAGS) -o $@
    
    # Remove (RM = rm -f) all .o files and the executable
    clean:
    	$(ECHO) -n "Cleaning... "
    	@$(RM) $(EXECUTABLE)
    	@$(RM) $(OBJDIR)/*.o
    	$(ECHO) Done.
    
    # Make and run
    run: all
    	./$(EXECUTABLE)
    
    # Make and debug
    debug: all
    	gdb $(EXECUTABLE)

    And finally, here is the error message I'm getting upon compiling the app:
    Code:
    birchy-mac: make
    g++ -c -Wall -g -x objective-c++ main.cpp -I include -I /usr/local/include/bLib -o obj/main.o
    g++   obj/main.o -framework Cocoa -L/usr/local/lib -lbLib -o bin/d
    ld: library not found for -lbLib
    collect2: ld returned 1 exit status
    make: *** [bin/d] Error 1
    I'm at a loss for why this is happening.
    Everything I've seen on Google says I'm creating the dylib properly.
    Do I need to install it or something, like in Linux, so my library cache is updated or something? :confused:

    Thanks in advance!
    -Birchy
     
  2. smith3134 macrumors newbie

    Joined:
    Aug 6, 2010
    #2
    Shared libraries are libraries that are loaded by programs when they start. When a shared library is installed properly, all programs that start afterwards automatically use the new shared library. Every shared library has a special name soname. The soname has the prefix "lib'', the name of the library, the phrase "so'', followed by a period and a version number which is incremented whenever the interface changes may occur.
     
  3. birchy thread starter macrumors newbie

    birchy

    Joined:
    Aug 6, 2010
    Location:
    Canada
    #3
    Omg, that was my mistake... I needed to prefix "lib" to my library name...
    Thanks smith! It must be time for me to go to bed :p
     

Share This Page