I have a library libmya.so and a library libmyb.so. The functions in libmyb.so depend on functions in libmya.so. Also I have an executable myexe which depends on libmyb.so. When I make these libraries, in which rules should I put the -l options?
Should it be 1):
libmya.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) -o $@ $^
libmyb.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^ -lmya
myexe: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^ -lmyb
or 2)
libmya.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) -o $@ $^
libmyb.so: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^
myexe: $(OBJ_FILES)
$(CPP) $(LDFLAGS) $(LIBS) -o $@ $^ -lmya -lmyb
or some other combo?
I would go with option 1 (though option 2 works, I wouldn’t recommend it since then anybody who links the exe needs to remember all the transitive libraries required).
However, this advice is only for making an
sofile, as you do above.sofiles (shared objects) are “intelligent” libraries, much like executables, except they don’t have a main.sofiles can link to other libraries (like executables), and when an executable links to ansofile, it will automatically recursively include the dependencies of thesofile.Therefore, an
sofile you create should be linked with all of its dependencies.A “dumb” library, such as an
afile (static library) is a different story; then you need to do all the linking in the executable (option 2).I recommend you use the
lddtool to investigate the dependencies of both the executable and thesofile to see how this works.For a real-world example of why option 1 is better, try
ldd /usr/lib/libpng.so. Note that libpng is linked with libz. If it wasn’t, anybody who ever links against libpng would also need to link against libz. As it is, you can link against libpng without even knowing that libz is involved.