Skip to content

Commit

Permalink
Switch to CMake (#38)
Browse files Browse the repository at this point in the history
* Switch to CMake (release builds are broken)

* Fixed release builds

* Install SDL2 first

* Fix install and uninstall

* Update INSTALL.md

* Update INSTALL.md
  • Loading branch information
Yey007 authored Dec 11, 2024
1 parent 5508c18 commit 222e830
Show file tree
Hide file tree
Showing 8 changed files with 206 additions and 158 deletions.
52 changes: 11 additions & 41 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,52 +7,13 @@ on:
- main

jobs:
build_lib:
build_test_bench:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Eigen
run: sudo apt-get install libeigen3-dev
- name: Build library
run: make libcevicp.a OPT=RELEASE
- name: Upload library
uses: actions/upload-artifact@v4
with:
name: libcevicp.a
path: libcevicp.a
retention-days: 1
test:
runs-on: ubuntu-22.04
needs: build_lib
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download library
uses: actions/download-artifact@v4
with:
name: libcevicp.a
- name: Install Eigen
run: sudo apt-get install libeigen3-dev
- name: Install simple-test
run: |
git clone https://github.com/cornellev/simple-test
cd simple-test
sudo make install
- name: Run tests
run: make test OPT=RELEASE
bench:
runs-on: ubuntu-22.04
needs: build_lib
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Download library
uses: actions/download-artifact@v4
with:
name: libcevicp.a
- name: Install Eigen
run: sudo apt-get install libeigen3-dev
- name: Install SDL2
run: sudo apt-get install libsdl2-dev
- name: Install sdl-wrapper
Expand All @@ -70,5 +31,14 @@ jobs:
git clone https://github.com/cornellev/config
cd config
sudo make install
- name: Install simple-test
run: |
git clone https://github.com/cornellev/simple-test
cd simple-test
sudo make install
- name: Build all
run: make OPT=Release
- name: Run tests
run: make test OPT=Release
- name: Run benchmarks
run: make bench OPT=RELEASE
run: make bench OPT=Release
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ docs/
_temp
*.gz
book/icp_descr
build/
1 change: 0 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
{
"C_Cpp.default.compilerPath": "/Users/ethan/Programming/bin/cc",
"files.associations": {
"__bit_reference": "cpp",
"__bits": "cpp",
Expand Down
95 changes: 95 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
cmake_minimum_required(VERSION 3.10)
project(cevicp CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Add compile options
add_compile_options(-Wall -Wextra -pedantic)

# Find dependencies
find_package(Eigen3 REQUIRED)
find_package(SDL2 REQUIRED)

# Library target
set(LIB_SOURCES
lib/algo/kdtree.cpp
lib/algo/quickselect.cpp
lib/icp/icp.cpp
lib/icp/driver.cpp
lib/icp/geo.cpp
lib/icp/impl/vanilla.cpp
lib/icp/impl/trimmed.cpp
lib/icp/impl/feature_aware.cpp
)
add_library(cevicp STATIC ${LIB_SOURCES})
target_include_directories(cevicp
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/include
${EIGEN3_INCLUDE_DIRS}
)

# Main executable
set(MAIN_SOURCES
src/main.cpp
src/sim/lidar_view.cpp
src/sim/view_config.cpp
)
add_executable(main ${MAIN_SOURCES})
target_link_libraries(main
cevicp
SDL2::SDL2
libcmdapp.a
libsdlwrapper.a
libconfig.a
)
target_include_directories(main
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
${EIGEN3_INCLUDE_DIRS}
/usr/local/include/cmdapp
/usr/local/include/config
/usr/local/include/sdlwrapper
)

set(TEST_SOURCES tests/test.cpp)
add_executable(test_suite ${TEST_SOURCES})
target_link_libraries(test_suite
cevicp
)
target_include_directories(test_suite
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/include
/usr/local/include/simple_test
)
target_compile_definitions(test_suite PRIVATE TEST)

# Debug/Release configuration
if(CMAKE_BUILD_TYPE STREQUAL "Release")
target_compile_definitions(cevicp PRIVATE RELEASE_BUILD)
target_compile_options(cevicp PRIVATE -O3)
else()
target_compile_options(cevicp PRIVATE -g)
endif()

# Installation
install(TARGETS cevicp
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cev_icp
FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp"
)

# Per https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake
# uninstall target
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)

add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
9 changes: 5 additions & 4 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ If not, please read the instructions at [cornellev.github.io/icp/](https://corne

> **Warning**: these instructions must be followed from start whenever an update to the installation is desired.
1. Run `make libcevicp.a OPT=RELEASE` from the project root directory to build the static library `libcevicp.a`.
1. The project uses CMake, but there is a Makefile provided for convenience.
2. Run `sudo make install` to install the library.
You can specify the installation locations by passing the `LIB_INSTALL` and `HEADER_INSTALL` variables.
The default behavior is
Expand All @@ -16,13 +16,14 @@ If not, please read the instructions at [cornellev.github.io/icp/](https://corne
```
The library `libcevicp.a` will be located at `LIB_INSTALL`.
The header files will be accessible from `HEADER_INSTALL/cev_icp`, e.g., `HEADER_INSTALL/cev_icp/icp/icp.h`.
3. Run `sudo make uninstall` to remove the library.
You can similarly pass the `LIB_INSTALL` and `HEADER_INSTALL` variables, but they must be the same as where you installed.
2. Run `sudo make uninstall` to remove the library.
You can similarly pass the `LIB_INSTALL` and `HEADER_INSTALL`, but they must be the same as where you installed.
Note that uninstalling may leave some remanant directory structure.
## Local Installation (Static)
Follow the same instructions as above, but supply `LIB_INSTALL` and `HEADER_INSTALL` to be the desired local paths.
## Git Submodule
If you choose to include this as a git submodule, you must take care to only include the `lib` folder in your build path and only include the `include` folder in your include path.
If you choose to include this as a git submodule, you must take care to only include the `lib` folder in your build path and only include the `include` folder in your include path. It's much easier if your project uses CMake as well.
140 changes: 47 additions & 93 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,108 +1,62 @@
# Copyright (C) 2023 Ethan Uppal. All rights reserved.
INCLUDE_DIR := include
LIB_DIR := lib
SRC_DIR := src
TEST_DIR := tests

CC := $(shell which g++ || which clang++)
CFLAGS := -std=c++17 -pedantic -Wall -Wextra -I $(INCLUDE_DIR)
CDEBUG := -g
CRELEASE := -O3 -DRELEASE_BUILD
LIB_NAME := libcevicp.a
MAIN_NAME := main
TEST_NAME := test

ifeq ($(OPT), RELEASE)
CFLAGS += $(CRELEASE)
else
CFLAGS += $(CDEBUG)
endif

LIB_SRC := $(shell find $(LIB_DIR) -name "*.cpp" -type f)
LIB_INCLUDE := -I/usr/include/eigen3
LIB_OBJ := $(LIB_SRC:.cpp=.o)
LIB_DEPS := $(LIB_OBJ:.o=.d)
$(LIB_NAME): CFLAGS += $(LIB_INCLUDE)
BUILD_DIR := build
LIB_TARGET := cevicp
MAIN_TARGET := main
TEST_TARGET := test_suite

N := 1
METHOD := vanilla

OPT := Debug
LIB_INSTALL := /usr/local/lib
HEADER_INSTALL := /usr/local/include
INSTALL_NAME := cev_icp

MAIN_SRC := $(shell find $(SRC_DIR) -name "*.cpp" -type f)
MAIN_INCLUDE := $(shell sdl2-config --cflags) \
-I/usr/include/eigen3 \
-I/usr/local/include/cmdapp \
-I/usr/local/include/config \
-I/usr/local/include/sdlwrapper
MAIN_LD := $(shell sdl2-config --libs) \
/usr/local/lib/libcmdapp.a \
/usr/local/lib/libsdlwrapper.a \
/usr/local/lib/libconfig.a
MAIN_OBJ := $(MAIN_SRC:.cpp=.o)
MAIN_DEPS := $(MAIN_OBJ:.o=.d)
$(MAIN_NAME): CFLAGS += $(MAIN_INCLUDE)
$(MAIN_NAME): LDFLAGS += $(MAIN_LD)

TEST_SRC := $(shell find $(TEST_DIR) -name "*.cpp" -type f)
TEST_INCLUDE := -I/usr/include/eigen3 \
-I/usr/local/include/simple_test
TEST_OBJ := $(TEST_SRC:.cpp=.o)
TEST_DEPS := $(TEST_OBJ:.o=.d)
$(TEST_NAME): CFLAGS += $(TEST_INCLUDE)
$(TEST_NAME): CFLAGS += -DTEST

-include $(LIB_DEPS)
-include $(MAIN_DEPS)
-include $(TEST_DEPS)

N := 3
METHOD := feature_aware

ifeq ($(shell uname), Darwin)
AR := /usr/bin/libtool
AR_OPT := -static
else
AR := ar
AR_OPT := rcs $@ $^
endif

$(LIB_NAME): $(LIB_OBJ)
$(AR) $(AR_OPT) -o $@ $^

$(MAIN_NAME): $(MAIN_OBJ) $(LIB_NAME)
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@

$(TEST_NAME): $(TEST_OBJ) $(LIB_NAME)
@$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@
@./$(TEST_NAME)
@rm $(TEST_NAME)

%.o: %.cpp
@echo 'Compiling $@'
$(CC) $(CFLAGS) -MMD -MP $< -c -o $@
CMAKE_FLAGS := -DCMAKE_BUILD_TYPE=$(OPT) -DCMAKE_INSTALL_LIBDIR=$(LIB_INSTALL) -DCMAKE_INSTALL_INCLUDEDIR=$(HEADER_INSTALL)

.PHONY: clean
clean:
@rm -f $(LIB_OBJ) $(LIB_DEPS) $(LIB_NAME) $(MAIN_OBJ) $(MAIN_DEPS) $(MAIN_NAME) $(TEST_OBJ) $(TEST_DEPS) $(TEST_NAME)
MAKE_FLAGS := -j $(shell nproc)

.PHONY: view
view: $(MAIN_NAME)
./$(MAIN_NAME) -S ex_data/scan$(N)/first.conf -D ex_data/scan$(N)/second.conf --method $(METHOD) --gui
.PHONY: build_all
build_all: configure
cmake --build $(BUILD_DIR) -- $(MAKE_FLAGS)

.PHONY: configure
configure:
cmake -S . -B $(BUILD_DIR) $(CMAKE_FLAGS)

.PHONY: $(LIB_TARGET)
$(LIB_TARGET): configure
cmake --build $(BUILD_DIR) --target $(LIB_TARGET) -- $(MAKE_FLAGS)

.PHONY: $(MAIN_TARGET)
$(MAIN_TARGET): configure
cmake --build $(BUILD_DIR) --target $(MAIN_TARGET) -- $(MAKE_FLAGS)

.PHONY: $(TEST_TARGET)
$(TEST_TARGET): configure
cmake --build $(BUILD_DIR) --target $(TEST_TARGET) -- $(MAKE_FLAGS)

.PHONY: test
test: $(TEST_TARGET)
./$(BUILD_DIR)/$(TEST_TARGET)

.PHONY: view
view: $(MAIN_TARGET)
./$(BUILD_DIR)/$(MAIN_TARGET) -S ex_data/scan$(N)/first.conf -D ex_data/scan$(N)/second.conf --method $(METHOD) --gui

.PHONY: bench
bench: $(MAIN_NAME)
./$(MAIN_NAME) -S ex_data/scan$(N)/first.conf -D ex_data/scan$(N)/second.conf --method $(METHOD) --bench
bench: $(MAIN_TARGET)
./$(BUILD_DIR)/$(MAIN_TARGET) -S ex_data/scan$(N)/first.conf -D ex_data/scan$(N)/second.conf --method $(METHOD) --bench

.PHONY: clean
clean: configure
cmake --build $(BUILD_DIR) --target clean

.PHONY: install
install: $(LIB_NAME)
mkdir -p $(LIB_INSTALL)
mkdir -p $(HEADER_INSTALL)/$(INSTALL_NAME)
cp $(LIB_NAME) $(LIB_INSTALL)
cp -r $(INCLUDE_DIR)/* $(HEADER_INSTALL)/$(INSTALL_NAME)
install: configure $(LIB_TARGET)
cmake --install $(BUILD_DIR)

.PHONY: uninstall
uninstall:
rm -r $(LIB_INSTALL)/$(LIB_NAME) $(HEADER_INSTALL)/$(INSTALL_NAME)
uninstall: configure
cmake --build $(BUILD_DIR) --target uninstall

SCRIPT_DIR := script
RUN_SCRIPT := cd $(SCRIPT_DIR); uv venv; source .venv/bin/activate; uv sync; python3
Expand Down
22 changes: 22 additions & 0 deletions cmake_uninstall.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Per https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif()

file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
execute_process(
COMMAND "@CMAKE_COMMAND@" -E remove "$ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif()
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif()
endforeach()
Loading

0 comments on commit 222e830

Please sign in to comment.