動機
最近被autoconf弄,所以來記錄一下各種make 如果需要範例code在github上
手工
header是給compiler看,但不管實際上有沒有這些函數的實作
之後是透過linker去static或是dynamic的地方找code
這次的範例是有三個cpp(與各自的header)
- 一個主程式 :
main.cpp
- static 的 函數 :
stc.cpp
- dynamic 的 函數 :
dyn.cpp
編的方式
給I
:去哪找header
給L
:去哪找so
給l
:用哪個library(像libdyn.so就是-ldyn
)
g++ -c -o syn.o syn.cpp
g++ -fPIC -shared -o libdyn.so dyn.cpp
g++ -I. -o main main.cpp sta.o libdyn.so
LD_LIBRARY_PATH=. ./main # LD_LIBRARY_PATH is to indicate where to search .so file
make
makefile的邏輯很簡單
- 每個target都有對應要編的檔案
- 再編檔案之前都要看前提有沒有滿足
而Makefile為了方便有一些自訂的變數,像
$@
: target的名字$^
: 整串前提$<
: 所有前提的第一項
那PHONY是為了什麼存在的? clean沒有對應的檔案,但可以當成一個假的target去跑
main: main.cpp sta.o dyn.so
g++ -I. -o $@ $^
dyn.so: dyn.cpp
g++ -fPIC -shared -o $@ $^
%.o: %.cpp
g++ -c -o $@ $<
# current , first
clean:
rm *.o *.so
.PHONY: clean
autoconf
整個步驟如下
- autoscan
- mv configure.scan configure.in
- 改 configure.in
- 寫 Makefile.am
- autoreconf -i
- ./configure
- make
很長,也很眼花撩亂
先看configure.in,主要是看有EDIT或是ADD的那幾行
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
#AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
AC_INIT(main, 1.0.0, 123456@gmail.com) # EDIT
AC_CONFIG_SRCDIR([main.cpp])
AM_INIT_AUTOMAKE([foreign -Wall -Werror]) # EDIT, optional
AC_CONFIG_HEADERS([config.h])
# autoreconf complain ,so add this line
AC_CONFIG_MACRO_DIRS([m4]) # ADD this to stop complaining
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
LT_INIT # ADD this, cuz we have .so file
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
再來是Makefile.am,同樣看註解
AUTOMAKE_OPTIONS=foreign
# autoreconf complain, so add this line
ACLOCAL_AMFLAGS = -I m4
# program !!
bin_PROGRAMS=main
main_SOURCES=main.cpp sta.cpp
include_HEADERS = sta.h dyn.h
# Add out .so file
lib_LTLIBRARIES = libdyn.la
libdyn_la_SOURCES = dyn.cpp
# link .so file after compiling has done
LDADD = libdyn.la
cmake
人性化的多,只要一個CMakeLists.txt,就沒事了
比較需要注意的是CMAKE_SOURCE_DIR與CMAKE_BINARY_DIR
Assuming that you have 2 folders src and build where src contains your projects and build is the empty folder that you just created so you can deploy your out-of-tree build in it: CMAKE_SOURCE_DIR is the path to src where CMAKE_BINARY_DIR points to build.
CMAKE_CURRENT_SOURCE_DIR => CMakeLists.txt在? CMAKE_CURRENT_BINARY_DIR => cmake正在哪裡跑?
感覺這根本不用解釋,看就懂了
cmake_minimum_required (VERSION 3.16)
project(main CXX)
include_directories( ${CMAKE_SOURCE_DIR} )
link_directories( ${CMAKE_SOURCE_DIR} )
set(main_SOURCES
main.cpp
sta.cpp
)
add_library(dyn
SHARED
dyn.cpp
)
set(main_LIBS
dyn
)
add_executable( ${PROJECT_NAME} ${main_SOURCES} )
target_link_libraries( ${PROJECT_NAME} ${main_LIBS} )
Ref
CMake 入門 cmake与autoconf+automake的对比 构建Make,Automake,CMake Using Automake and Autoconf xmake vs cmake对比分析 Where is CMAKE_SOURCE_DIR?