Skip to content
This repository was archived by the owner on Apr 17, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 43 additions & 23 deletions cmake/Platform/Targets/ArduinoCMakeLibraryTarget.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,20 @@
#=============================================================================#
function(_set_library_flags _library_target _board_id)

set(scope_options "PRIVATE" "PUBLIC" "INTERFACE")
cmake_parse_arguments(parsed_args "${scope_options}" "" "" ${ARGN})

if (parsed_args_PRIVATE)
set(scope PRIVATE)
elseif (parsed_args_INTERFACE)
set(scope INTERFACE)
else ()
set(scope PUBLIC)
endif ()

# Set C++ compiler flags
get_cmake_compliant_language_name(cpp flags_language)
set_compiler_target_flags(${_library_target} "${_board_id}" PUBLIC LANGUAGE ${flags_language})
set_compiler_target_flags(${_library_target} "${_board_id}" ${scope} LANGUAGE ${flags_language})

# Set linker flags
set_linker_flags(${_library_target} "${_board_id}")
Expand All @@ -22,37 +33,45 @@ endfunction()
# _target_name - Name of the library target to be created. Usually library's real name.
# _board_id - Board ID associated with the linked Core Lib.
# _sources - Source and header files to create library target from.
# [ARCH] - Optional library architecture (Such as 'avr', 'nrf52', etc.)
# [ARCH] - Optional library architecture (Such as 'avr', 'nrf52', etc.).
# [INTERFACE] - Whether the library should be created as an interface library (header-only).
#=============================================================================#
function(_add_arduino_cmake_library _target_name _board_id _sources)

cmake_parse_arguments(library "" "ARCH" "" ${ARGN})
cmake_parse_arguments(parsed_args "INTERFACE" "ARCH" "" ${ARGN})

if (library_ARCH) # Treat architecture-specific libraries differently
if (parsed_args_ARCH) # Treat architecture-specific libraries differently
# Filter any sources that aren't supported by the platform's architecture
list(LENGTH library_ARCH num_of_libs_archs)
if (${num_of_libs_archs} GREATER 1)
# Exclude all unsupported architectures, request filter in regex mode
_get_unsupported_architectures("${library_ARCH}" arch_filter REGEX)
_get_unsupported_architectures("${parsed_args_ARCH}" arch_filter REGEX)
set(filter_type EXCLUDE)
else ()
set(arch_filter "src\\/[^/]+\\.|${library_ARCH}")
set(arch_filter "src\\/[^/]+\\.|${parsed_args_ARCH}")
set(filter_type INCLUDE)
endif ()
list(FILTER _sources ${filter_type} REGEX ${arch_filter})
endif ()

add_library(${_target_name} STATIC "${_sources}")
if (parsed_args_INTERFACE)
add_library(${_target_name} INTERFACE)
set(scope INTERFACE)
else ()
add_library(${_target_name} STATIC "${_sources}")
set(scope PUBLIC)
endif ()

# Treat headers' parent directories as include directories of the target
get_headers_parent_directories("${_sources}" include_dirs)
target_include_directories(${_target_name} PUBLIC ${include_dirs})
target_include_directories(${_target_name} ${scope} ${include_dirs})

_set_library_flags(${_target_name} ${_board_id})
_set_library_flags(${_target_name} ${_board_id} ${scope})

if (library_ARCH)
string(TOUPPER ${library_ARCH} upper_arch)
if (parsed_args_ARCH)
string(TOUPPER ${parsed_args_ARCH} upper_arch)
set(arch_definition "ARDUINO_ARCH_${upper_arch}")
target_compile_definitions(${_target_name} PUBLIC ${arch_definition})
target_compile_definitions(${_target_name} ${scope} ${arch_definition})
endif ()

endfunction()
Expand All @@ -76,6 +95,15 @@ function(_link_arduino_cmake_library _target_name _library_name)
set(scope_options "PRIVATE" "PUBLIC" "INTERFACE")
cmake_parse_arguments(link_library "${scope_options}" "BOARD_CORE_TARGET" "" ${ARGN})

# Now, link library to executable
if (link_library_PUBLIC)
set(scope PUBLIC)
elseif (link_library_INTERFACE)
set(scope INTERFACE)
else ()
set(scope PRIVATE)
endif ()

# First, include core lib's directories in library as well
if (link_library_BOARD_CORE_TARGET)
set(core_target ${link_library_BOARD_CORE_TARGET})
Expand All @@ -84,17 +112,9 @@ function(_link_arduino_cmake_library _target_name _library_name)
endif ()

get_target_property(core_lib_includes ${core_target} INCLUDE_DIRECTORIES)
target_include_directories(${_library_name} PUBLIC "${core_lib_includes}")
target_link_libraries(${_library_name} PUBLIC ${core_target})
target_include_directories(${_library_name} ${scope} "${core_lib_includes}")
target_link_libraries(${_library_name} ${scope} ${core_target})

