Question

I'm very new to makefiles. I'm reading the GNU-make manual, but I'm still unclear about how to set the parameters for the compiler and the linker when they are executed by an implicit rule. This is part of the makefile, note there is no explicit declaration of how to compile and link everything:

.PHONY: $(TARGET) build_libs

all: build_libs $(TARGET)

$(TARGET):
    @echo "============> building target: $(TARGET)"
    @$(MAKE) -C $(SDK_PATH)/VP_SDK/Build $(TMP_SDK_FLAGS) $(SDK_FLAGS) $(MAKECMDGOALS) USE_LINUX=yes
    mv $(ARDRONE_TARGET_DIR)/ardrone_testing_tool $(TARGET)
    mv $(TARGET) $(ARDRONE_TARGET_DIR)/
    @echo "============> end building target: $(TARGET)"

$(MAKECMDGOALS): build_libs
    @echo "============> making cmd goals"
    @$(MAKE) -C $(SDK_PATH)/VP_SDK/Build $(TMP_SDK_FLAGS) $(SDK_FLAGS) $(MAKECMDGOALS) USE_LINUX=yes
    @echo "============> end making cmd goals"

build_libs:
    @echo "============> building libs"
    @$(MAKE) -C $(SDK_PATH)/Soft/Build $(TMP_SDK_FLAGS) $(SDK_FLAGS) $(MAKECMDGOALS) USE_LINUX=yes
    @echo "============> end building libs"

That makefile builds an executable from the source files and library. But I want to compile them into a shared library. Because of that I (think I) have to add the -fPIC parameter to cc and the -shared and -soname parameters to ld. I've tried with CFLAGS=-fPIC and LDFLAGS=-shared -soname foo, which didn't work. Has anybody suggestions on how to get a shared libarary? If you need more information please just ask. Thanks in advance!

UPDATE: The makefile in $(SDK_PATH)/Soft/Build:

GEN_CUSTOM_HEADER:=../Common/generated_custom.h

include custom.makefile 
include config.makefile

GNUTOOLS_PATH=/usr/local/$(GNUTOOLS_VERSION)/bin

define ADD_RULE_TEMPLATE
  TO_BUILD+=build_$(1)
endef

# Add rule for each target
$(foreach target,$(TARGETS),$(eval $(call ADD_RULE_TEMPLATE,$(target))))

.PHONY: linux_sample svn_update $(TO_BUILD) build_libs $(MAKECMDGOALS)

all: $(GEN_CUSTOM_HEADER) build_libs $(TO_BUILD)

$(GEN_CUSTOM_HEADER): custom.makefile
    @echo "#ifndef _GENERATED_CUSTOM_CONFIGURATION_H_" > $@
    @echo "#define _GENERATED_CUSTOM_CONFIGURATION_H_" >> $@
    @echo >> $@
    @echo "#if  defined(BR2_PACKAGE_BCM4318_AP)" >> $@
    @echo "#  define AP" >> $@
    @echo "#else" >> $@
    @echo "#  define STA" >> $@
    @echo "#endif" >> $@
    @echo "#define CURRENT_NUM_VERSION_SOFT \"$(MAJOR_VERSION).$(MINOR_VERSION).$(MODIF_VERSION)\"" >> $@
    @echo "#define CURRENT_BUILD_DATE \"$(shell date +%F\ %H:%M)\"" >> $@
    @echo >> $@
ifeq ("$(VIDEO_YUV)","yes")
    @echo "#define USE_VIDEO_YUV" >> $@
endif
ifeq ("$(RECORD_VISION_DATA)","yes")
    @echo "#define RECORD_VISION_DATA" >> $@
endif
    @echo >> $@
    @echo "#define WIFI_NETWORK_NAME \"$(WIFI_NETWORK_NAME)\"" >> $@
    @echo "#define WIFI_BROADCAST \"$(WIFI_BROADCAST)\"" >> $@
    @echo "#define WIFI_ARDRONE_IP \"$(WIFI_ARDRONE_IP)\"" >> $@
    @echo >> $@
    @echo "#if defined(__linux__) || defined(USE_MINGW32)" >> $@
    @echo "# define WIFI_MOBILE_IP \"$(WIFI_MOBILE_IP)\"" >> $@
    @echo "# define WIRED_ITFNAME \"$(WIRED_ITFNAME)\"" >> $@
    @echo "#endif // ! __linux__" >> $@
    @echo >> $@
    @echo >> $@
    @echo "#endif // ! _GENERATED_CUSTOM_CONFIGURATION_H_" >> $@

ifneq "$(MAKECMDGOALS)" ""
  ifneq "$(MAKECMDGOALS)" "clean"
    ifneq "$(MAKECMDGOALS)" "update"
      $(MAKECMDGOALS):
      @echo -e "\nCannot make what you ask me to do :-("
    else
      $(MAKECMDGOALS): svn_update
    endif
  endif
endif

