I have a CMakelist.txt :
cmake_minimum_required(VERSION 3.12)
project(test)
set(TEST_HOME ${CMAKE_CURRENT_SOURCE_DIR})
message("test SDK home directory: " ${TEST_HOME})
set(a true)
list(APPEND plugins a)
set(b true)
list(APPEND plugins b)
set(c true)
list(APPEND plugins c)
add_executable(test main.c)
foreach(plugin IN LISTS plugins)
if(${${plugin}})
file(GLOB ${plugin}-SRC "${TEST_HOME}/plugins/${plugin}/src/*.c")
message(${${plugin}-SRC})
add_library(slt_${plugin} SHARED ${${plugin}-SRC})
message(${plugin})
target_link_libraries(test slt_${plugin}.so)
endif()
endforeach()
TLDR: I turn for create libraries and link them to my executable.
But my last library isn't created, the output of my Makefile generate by this CMakelist.txt is :
Scanning dependencies of target slt_c
[ 12%] Building C object CMakeFiles/slt_c.dir/plugins/c/src/c.c.o
[ 25%] Linking C shared library libslt_c.so
[ 25%] Built target slt_c
Scanning dependencies of target slt_b
[ 37%] Building C object CMakeFiles/slt_b.dir/plugins/b/src/b.c.o
[ 50%] Linking C shared library libslt_b.so
[ 50%] Built target slt_b
[ 62%] Linking C executable minko
/usr/bin/x86_64-linux-gnu-ld: cannot find -lslt_a
/usr/bin/x86_64-linux-gnu-ld: cannot find -lslt_b
/usr/bin/x86_64-linux-gnu-ld: cannot find -lslt_c
And when I turn a to false. It's be who don't build.
I really don't know what cause this, I just start CMAKE with some tests. Thank you.
Related
I have a project where I want to run cppcheck and clang-format using cmake when building the project.
Here is my code and the output. What am I missing? The output does not run either the cppcheck and clang-format. Both programs are on my path.
CMakeLists.txt:
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
# set your relative path to the gcc compiler
SET(CMAKE_C_COMPILER "gcc")
project(eec_cmocka_example VERSION 1.0 LANGUAGES C)
include(cmake/cppcheck.cmake)
include(cmake/clang-format.cmake)
include(cmake/FetchCMocka.cmake)
file(GLOB_RECURSE TEST_SRC_FILES unit-tests/*.c)
file(GLOB_RECURSE SRC_FILES src/*.c)
add_executable(eec_cmocka_example main.c ${SRC_FILES} ${TEST_SRC_FILES})
target_compile_features(eec_cmocka_example PRIVATE c_std_99)
target_link_libraries(eec_cmocka_example PRIVATE cmocka-static)
enable_testing()
add_test(NAME eec_cmocka_example COMMAND eec_cmocka_example)
set_property(TARGET eec_cmocka_example PROPERTY LINK_FLAGS "${DEFAULT_LINK_FLAGS} -Wl,\
--wrap=get_rx_dali_flag,\
--wrap=set_led_frequency,\
--wrap=application_process")
cppcheck.cmake:
file(GLOB_RECURSE ALL_SOURCE_FILES src/*.c src/*.h)
add_custom_target(
cppcheck
ALL
COMMAND /usr/bin/cppcheck
--enable=warning,performance,portability,information,missingInclude
--suppress=missingIncludeSystem
--std=c99
--library=std.cfg
--template="[{severity}][{id}] {message} {callstack} \(On {file}:{line}\)"
--verbose
--quiet
${ALL_SOURCE_FILES}
)
clang-format.cmake:
file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h)
add_custom_target(
clangformat
ALL
COMMAND /usr/bin/clang-format
-style=Microsoft
-i
${ALL_SOURCE_FILES}
)
Output:
arda#arda-VirtualBox:~/Desktop/eec/UnitTesting_example/build$ make clangformat
Built target clangformat
arda#arda-VirtualBox:~/Desktop/eec/UnitTesting_example/build$ make cppcheck
Built target cppcheck
arda#arda-VirtualBox:~/Desktop/eec/UnitTesting_example/build$ make
[ 0%] Built target cppcheck
[ 0%] Built target clangformat
Consolidate compiler generated dependencies of target cmocka-static
[ 22%] Built target cmocka-static
Consolidate compiler generated dependencies of target eec_cmocka_example
[ 77%] Built target eec_cmocka_example
Consolidate compiler generated dependencies of target cmocka
[100%] Built target cmocka
arda#arda-VirtualBox:~/Desktop/eec/UnitTesting_example/build$
Introduction
Using CMake, I am trying to build a library using a special make target. To this end, I use the EXCLUDE_FROM_ALL argument to ensure that the library is not built by running make (which defaults to make all). Unfortunately, the EXCLUDE_FROM_ALL option seems to be ignored by cmake.
Consider the following file tree:
.
├── CMakeLists.txt
├── foo
│ ├── CMakeLists.txt
│ ├── headers
│ │ └── foo.h
│ └── src
│ └── foo.cpp
└── src
└── main.cpp
4 directories, 5 files
In this file tree, you can see that I basically have two parts:
The foo library, for which all files are located in ./foo/.
The main executable, for which the source code is located in ./src/main.cpp.
Below, I will further explain these two parts and the behaviour I am observing.
The foo library
First of all, the header code located in ./foo/headers/foo.h is:
#ifndef _FOO_H_
#define _FOO_H_
#include <iostream>
void foo(void);
#endif // _FOO_H_
The corresponding source code, located in ./foo/src/foo.cpp, is:
#include "foo.h"
void foo(void) {
std::printf("Hello foo!\n");
}
As you can see, the foo library only contains the function foo(). This function simply prints Hello, foo! to the terminal. To build the foo library, I have the following CMakeLists.txt file defined (in ./foo/CMakeLists.txt):
cmake_minimum_required(VERSION 3.10)
project(foo
LANGUAGES CXX
)
# Create a foo library target
add_library(foo EXCLUDE_FROM_ALL
"src/foo.cpp"
)
target_include_directories(foo
PUBLIC "headers"
)
Note that I use the EXCLUDE_FROM_ALL argument in the add_library() function.
To test the behaviour of the EXCLUDE_FROM_ALL argument, I will now build the foo library as a stand-alone (using the previously shown CMakeLists.txt). Starting from the top directory (.), I use the following workflow:
$ cd foo
$ mkdir build
$ cd build
$ cmake ..
After this is finished, I run the make command:
$ make
(nothing happens)
As expected, nothing happens (since the foo library is excluded from the all target). Now, when I use make foo, I get the following output:
$ make foo
Scanning dependencies of target foo
[ 50%] Building CXX object CMakeFiles/foo.dir/src/foo.cpp.o
[100%] Linking CXX static library libfoo.a
[100%] Built target foo
So far, so good. Before moving on to building the main executable, I completely remove the ./foo/build directory and go back to the top-level directory:
$ cd ..
$ rm -rf build
$ cd ..
The main executable
The source code for the main executable is located in ./src/main.cpp:
#include "foo.h"
int main() {
foo();
return 0;
}
The top-level CMakeLists.txt contains:
cmake_minimum_required(VERSION 3.10)
project(TestProject
LANGUAGES CXX
)
# Include the foo library
add_subdirectory("foo" EXCLUDE_FROM_ALL)
# Create the main executable
add_executable(TestProject
"src/main.cpp"
)
target_link_libraries(TestProject
PRIVATE foo
)
Note that I again use the EXCLUDE_FROM_ALL argument, but now for the add_subdirectory() function.
To generate a makefile for the main executable, I use the following workflow:
$ mkdir build
$ cd build
$ cmake ..
When I now run make, I get the following output:
$ make
Scanning dependencies of target foo
[ 25%] Building CXX object foo/CMakeFiles/foo.dir/src/foo.cpp.o
[ 50%] Linking CXX static library libfoo.a
[ 50%] Built target foo
Scanning dependencies of target TestProject
[ 75%] Building CXX object CMakeFiles/TestProject.dir/src/main.cpp.o
[100%] Linking CXX executable TestProject
[100%] Built target TestProject
As you can see, it first builds the foo library. However, this is not what I expected! I explicitly stated to exclude the foo library from the all target. Hence, I would expect the need to first run make foo before running make.
This brings me to my main question(s): does someone know why it ignores the EXCLUDE_FROM_ALL option in the add_subdirectory() function in the top-level CMakeLists.txt? It did work when I built the foo library as a stand-alone. Is this a bug in cmake? If not, how do I achieve my expected behaviour (i.e. the need to run make foo before running make)?
This is not a bug. CMake does not include the foo lib in the all target directly. It does however add the foo target as dependency to TestProject and since TestProject is included in the all target, foo gets built too, if you build all.
This needs to be done this way. How else would you be able to link the foo function into TestProject?
If you want to use a lib that is not built as part of all, you need to use a imported lib. Doing this is and including the lib in the project seems a bit nonsensical though, but here you go.
add_library(foo STATIC EXCLUDE_FROM_ALL
"src/foo.cpp"
)
cmake_minimum_required(VERSION 3.10)
project(TestProject
LANGUAGES CXX
)
# Include the foo library
add_subdirectory("foo" EXCLUDE_FROM_ALL)
# Create the main executable
add_executable(TestProject
"src/main.cpp"
)
# add copy of foo as imported lib
add_library(foo_imported STATIC IMPORTED)
target_include_directories(foo_imported INTERFACE $<TARGET_PROPERTY:foo,INTERFACE_INCLUDE_DIRECTORIES>)
set_target_properties(foo_imported PROPERTIES IMPORTED_LOCATION $<TARGET_FILE:foo>)
target_link_libraries(TestProject
PRIVATE foo_imported
)
I'm trying to add ZipLip into my project using Clion on ubuntu, but I have this output:
====================[ Build | TryZip | Debug ]==================================
/home/david/Snap/clion-2019.2.4/bin/cmake/linux/bin/cmake --build
/home/david/CLionProjects/TryZip/cmake-build-debug --target TryZip -- -j 2
[ 13%] Built target bzip2
[ 31%] Built target zlib
[ 83%] Built target lzma
[ 95%] Built target ZipLib
Scanning dependencies of target TryZip
[ 97%] Linking CXX executable ../bin/TryZip
/usr/bin/ld: cannot find -lExternalLibrary/ZipLib
collect2: error: ld returned 1 exit status
CMakeFiles/TryZip.dir/build.make:102: recipe for target '../bin/TryZip' failed
make[3]: *** [../bin/TryZip] Error 1
CMakeFiles/Makefile2:109: recipe for target 'CMakeFiles/TryZip.dir/all' failed
make[2]: *** [CMakeFiles/TryZip.dir/all] Error 2
CMakeFiles/Makefile2:116: recipe for target 'CMakeFiles/TryZip.dir/rule' failed
make[1]: *** [CMakeFiles/TryZip.dir/rule] Error 2
Makefile:131: recipe for target 'TryZip' failed
make: *** [TryZip] Error 2
This is my Cmakefile.txt
cmake_minimum_required(VERSION 3.15)
project(TryZip)
if(BOOST_FILESYSTEM)
include_directories(${BOOST_INCLUDE_DIR})
link_directories(${BOOST_LIB_DIR})
add_definitions(-DUSE_BOOST_FILESYSTEM)
else()
if(MSVC)
add_definitions(-DFILESYSTEM_EXPERIMENTAL)
endif()
endif()
if(BOOST_FILESYSTEM)
if(UNIX)
find_package(Boost COMPONENTS system filesystem REQUIRED)
target_link_libraries(${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY})
endif()
endif()
add_subdirectory(ExternalLibrary/ZipLib)
link_libraries(ExternalLibrary/ZipLib)
include_directories(ExternalLibrary/ZipLib)
set(CMAKE_CXX_STANDARD 17)
add_executable(TryZip main.cpp ExternalLibrary/ZipLib/ZipFile.cpp)
target_link_libraries(TryZip ZipLib)
Can someone help me to solve this please?
My ZipLib folder is in the same folder as my cmakefile.txt file.
The call to link_libraries() appears to accept the wrong arguments in this case. The link_libraries() command takes arguments of existing CMake targets, or library names. It is also redundant with your target_link_libraries() call, as this already links ZipLib to TryZip.
Try removing the call to link_libraries(), as this CMake function is deprecated and its use is highly discouraged. The include_directories() call is similarly deprecated, in favor of the target-specific command, so consider using target_include_directories() instead.
Assuming your added sub-directory ExternalLibrary/ZipLib contains an additional CMakeLists.txt file for configuring the ZipLib target, you should not need to add the ZipFile.cpp file again. If this file is already compiled in the sub-directory into the target ZipLib, you do not need to compile it again into TryZip.
add_subdirectory(ExternalLibrary/ZipLib)
set(CMAKE_CXX_STANDARD 17)
add_executable(TryZip main.cpp)
target_include_directories(TryZip PRIVATE ExternalLibrary/ZipLib)
target_link_libraries(TryZip PRIVATE ZipLib)
EDIT: Based on your feedback, it appears ZipLib also depends on pthread but somehow it is not getting linked correctly. You might try to add the following to your ExternalLibrary/ZipLib/CMakeLists.txt file (if it doesn't already exist), to utilize CMake's FindThreads module:
find_package(Threads REQUIRED)
...
target_link_libraries(ZipLib PUBLIC Threads::Threads)
I would like to generate pkgconfig files in cmake from the targets. I started by writing something like this:
function(auto_pkgconfig TARGET)
get_target_property(INCLUDE_DIRS ${TARGET} INTERFACE_INCLUDE_DIRECTORIES)
string(REPLACE "$<BUILD_INTERFACE:" "$<0:" INCLUDE_DIRS "${INCLUDE_DIRS}")
string(REPLACE "$<INSTALL_INTERFACE:" "$<1:" INCLUDE_DIRS "${INCLUDE_DIRS}")
string(REPLACE "$<INSTALL_PREFIX>" "${CMAKE_INSTALL_PREFIX}" INCLUDE_DIRS "${INCLUDE_DIRS}")
file(GENERATE OUTPUT ${TARGET}.pc CONTENT "
Name: ${TARGET}
Cflags: -I$<JOIN:${INCLUDE_DIRS}, -I>
Libs: -L${CMAKE_INSTALL_PREFIX}/lib -l${TARGET}
")
install(FILES ${TARGET}.pc DESTINATION lib/pkgconfig)
endfunction()
This is a simplified version but it basically reads the INTERFACE_INCLUDE_DIRECTORIES properties and processes the INSTALL_INTERFACE of the generator expressions.
This works well as long as the include directories are set before calling auto_pkgconfig, like this:
add_library(foo foo.cpp)
target_include_directories(foo PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
${OTHER_INCLUDE_DIRS}
)
auto_pkgconfig(foo)
However, sometimes properties are set after the call to auto_pkgconfig, like this:
add_library(foo foo.cpp)
auto_pkgconfig(foo)
target_include_directories(foo PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>
${OTHER_INCLUDE_DIRS}
)
However, this won't properly read the include directories anymore. I would like auto_pkgconfig to run after all the target properties are set. I could use generator expressions for this, by changing auto_pkgconfig to this:
function(auto_pkgconfig TARGET)
file(GENERATE OUTPUT ${TARGET}.pc CONTENT "
Name: ${TARGET}
Cflags: -I$<JOIN:$<TARGET_PROPERTY:${TARGET},INTERFACE_INCLUDE_DIRECTORIES>, -I>
Libs: -L$<TARGET_FILE_DIR:${TARGET}> -l${TARGET}
")
install(FILES ${TARGET}.pc DESTINATION lib/pkgconfig)
endfunction()
However, this will read the BUILD_INTERFACE instead of the INSTALL_INTERFACE. So is there another way to read target properties after they have been set?
According to the CMake documentation, the contents of INSTALL_INTERFACE are only available when calling install(EXPORT). Unless they extend CMake, it will be best to do something else to generate your PkgConfig files. Ideally you would have enough control over your install layout to make this easy.
However, this doesn't mean you can't do what you ask; it's just "Tony the Pony" levels of evil. I actually hesitated to post this. Please don't take this as a recommendation.
The idea is to use install(EXPORT) to have CMake generate the appropriate scripts. Then generate a dummy CMake project that uses the file(GENERATE OUTPUT ...) code you gave above; the dummy project will see the exported, ie. INSTALL_INTERFACE properties.
I initially tried to use install(CODE [[ ... ]]) to do this, but it also sees the $<BUILD_INTERFACE:...> view. I've asked about this on the CMake Discourse.
cmake_minimum_required(VERSION 3.16)
project(example)
# Dummy library for demo
add_library(example SHARED example.cpp)
target_compile_definitions(example
PUBLIC $<BUILD_INTERFACE:BUILD>
$<INSTALL_INTERFACE:INSTALL>)
target_include_directories(example
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include>)
# Here be dragons...
function(auto_pc TARGET)
file(CONFIGURE OUTPUT "pc.${TARGET}/CMakeLists.txt"
CONTENT [[
cmake_minimum_required(VERSION 3.16)
project(pc_#TARGET#)
find_package(pc_#TARGET# REQUIRED CONFIG)
file(GENERATE OUTPUT #TARGET#.pc
CONTENT [=[
Name: #TARGET#
Cflags: -I$<JOIN:$<TARGET_PROPERTY:INTERFACE_INCLUDE_DIRECTORIES>, -I> -D$<JOIN:$<TARGET_PROPERTY:INTERFACE_COMPILE_DEFINITIONS>, -D>
Libs: -L$<TARGET_FILE_DIR:#TARGET#> -l#TARGET#
]=] TARGET "#TARGET#")
]] #ONLY NEWLINE_STYLE LF)
install(TARGETS ${TARGET} EXPORT pc_${TARGET})
install(EXPORT pc_${TARGET} DESTINATION "_auto_pc" FILE pc_${TARGET}-config.cmake)
file(CONFIGURE OUTPUT "pc.${TARGET}/post-install.cmake"
CONTENT [[
file(REAL_PATH "${CMAKE_INSTALL_PREFIX}" prefix)
set(proj "#CMAKE_CURRENT_BINARY_DIR#/pc.#TARGET#")
execute_process(COMMAND "#CMAKE_COMMAND#" "-Dpc_#TARGET#_DIR=${prefix}/_auto_pc" -S "${proj}" -B "${proj}/build")
file(COPY "${proj}/build/#TARGET#.pc" DESTINATION "${prefix}")
]] #ONLY NEWLINE_STYLE LF)
install(SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/pc.${TARGET}/post-install.cmake")
endfunction()
auto_pc(example)
# Clean up install path
install(CODE [[ file(REMOVE_RECURSE "${CMAKE_INSTALL_PREFIX}/_auto_pc") ]])
This results in the following:
alex#Alex-Desktop:~/test$ cmake -S . -B build
...
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
alex#Alex-Desktop:~/test$ cmake --build build/
...
alex#Alex-Desktop:~/test$ cmake --install build --prefix install
-- Install configuration: ""
-- Installing: /home/alex/test/install/lib/libexample.so
-- Installing: /home/alex/test/install/_auto_pc/pc_example-config.cmake
-- Installing: /home/alex/test/install/_auto_pc/pc_example-config-noconfig.cmake
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build/pc.example/build
alex#Alex-Desktop:~/test$ ls install/
example.pc lib
alex#Alex-Desktop:~/test$ cat install/example.pc
Name: example
Cflags: -I/home/alex/test/install/include -DINSTALL
Libs: -L/home/alex/test/install/lib -lexample
This should make you sad. It makes me sad.
edit: off topic, since here, the pc files are generated manually
pkgconfig template files
motivation:
CMakeLists.txt should be the single source of truth (name, version)
pkgconfig files are about 10 times smaller than cmake files (cmake to pkgconfig is a lossy transformation)
template file: my_package.pc.in
prefix="#CMAKE_INSTALL_PREFIX#"
exec_prefix="${prefix}"
libdir="${prefix}/lib"
includedir="${prefix}/include"
Name: #PROJECT_NAME#
Description: #CMAKE_PROJECT_DESCRIPTION#
Version: #PROJECT_VERSION#
Cflags: -I${includedir}
Libs: -L${libdir} -l#target1#
CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(my_library VERSION 1.1.2 LANGUAGES C
DESCRIPTION "example library")
add_library(my_library src/my_library.c)
# generate pc file for pkg-config
set(target1 my_library)
configure_file(my_package.pc.in
lib/pkgconfig/my_package.pc #ONLY)
based on: CMake generate pkg-config .pc
related: exporting targets to cmake files
Here's the relevant part of my project structure
iNode
├── CMakeLists.txt
├── src
| └──iNode.c
├── include
| └──iNode.h
└── test
└──tests.cpp
cmake can't find function definitions from iNode.c
I don't know why they don't get added when I add_library
I've tried several permutations of linking libraries
cmake_minimum_required (VERSION 2.8)
project(iNode)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Wshadow -Wpedantic -D_XOPEN_SOURCE=700")
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -Wshadow -Werror -g -D_XOPEN_SOURCE=700")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 -g")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} -g")
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif()
include_directories(${f16fs_INCLUDE_DIRS} ${dyn_array_INCLUDE_DIRS} include)
add_library(${PROJECT_NAME} SHARED src/${PROJECT_NAME}.c)
set_target_properties(${PROJECT_NAME} PROPERTIES POSITION_INDEPENDENT_CODE ON)
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
install(FILES include/${PROJECT_NAME}.h DESTINATION include)
add_executable(${PROJECT_NAME}_test test/tests.cpp)
target_link_libraries(${PROJECT_NAME}_test gtest pthread ${PROJECT_NAME})
set(${PROJECT_NAME}_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include CACHE INTERNAL "${PROJECT_NAME}: Include Directories" FORCE)
The error
$ make
-- Configuring done
-- Generating done
-- Build files have been written to: /home/syg84/project3_syg84/build
[ 10%] Built target dyn_array_tester
[ 20%] Built target dyn_array
[ 30%] Built target bitmap_tester
[ 40%] Built target bitmap
[ 50%] Built target block_store
[ 60%] Built target block_store_test
[ 70%] Built target iNode
[ 80%] Built target f16fs
[ 90%] Built target f16fs_test
Scanning dependencies of target iNode_test
[ 95%] Linking CXX executable iNode_test
CMakeFiles/iNode_test.dir/test/tests.cpp.o: In function `getDirectoryContents_rootDirectory_Test::TestBody()':
/home/syg84/project3_syg84/iNode/test/tests.cpp:6: undefined reference to `createNewINodeArray(unsigned long)'
/home/syg84/project3_syg84/iNode/test/tests.cpp:8: undefined reference to `getDirectoryContents(iNode**, unsigned char)'
/home/syg84/project3_syg84/iNode/test/tests.cpp:10: undefined reference to `destroyINodeArray(iNode**, unsigned long)'
collect2: error: ld returned 1 exit status
make[2]: *** [iNode/iNode_test] Error 1
make[1]: *** [iNode/CMakeFiles/iNode_test.dir/all] Error 2
make: *** [all] Error 2