# Now, link library to executable
if (link_library_PUBLIC)
set(scope PUBLIC)
elseif (link_library_INTERFACE)
set(scope INTERFACE)
else ()
set(scope PRIVATE)
endif ()
target_link_libraries(${_target_name} ${scope} ${_library_name})
target_link_libraries(${_target_name} PRIVATE ${_library_name})

endfunction()
52 changes: 41 additions & 11 deletions cmake/Platform/Targets/ArduinoLibraryTarget.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,15 @@ function(add_arduino_library _target_name _board_id _sources)

endfunction()

function(add_arduino_header_only_library _target_name _board_id)

cmake_parse_arguments(parsed_args "ARCH" "" "HEADERS" ${ARGN})

_add_arduino_cmake_library(${_target_name} ${_board_id} "${parsed_args_HEADERS}"
INTERFACE ${parsed_args_ARCH})

endfunction()

#=============================================================================#
# Finds an Arduino library with the given library name and creates a library target from it
# with the given target name.
Expand All @@ -95,12 +104,14 @@ endfunction()
# _library_name - Name of the Arduino library to find.
# _board_id - Board ID associated with the linked Core Lib.
# [3RD_PARTY] - Whether library should be treated as a 3rd Party library.
# [HEADER_ONLY] - Whether library is a header-only library, i.e has no source files
#=============================================================================#
function(find_arduino_library _target_name _library_name _board_id)

cmake_parse_arguments(find_lib "3RD_PARTY" "" "" ${ARGN})
set(argument_options "3RD_PARTY" "HEADER_ONLY")
cmake_parse_arguments(parsed_args "${argument_options}" "" "" ${ARGN})

if (NOT find_lib_3RD_PARTY)
if (NOT parsed_args_3RD_PARTY)
convert_string_to_pascal_case(${_library_name} _library_name)
endif ()

Expand Down Expand Up @@ -130,13 +141,23 @@ function(find_arduino_library _target_name _library_name _board_id)
set(error_message "Couldn't find any header files for the ${_library_name} library")
message(SEND_ERROR "${error_message}")
else ()
find_library_source_files("${library_path}" library_sources)
if (NOT library_sources)
set(error_message "Couldn't find any source files for the ${_library_name} library")
message(SEND_ERROR "${error_message}")
if (parsed_args_HEADER_ONLY)
add_arduino_header_only_library(${_target_name} ${_board_id}
ARCH ${lib_arch}
HEADERS ${library_headers})
else ()
set(sources ${library_headers} ${library_sources})
add_arduino_library(${_target_name} ${_board_id} "${sources}" ARCH ${lib_arch})
find_library_source_files("${library_path}" library_sources)
if (NOT library_sources)
string(CONCAT error_message
"Couldn't find any source files for the ${_library_name} library - "
"Is it a header-only library?\n"
"If so, please pass the HEADER_ONLY option as an argument to the function")
message(SEND_ERROR "${error_message}")
else ()
set(sources ${library_headers} ${library_sources})
add_arduino_library(${_target_name} ${_board_id} "${sources}"
ARCH ${lib_arch})
endif ()
endif ()
endif ()
endif ()
Expand All @@ -151,9 +172,12 @@ endfunction()
# _target_name - Name of the "executable" target.
# _library_target_name - Name of the library target.
# _board_id - Board ID associated with the linked Core Lib.
# [HEADER_ONLY] - Whether library is a header-only library, i.e has no source files
#=============================================================================#
function(link_arduino_library _target_name _library_target_name _board_id)

cmake_parse_arguments(parsed_args "HEADER_ONLY" "" "" ${ARGN})

get_core_lib_target_name(${_board_id} core_lib_target)

if (NOT TARGET ${_target_name})
Expand All @@ -164,8 +188,14 @@ function(link_arduino_library _target_name _library_target_name _board_id)
message(FATAL_ERROR "Core Library target doesn't exist. This is bad and should be reported")
endif ()

_link_arduino_cmake_library(${_target_name} ${_library_target_name}
PUBLIC
BOARD_CORE_TARGET ${core_lib_target})
if (parsed_args_HEADER_ONLY)
_link_arduino_cmake_library(${_target_name} ${_library_target_name}
INTERFACE
BOARD_CORE_TARGET ${core_lib_target})
else ()
_link_arduino_cmake_library(${_target_name} ${_library_target_name}
PUBLIC
BOARD_CORE_TARGET ${core_lib_target})
endif ()

endfunction()
14 changes: 14 additions & 0 deletions examples/3rd-party-library/3rd_party.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <Arduino.h>
#include "NeoPixelTest.hpp"
#include "GFXTest.h"

void setup()
{
testNeoPixel();
testGFX();
}

void loop()
{

}
14 changes: 10 additions & 4 deletions examples/3rd-party-library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@ cmake_minimum_required(VERSION 3.8.2)
project(3rd_Party_Arduino_Library)
get_board_id(board_id nano atmega328)

