将Makefile转换为CMakeLists,从哪里开始

kal*_*ger 5 makefile cmake

我搜索了inet,但我没有找到任何明确的答案.你能指出我如何将Makefile转换为CMakeLists的正确方向吗?

我想这样做,因为我是makefile和cmake的新手.在我的工作中,CMake更常用,因为我需要开始使用其中一个,我更喜欢在CMake中拥有一切.我知道CMake正在生成一个Makefile,但对我来说,CMake比Makefile更容易阅读.

我有以下Makefile:

PREFIX ?= /usr/local

CC = gcc
AR = ar

CFLAGS = -std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4

APRILTAG_SRCS := $(shell ls *.c common/*.c)
APRILTAG_HEADERS := $(shell ls *.h common/*.h)
APRILTAG_OBJS := $(APRILTAG_SRCS:%.c=%.o)
TARGETS := libapriltag.a libapriltag.so 
# LIBS := -Lusr/include/flycapture

.PHONY: all
all: $(TARGETS)
    @$(MAKE) -C example all

.PHONY: install
install: libapriltag.so
    @chmod +x install.sh
    @./install.sh $(PREFIX)/lib libapriltag.so #this should be the line that install the library
    @./install.sh $(PREFIX)/include/apriltag $(APRILTAG_HEADERS)
    @sed 's:^prefix=$$:prefix=$(PREFIX):' < apriltag.pc.in > apriltag.pc
    @./install.sh $(PREFIX)/lib/pkgconfig apriltag.pc
    @rm apriltag.pc
    @ldconfig

libapriltag.a: $(APRILTAG_OBJS)
    @echo "   [$@]"
    @$(AR) -cq $@ $(APRILTAG_OBJS)

libapriltag.so: $(APRILTAG_OBJS)
    @echo "   [$@]"
    @$(CC) -fPIC -shared -o $@ $^

%.o: %.c
    @echo "   $@"
    @$(CC) -o $@ -c $< $(CFLAGS)

.PHONY: clean
clean:
    @rm -rf *.o common/*.o $(TARGETS)
    @$(MAKE) -C example clean
Run Code Online (Sandbox Code Playgroud)

我不是要求你做我的工作,但我希望有一些指导或一个好的链接在哪里看.

该项目包含C和C++编程语言.

我开始创建一个新的CMakeLists.txt文件,但它仍然无法正常工作.它给了我以下错误:您已经为库librapriltag.a调用了ADD_LIBRARY而没有任何源文件.这通常表示您的CMakeLists.txt文件存在问题

-- Configuring done
CMake Error: Cannot determine link language for target "librapriltag.a".
CMake Error: CMake can not determine linker language for target: librapriltag.a
-- Generating done
-- Build files have been written to: .....
Run Code Online (Sandbox Code Playgroud)

我开始创建的CMakeLists.txt如下:

project( apriltag2 C CXX)

cmake_minimum_required(VERSION 2.8)

set(CMAKE_C_FLAGS "-std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4")

include_directories("/home/fschiano/Repositories/apriltag2")
include_directories("/home/fschiano/Repositories/apriltag2/common")

add_library( librapriltag.a )
Run Code Online (Sandbox Code Playgroud)

有效的CMakeLists.txt如下:

project( apriltag2 )

cmake_minimum_required(VERSION 2.8)

set(CMAKE_C_FLAGS "-std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4")

message("CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}")

file(GLOB apriltag_SRC "*.c")
file(GLOB apriltag_HEADERS "*.h")

set(APRILTAG_SRCS ${apriltag_SRC})
set(APRILTAG_HEADERS ${apriltag_HEADERS})

message(STATUS "CMAKE_CURRENT_LIST_DIR=${CMAKE_CURRENT_LIST_DIR}")

add_library(apriltag STATIC ${APRILTAG_SRCS})

target_include_directories(apriltag PUBLIC ${CMAKE_SOURCE_DIR})
target_compile_options(apriltag PUBLIC -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -O4)

install(TARGETS apriltag
        ARCHIVE DESTINATION lib
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib)
install(DIRECTORY CMAKE_CURRENT_LIST_DIR/include/
        DESTINATION CMAKE_CURRENT_LIST_DIR/include/
        FILES_MATCHING PATTERN *.h)
Run Code Online (Sandbox Code Playgroud)

编辑:

有些事情仍然不对.如果我想在我的库中更改某些内容,就像在/home/fschiano/Repositories/apriltag2/common 我做的所有这些修改之前使用的Makefile一样,我会这样做:

  1. 使
  2. 在我想修改的文件中做一些修改
  3. sudo make install,这会给我以下输出:

    /usr/local/lib/libapriltag.so /usr/local/include/apriltag/apriltag.h /usr/local/include/apriltag/common/g2d.h /usr/local/include/apriltag/common/getopt.h /usr/local/include/apriltag/common/homography.h /usr/local/include/apriltag/common/image_f32.h /usr/local/include/apriltag/common/image_u8.h/usr/local/include/apriltag /common/image_u8x3.h /usr/local/include/apriltag/common/matd.h /usr/local/include/apriltag/common/math_util.h /usr/local/include/apriltag/common/pnm.h/usr /local/include/apriltag/common/postscript_utils.h /usr/local/include/apriltag/common/string_util.h /usr/local/include/apriltag/common/svd22.h/usr/local/include/apriltag/common /thash_impl.h /usr/local/include/apriltag/common/timeprofile.h /usr/local/include/apriltag/common/time_util.h /usr/local/include/apriltag/common/unionfind.h/usr/local /include/apriltag/common/workerpool.h /usr/local/include/apriltag/common/zarray.h /usr/local/include/apriltag/common/zhash.h/usr/local/include/apriltag/common/zmaxheap .h/usr/loca l/include/apriltag/tag16h5.h /usr/local/include/apriltag/tag25h7.h /usr/local/include/apriltag/tag25h9.h /usr/local/include/apriltag/tag36artoolkit.h/usr/local/include/apriltag/tag36h10.h /usr/local/include/apriltag/tag36h11.h /usr/local/lib/pkgconfig/apriltag.pc /sbin/ldconfig.real:/usr/lib/libstdc++.so.5不是象征性的链接

并且修改将生效.

现在,如果我删除Makefile并且我这样做:

  1. cmake.
  2. 使
  3. 在我想修改的文件中做一些修改
  4. sudo make install,它给我以下输出:

    安装项目... - 安装配置:"" - 最新:/usr/local/lib/libapriltag.a

所以似乎CMakeLists.txt的安装部分不对!

install.sh文件如下.

#!/bin/sh -e
# Usage: install.sh TARGET [RELATIVE PATHS ...]
#
# e.g. ./install.sh /usr/local foo/file1 foo/file2 ...
# This creates the files /usr/local/foo/file1 and /usr/local/foo/file2

TARGETDIR=$1
shift

for src in "$@"; do
    dest=$TARGETDIR/$src
    mkdir -p $(dirname $dest)
    cp $src $dest
    echo $dest
done
Run Code Online (Sandbox Code Playgroud)

你能帮我吗?谢谢

Tor*_*örn 10

让我们一步一步来:

PREFIX ?= /usr/local
Run Code Online (Sandbox Code Playgroud)

我们忽略它,因为它是默认设置。可以被覆盖CMAKE_INSTALL_PREFIX

CC = gcc
AR = ar
Run Code Online (Sandbox Code Playgroud)

也忽略这些。使用CMAKE_C_COMPILERCMAKE_CXX_COMPILER强制切换编译器。

CFLAGS = -std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4
Run Code Online (Sandbox Code Playgroud)

它们对于类似 gcc 的编译器来说非常特别。CMAKE_C_COMPILER_ID MATCHES GNU定义目标后,有条件地设置它们以进一步降低。标准由set(C_STANDARD 98)和设定set(CXX_STANDARD 98)

APRILTAG_SRCS := $(shell ls *.c common/*.c)
Run Code Online (Sandbox Code Playgroud)

定义一个单独列出所有源文件的变量: set(APRILTAG_SRCS ...)

APRILTAG_HEADERS := $(shell ls *.h common/*.h)
Run Code Online (Sandbox Code Playgroud)

定义一个单独列出所有头文件的变量:set(APRILTAG_HEADERS ...). 但是,您实际上在任何地方都不需要它们(除非您希望 Visual Studio 列出它们)。

APRILTAG_OBJS := $(APRILTAG_SRCS:%.c=%.o)
Run Code Online (Sandbox Code Playgroud)

在大多数情况下,您不需要那个。对于那些罕见的情况,有Object Libraries

TARGETS := libapriltag.a libapriltag.so 
# LIBS := -Lusr/include/flycapture
Run Code Online (Sandbox Code Playgroud)

我们在这里定义我们的库add_library

add_library(apriltag ${APRILTAG_SRCS})
target_include_directories(apriltag PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/apriltag)
target_compile_options(apriltag PUBLIC -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -O4)
Run Code Online (Sandbox Code Playgroud)

静态共享之间的切换是通过BUILD_SHARED_LIBS调用 CMake来完成的。

.PHONY: all
all: $(TARGETS)
    @$(MAKE) -C example all
Run Code Online (Sandbox Code Playgroud)

无所事事。CMake 会自动创建它。

.PHONY: install
install: libapriltag.so
    @chmod +x install.sh
    @./install.sh $(PREFIX)/lib libapriltag.so #this should be the line that install the library
    @./install.sh $(PREFIX)/include/apriltag $(APRILTAG_HEADERS)
    @sed 's:^prefix=$$:prefix=$(PREFIX):' < apriltag.pc.in > apriltag.pc
    @./install.sh $(PREFIX)/lib/pkgconfig apriltag.pc
    @rm apriltag.pc
    @ldconfig
Run Code Online (Sandbox Code Playgroud)

CMake 将把这减轻一个幅度:

install(TARGETS apriltag
        ARCHIVE DESTINATION lib
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION lib)
install(DIRECTORY include/
        DESTINATION include/
        FILES_MATCHING PATTERN *.h)
Run Code Online (Sandbox Code Playgroud)

这将安装库静态和共享库(无论存在什么)和头文件。

libapriltag.a: $(APRILTAG_OBJS)
    @echo "   [$@]"
    @$(AR) -cq $@ $(APRILTAG_OBJS)

libapriltag.so: $(APRILTAG_OBJS)
    @echo "   [$@]"
    @$(CC) -fPIC -shared -o $@ $^

%.o: %.c
    @echo "   $@"
    @$(CC) -o $@ -c $< $(CFLAGS)
Run Code Online (Sandbox Code Playgroud)

这一切都不需要。

.PHONY: clean
clean:
    @rm -rf *.o common/*.o $(TARGETS)
    @$(MAKE) -C example clean
Run Code Online (Sandbox Code Playgroud)

你不需要那个。CMake 会clean自动生成一个目标。


arr*_*owd 5

从判断起TARGETS := libapriltag.a libapriltag.so,你将需要add_library命令来创建目标.

不要像使用通配符一样收集要编译的源APRILTAG_SRCS := $(shell ls *.c common/*.c),而是建议在add_library调用中明确列出它们.但是如果你真的想自动列出它们,请参阅file(GLOB ...)命令.(但有一些重要的事情要注意,请参阅使用GLOB全局指定源文件?).

所述clean目标将自动CMake的生成.

最后,请参阅install()命令的文档以创建安装规则.

编译器标志使用set(CMAKE_C_FLAGS "blabla")或附加使用set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} blabla").

  • 不要使用`GLOB`.CMake无法检测新添加的文件以自动重新配置项目. (3认同)