簡體   English   中英

部分編譯並在makefile中包含boost(C ++)

[英]Partially compile and include boost with makefile (c++)

我有一個c ++項目,我希望它具有一定的可移植性,並且可以通過發出單個“ make”命令進行編譯。 我目前對某些操作使用boost標頭,但現在需要boost的“文件系統”,需要編譯。

我知道有一種方法可以使用包含的shell腳本來編譯boost,但這需要永遠。 我很好奇一種方法,可以有選擇地編譯一個makefile中指定的boost庫,並將它們包含在鏈接過程中。

我目前的總體思路是:

  1. 有想要編譯和包含的boost庫的makefile變量。

  2. 從boost分發文件夾中編譯這些庫(在任何依賴項目之前),並將已編譯的二進制文件輸出到makefile項目中的特定文件夾(例如:“ lib”文件夾)

  3. 我了解如何使用以下方法將這些文件包含在項目中:

    -Llib

做到這一點的最佳方法是什么,以及選擇編譯的增強輸出在哪里? 文件應該是.a還是.o文件? (或沒有擴展名?)

這是先前答案的手動makefile的更老的兄弟。 給定BOOST發行版的路徑BOOST_DISTRO ,它找到TARGET_BOOST_LIBS指定的目標庫的相關源文件,將它們編譯為$(WORK_FOLDER)/<lib>/ ,並將生成的對象歸檔到$(DEST_FOLDER)/libboost_<lib>.a

BOOST_DISTRO=.
DEST_FOLDER=libs
WORK_FOLDER=build

TARGET_BOOST_LIBS=\
  system \
  filesystem \
  serialization

.PHONY: all
all: $(foreach lib,$(TARGET_BOOST_LIBS),$(DEST_FOLDER)/libboost_$(lib).a )

$(DEST_FOLDER):
    mkdir -p $(DEST_FOLDER)

$(WORK_FOLDER):
    mkdir -p $(WORK_FOLDER)