add_arduino_executable(3rd_Party_Arduino_Library ${board_id} NeoPixelTest.cpp GFXTest.cpp)
# First, declare and create our executable - It'll use 4 sources
add_arduino_executable(3rd_Party_Arduino_Library ${board_id} 3rd_party.cpp
NeoPixelTest.cpp GFXTest.cpp)
target_include_directories(3rd_Party_Arduino_Library PRIVATE include)

# Add the "NeoPixel" library manually using the library addition API
add_arduino_library(Adafruit_NeoPixel ${board_id} libraries/Adafruit_NeoPixel/Adafruit_NeoPixel.cpp)
target_include_directories(Adafruit_NeoPixel PUBLIC libraries/Adafruit_NeoPixel)

# 'Trick' the framework to use current directory as Sketchbook, allowing us to use the 'find' API
# Find the "GFX" library by 'tricking' the framework to use current directory as the Sketchbook path,
# allowing us to use the 'find' API
set(ARDUINO_CMAKE_SKETCHBOOK_PATH "${CMAKE_CURRENT_LIST_DIR}")
find_arduino_library(Adafruit_GFX Adafruit-GFX-Library ${board_id} 3RD_PARTY)
target_source_directories(Adafruit_GFX
DIRS libraries/Adafruit-GFX-Library/Fonts)
# We can also explicitly add additional directories to the target,
# as only root dir and 'src' sub-dir are added by default
target_source_directories(Adafruit_GFX DIRS libraries/Adafruit-GFX-Library/Fonts)

# Link all libraries to our previously created target
link_arduino_library(3rd_Party_Arduino_Library Adafruit_NeoPixel ${board_id})
link_arduino_library(3rd_Party_Arduino_Library Adafruit_GFX ${board_id})
2 changes: 1 addition & 1 deletion examples/3rd-party-library/GFXTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

static Adafruit_GFX_Button gfxButton;

void doSomething()
void testGFX()
{
gfxButton.isPressed();
}
14 changes: 5 additions & 9 deletions examples/3rd-party-library/NeoPixelTest.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
#include <Adafruit_NeoPixel.h>
#include "GFXTest.h"

#include <NeoPixelTest.hpp>

#include "include/NeoPixelTest.hpp"

Adafruit_NeoPixel neoPixel;

void setup()
void testNeoPixel()
{
neoPixel.clear();
doSomething();
}

void loop()
{

}
2 changes: 1 addition & 1 deletion examples/3rd-party-library/include/GFXTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@

#include <Adafruit_GFX.h>

void doSomething();
void testGFX();

#endif //EXAMPLES_GFXTEST_HPP
8 changes: 8 additions & 0 deletions examples/3rd-party-library/include/NeoPixelTest.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef EXAMPLES_NEOPIXELTEST_HPP
#define EXAMPLES_NEOPIXELTEST_HPP

#include <Adafruit_NeoPixel.h>

void testNeoPixel();

#endif //EXAMPLES_NEOPIXELTEST_HPP
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ project(Examples LANGUAGES C CXX ASM)
add_subdirectory(hello-world)
add_subdirectory(arduino-library)
add_subdirectory(3rd-party-library)
add_subdirectory(header-only-library)
add_subdirectory(blink-example)
add_subdirectory(servo-knob-example)
add_subdirectory(sketch)
13 changes: 13 additions & 0 deletions examples/header-only-library/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.8.2)

project(Header_Only_Lib)
get_board_id(board_id nano atmega328)

add_arduino_executable(Header_Only_Lib ${board_id} headerOnlyTest.cpp)

# Find the library by 'tricking' the framework to use current directory as the Sketchbook path,
# allowing us to use the 'find' API
set(ARDUINO_CMAKE_SKETCHBOOK_PATH "${CMAKE_CURRENT_LIST_DIR}")
find_arduino_library(headerTest test-lib ${board_id} 3RD_PARTY HEADER_ONLY)

link_arduino_library(Header_Only_Lib headerTest ${board_id} HEADER_ONLY)
18 changes: 18 additions & 0 deletions examples/header-only-library/headerOnlyTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <Arduino.h>
#include <TestLib.hpp>

void setup()
{
pinMode(BAR, OUTPUT);
}

void loop()
{
foo();
delayMicroseconds(SOME_DELAY);
}

void foo()
{
digitalWrite(BAR, HIGH);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=Test Library
version=0.1
author=Arduino-CMake-NG
maintainer=Arduino-CMake-NG <https://github.com/arduino-cmake/Arduino-CMake-NG>
sentence=Arduino library to test header-only feature support in the Arduino-CMake framework
paragraph=Arduino library to test header-only feature support in the Arduino-CMake framework
category=Display
url=https://github.com/arduino-cmake/Arduino-CMake-NG
architectures=*
11 changes: 11 additions & 0 deletions examples/header-only-library/libraries/test-lib/src/TestLib.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef EXAMPLES_TESTLIB_HPP
#define EXAMPLES_TESTLIB_HPP

#include <Arduino.h>

#define BAR 1
#define SOME_DELAY 200

void foo();

#endif //EXAMPLES_TESTLIB_HPP