$(MAKECMDGOALS): build_libs $(TO_BUILD)

checkpackages:
ifeq ($(IPHONE_MODE),yes)
    sh $(shell pwd)/check_dependencies.sh iphone RELEASE_BUILD=$(RELEASE_BUILD) $(MAKECMDGOALS)
else
ifeq ($(USE_LINUX),yes)
    sh $(shell pwd)/check_dependencies.sh static RELEASE_BUILD=$(RELEASE_BUILD) $(MAKECMDGOALS)
else
ifeq ($(USE_ANDROID),yes)
    sh $(shell pwd)/check_dependencies.sh android_no_neon RELEASE_BUILD=$(RELEASE_BUILD) $(MAKECMDGOALS)
endif
endif
endif

define GENERIC_RULES_TEMPLATE
build_$(1): 
    @$(MAKE) -C $(1) $(MAKECMDGOALS)
endef

$(foreach target,$(TARGETS),$(eval $(call GENERIC_RULES_TEMPLATE,$(target))))

build_libs: checkpackages
    @$(MAKE) PC_TARGET=yes USE_ARDRONE_TOOL=yes TARGET=pc_ USE_MINGW32=no -C ../Lib/Build $(MAKECMDGOALS)
    @$(MAKE) PC_TARGET=yes USE_ARDRONE_TOOL=no TARGET=pc_ USE_MINGW32=no -C ../Lib/Build $(MAKECMDGOALS)

ifeq ("$(MINGW32_MODE)","yes")
ifeq ($(shell which i586-mingw32msvc-gcc 2> /dev/null),)
        $(warning You need MinGW32 to compile My Ardrone lib for Windows if you want. (under Debian: apt-get install mingw32))
else
#   @$(MAKE) PC_TARGET=yes TARGET=mingw32_ USE_MINGW32=yes TMP_SDK_FLAGS="USE_MINGW32=yes NO_COM=yes USE_BLUEZ=no" -C ../Lib/Build $(MAKECMDGOALS)
#   @$(MAKE) PC_TARGET=yes TARGET=emb_mingw32_ USE_MINGW32=yes CONTROL_DLL=yes TMP_SDK_FLAGS="USE_MINGW32=yes NO_COM=yes USE_BLUEZ=no" -C ../Lib/Build $(MAKECMDGOALS)
endif
endif
ifeq ($(WIIMOTE_SUPPORT),yes)
#   @$(MAKE) PC_TARGET=yes TARGET=pc_ TMP_SDK_FLAGS="USE_BLUEZ=yes" -C ../Lib/libcwiid $(MAKECMDGOALS)
endif

define svn_update_template
   cd ../.. ; \
    echo "Checking out tag $(1) of $(2) ..." ; \
    if [ $(1) != head ] ; then \
       svn co -r $(1) https://svn.ardrone.org/repo/ARDrone_API/$(2) ; \
    else \
        svn co https://svn.ardrone.org/repo/ARDrone_API/$(2) ; \
    fi ; \
    cd Soft/Build ; 
endef

svn_update:
    @-$(call svn_update_template,$(SDK_VERSION),ARDroneLib)

If custom.makefile and config.makefile are needed you can find them here: http://pastebin.com/H8PNKKhu

UPDATE 2: I just discovered this, located in $(SDK_PATH)/VP_SDK/Build: http://pastebin.com/3knnSkmy

Was it helpful?

Solution 3

I did it. Finally!!!

The solution: in $(SDK_PATH)/VP_SDK/Build there was a file named generic.makefile containing all the compiler and linker invocations. I had to add the -shared and -fPIC arguments to some of them. Sounds really simple, but nothing of that was documented so I first had to look for that hidden compiler/linker invocations...

OTHER TIPS

Since you haven't showed us the makefile in $(SDK_PATH)/Soft/Build, I'm going to take a guess.

In the GNU Make manual, there is the list of variables used by implicit rules:

  • CFLAGS: Extra flags to give the C compiler.
  • LDFLAGS: Extra flags to give to compiler when they are supposed to invoke the linker 'ld'.

In addition, the catalogue of implicit rules mentions the LDLIBS variable that names libraries used in the implicit link rule. (The implicit link rule is fine when you have a single source file being linked or where one of the object files is the name of the final executable, otherwise you need to write an explicit linking rule.)

This isn't coming into focus. These appear to be generated makefiles, so they're hard to trace, there's clearly more going on than we're seeing (and I don't blame you for not posting everything), and I don't see where the build_libs rule leads, or any use of the linker, or anything that could build a static library. We could show you how to write an explicit rule to build a shared library, but without a list of sources or objects we wouldn't know what to put into that library.

This is getting desperate, but could you try the following:

1) make -C $(SDK_PATH)/Soft/Build (putting in the appropriate value for $(SDK_PATH)) and verify that this produces the static library.

2) make -n, capture the torrent of output and put it in pastebin. We'll try to see what rules it's using, which might lead to what we need.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top