#####
# helper for building the .o files in WORK_FOLDER
#####
define MAKE_BOOST_LIB_COMPILE_RULES
$(foreach cppfile,$(shell ls $(BOOST_DISTRO)/boost/libs/$(1)/src/*.cpp),$(WORK_FOLDER)/$(1)/$(notdir $(cppfile:.cpp=.o)): $(cppfile) | $(WORK_FOLDER)/$(1)
    $(CXX) $(CXXFLAGS) -D BOOST_ALL_NO_LIB \
          -I$(BOOST_DISTRO)/boost \
          -c $$^ \
          -o $$@
)
endef


#####
# define the build rules based on the files we find in the subfolders of
# the boost distro that correspond to our library names
#####
define BUILD_BOOST_LIB
$(WORK_FOLDER)/$(1): | $(WORK_FOLDER)
    mkdir -p $$@
$(call MAKE_BOOST_LIB_COMPILE_RULES,$(1))
$(DEST_FOLDER)/libboost_$(1).a: $(foreach cppfile,$(notdir $(shell ls $(BOOST_DISTRO)/boost/libs/$(1)/src/*.cpp)),$(WORK_FOLDER)/$(1)/$(cppfile:.cpp=.o)) | $(DEST_FOLDER)
    ar r $$@ $$^
    ranlib $$@
endef


#####
# dynamically generate the build rules from the list of libs
#####
$(foreach lib,$(TARGET_BOOST_LIBS),$(eval $(call BUILD_BOOST_LIB,$(lib))))

.PHONY: clean
clean:
    -rm -rf $(WORK_FOLDER)
    -rm -rf $(DEST_FOLDER)

使用我古老的BOOST( #define BOOST_VERSION 105500 )進行測試,這將構建列出的庫,並且一個虛擬測試程序會成功編譯並調用boost::filesystem::absolute()

使用lockcmpxchg8b的答案,我可以使其適應我的需求。

在遞歸調用時使makefile正常工作有點棘手,但我能夠使其正常工作。

SHELL = /bin/sh

# This makefile expects multiple arguments to be passed:
#
# Use the pattern: make var_name="var_value" when invoking this makefile
#
# BOOST_VER (the version suffix )
# BOOST_LIBS_TO_BUILD (space delimited list of boost libraries to build)
# BOOST_LIB_DIR (the output lib dir for the boost libraries)
# BOOSTDIR (the base directory to build from)
#

# Compile Info
CXX = g++
CXXFLAGS = -Wall -std=c++11

WORK_FOLDER = obj_boost$(BOOST_VER)

.PHONY: all
all: $(foreach lib,$(BOOST_LIBS_TO_BUILD),$(BOOST_LIB_DIR)/libboost_$(lib).a )

$(BOOST_LIB_DIR):
    @mkdir -p $(BOOST_LIB_DIR)

$(WORK_FOLDER):
    @mkdir -p $(WORK_FOLDER)

#####
# helper for building the .o files in WORK_FOLDER
#####
define MAKE_BOOST_LIB_COMPILE_RULES
$(foreach cppfile,$(shell ls $(BOOSTDIR)/libs/$(1)/src/*.cpp),$(WORK_FOLDER)/$(1)/$(notdir $(cppfile:.cpp=.o)): $(cppfile) | $(WORK_FOLDER)/$(1)
        $(CXX) $(CXXFLAGS) -D BOOST_ALL_NO_LIB \
                    -I$(BOOSTDIR) \
                    -c $$^ \
                    -o $$@
)
endef

#####
# define the build rules based on the files we find in the subfolders of
# the boost distro that correspond to our library names
#####
define BUILD_BOOST_LIB
$(WORK_FOLDER)/$(1): | $(WORK_FOLDER)
        @mkdir -p $$@
$(call MAKE_BOOST_LIB_COMPILE_RULES,$(1))
$(BOOST_LIB_DIR)/libboost_$(1).a: $(foreach cppfile,$(notdir $(shell ls $(BOOSTDIR)/libs/$(1)/src/*.cpp)),$(WORK_FOLDER)/$(1)/$(cppfile:.cpp=.o)) | $(BOOST_LIB_DIR)
        @ar r $$@ $$^
        @ranlib $$@
endef

#####
# dynamically generate the build rules from the list of libs
#####
$(foreach lib,$(BOOST_LIBS_TO_BUILD),$(eval $(call BUILD_BOOST_LIB,$(lib))))

.PHONY: clean
clean:
        @rm -rf $(WORK_FOLDER)
        @rm -rf $(BOOST_LIB_DIR)/*
        @echo "---- Done Cleaning Boost Libs ----"

要調用此makefile,我使用以下命令從另一個makefile調用它:

# Boost
BOOST_VER= _1_65_1

BOOST_LIBS_TO_BUILD = filesystem timer chrono
#relative to this file
BOOST_LIB_DIR = shared/lib_boost$(BOOST_VER)
#relative to this file
BOOSTDIR = shared/boost$(BOOST_VER)

#Subdirectories
DIRECTORIES = $(sort $(dir $(wildcard */makefile)))

.PHONY: build
build: dependencies
        @$(foreach dir,$(DIRECTORIES),$(MAKE) -C $(dir);)

dependencies:
        @echo "---- Build Dependencies ----"
        @$(MAKE) -C shared -f build_boost_libs.mk BOOST_LIBS_TO_BUILD="$(BOOST_LIBS_TO_BUILD)" BOOST_LIB_DIR="../$(BOOST_LIB_DIR)" BOOSTDIR="../$(BOOSTDIR)" BOOST_VER="$(BOOST_VER)"

正確調用遞歸生成的模式是:

$(MAKE) -C subdir_of_makefile -f makefile_name.mk

使用$(MAKE)是調用make的正確方法(根據文檔 -確保使用相同的make命令作為最頂層的make)並正確更改運行目錄,您需要使用-C參數(否則,任何子make的目錄上下文都是調用堆棧中最頂層的父makefile)。 -f選項指定一個makefile,除了makefile的默認名稱以外,它什么都沒有。 查找命名的makefile時,這考​​慮了-C選項。

我還發現,將“參數”傳遞給makefile有點棘手,通常是通過export和unexport完成的,但是這些問題是由於僅將要導出的變量的LAST“ status”用於整個makefile。 您無法導出變量,無法調用子make,然后取消導出。 在整個makefile運行中,它將不導出(因為變量的最后一個“狀態”將在子make之后被調用,但仍要導出)。 在生成文件執行之前,將計算/解析變量“狀態”。

謝謝您的幫助! 我很感激。 將來,我還將在一個開源項目中發布此Makefile(我相信您的用戶名會對此有所幫助)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM