I'm developing a build system using CMake to build applications using the arm-none-eabi toolchain.
This is my folder structure:
project/
├── apps/
│ ├── test_app
│ │ ├── inc/
│ │ ├── src/
│ │ ├── CMakeLists.txt
├── arch/
│ ├── CMSIS/
│ ├── include/
│ ├── startup/
│ ├── CMakeLists.txt
├── cmake/
│ ├── toolchain-samd51.cmake
├── CMakeLists.txt
This is my top level CMakeLists.txt:
cmake_minimum_required(VERSION 3.17)
project(SMALL-FW LANGUAGES C)
add_subdirectory(arch)
add_subdirectory(apps/test_app)
This is the toolchain cmake file:
# Set target architecture
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
# Set compiler to use
set(CMAKE_C_COMPILER "arm-none-eabi-gcc")
#set(CMAKE_LINKER "arm-none-eabi-ld")
# Clear default compiler and linker flags.
set(CMAKE_C_FLAGS "")
set(CMAKE_C_LINK_FLAGS "")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# FIX - Bypass compiler check
set(CMAKE_C_COMPILER_FORCED TRUE)
# Define common compiler and linker flags
set(ARM_OPTIONS
-mthumb
-mabi=aapcs-linux
-mcpu=cortex-m4
-mfpu=fpv4-sp-d16
-mfloat-abi=softfp
--specs=nano.specs
-mlong-calls
-DSAMD51
)
# Define compiler specific flags
add_compile_options(
${ARM_OPTIONS}
-D__SAMD51J19A__
-ffunction-sections
-Wall
)
# Define linker specific flags
add_link_options(
${ARM_OPTIONS}
#--specs=nano.specs
LINKER:--gc-sections
)
This is the CMakeList.txt inside the arch folder:
add_library(asf OBJECT
startup/startup_samd51.c
startup/system_samd51.c
)
# Every target that links against asf needs to know where the ASF headers are.
target_include_directories(asf PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/CMSIS/Include
${CMAKE_CURRENT_SOURCE_DIR}/include
)
# Use the custom linker script provided with ASF.
target_link_options(asf PUBLIC
-T${CMAKE_CURRENT_SOURCE_DIR}/startup/samd51j19a_flash.ld
)
And this is the app CMakeLists.txt:
add_executable(APP)
target_sources(APP PRIVATE src/main.c src/module.c)
target_include_directories(APP PRIVATE inc/)
target_link_libraries(APP asf)
CMake is running fine when the CMAKE_C_COMPILER_FORCED options is set to true, but when I try to make the project it fails with multiple undefined references errors like the next one:
/build/arm-none-eabi-newlib/src/build-nano/arm-none-eabi/thumb/v7e-m+fp/softfp/newlib/libc/reent/../../../../../../../../newlib-4.2.0.20211231/newlib/libc/reent/sbrkr.c:51: undefined reference to _sbrk'`
I have tried using nosys.specs flag but similar errors occurs.
Try this, it looks like typo
# Define linker specific flags
add_link_options(
${ARM_OPTIONS}
--specs=nano.specs
--gc-sections
)
I have a big project containing multiple projects that create library/executables and some even a python module using a library.
To keep it simple, I have an MWE included called myprogram that creates an executable and a shared library for use by Cython code to create a python package for that same code. I use CMake to compile the code but due to my setup, as detailed here, the build process of the python routine is executed twice (during build and install).
During build the output is:
Scanning dependencies of target pymyprogram
[ 80%] Generating build/timestamp
Compiling /builds/myprogram/src/myprogram/pymyprogram.pyx because it changed.
[1/1] Cythonizing /builds/myprogram/src/myprogram/pymyprogram.pyx
running build_ext
building 'pymyprogram' extension
creating build
creating build/temp.linux-x86_64-3.8
creating build/temp.linux-x86_64-3.8/builds
creating build/temp.linux-x86_64-3.8/builds/myprogram
creating build/temp.linux-x86_64-3.8/builds/myprogram/src
creating build/temp.linux-x86_64-3.8/builds/myprogram/src/myprogram
gcc -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -I/opt/rh/rh-python38/root/usr/include -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -I/opt/rh/rh-python38/root/usr/include -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/builds/myprogram/src/myprogram -I/builds/myprogram/include -I/builds/myprogram/buildRelease -I/opt/rh/rh-python38/root/usr/include/python3.8 -c /builds/myprogram/src/myprogram/pymyprogram.c -o build/temp.linux-x86_64-3.8/builds/myprogram/src/myprogram/pymyprogram.o
creating build/lib.linux-x86_64-3.8
gcc -pthread -shared -L/opt/rh/rh-python38/root/usr/lib64-Wl,-z,relro -Wl,-rpath,/opt/rh/rh-python38/root/usr/lib64 -Wl,--enable-new-dtags -g -L/opt/rh/rh-python38/root/usr/lib64-Wl,-z,relro -Wl,-rpath,/opt/rh/rh-python38/root/usr/lib64 -Wl,--enable-new-dtags -g build/temp.linux-x86_64-3.8/builds/myprogram/src/myprogram/pymyprogram.o -L/builds/myprogram/buildRelease/src/myprogram -L/opt/rh/rh-python38/root/usr/lib64 -lmyprogram -o build/lib.linux-x86_64-3.8/pymyprogram.cpython-38-x86_64-linux-gnu.so -Wl,-rpath=/builds/myprogram/lib/
[ 80%] Built target pymyprogram
And during install:
-- Installing: /builds/myprogram/bin/myprogram.x
running install
running build
running build_ext
building 'pymyprogram' extension
creating build
creating build/temp.linux-x86_64-3.8
creating build/temp.linux-x86_64-3.8/builds
creating build/temp.linux-x86_64-3.8/builds/myprogram
creating build/temp.linux-x86_64-3.8/builds/myprogram/src
creating build/temp.linux-x86_64-3.8/builds/myprogram/src/myprogram
gcc -Wno-unused-result -Wsign-compare -DNDEBUG -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -I/opt/rh/rh-python38/root/usr/include -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -I/opt/rh/rh-python38/root/usr/include -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -D_GNU_SOURCE -fPIC -fwrapv -fPIC -I/builds/myprogram/src/myprogram -I/builds/myprogram/include -I/builds/myprogram/buildRelease -I/opt/rh/rh-python38/root/usr/include/python3.8 -c /builds/myprogram/src/myprogram/pymyprogram.c -o build/temp.linux-x86_64-3.8/builds/myprogram/src/myprogram/pymyprogram.o
creating build/lib.linux-x86_64-3.8
gcc -pthread -shared -L/opt/rh/rh-python38/root/usr/lib64-Wl,-z,relro -Wl,-rpath,/opt/rh/rh-python38/root/usr/lib64 -Wl,--enable-new-dtags -g -L/opt/rh/rh-python38/root/usr/lib64-Wl,-z,relro -Wl,-rpath,/opt/rh/rh-python38/root/usr/lib64 -Wl,--enable-new-dtags -g build/temp.linux-x86_64-3.8/builds/myprogram/src/myprogram/pymyprogram.o -L/builds/myprogram/buildRelease/src/myprogram -L/opt/rh/rh-python38/root/usr/lib64 -lmyprogram -o build/lib.linux-x86_64-3.8/pymyprogram.cpython-38-x86_64-linux-gnu.so -Wl,-rpath=/builds/myprogram/lib/
running install_lib
creating /builds/myprogram/lib64
creating /builds/myprogram/lib64/python3.8
creating /builds/myprogram/lib64/python3.8/site-packages
copying build/lib.linux-x86_64-3.8/pymyprogram.cpython-38-x86_64-linux-gnu.so -> /builds/program/lib/python3.8/site-packages
running install_egg_info
Writing /builds/myprogram/lib/python3.8/site-packages/pymyprogram-1.1A-py3.8.egg-info
Also when I make changes to otherprogram.c but no changes to myprogram in either the library of pyx code, at install stage the library is build anyway which increases compilation time.
I therefore searched for a solution and found the method from PJ_Finnegan but have a few issues so wondered whether others have resolved that or could help out.
My working tree for the MWE is:
.
├── README.TXT
├── README.md
├── bin
├── CMakeLists.txt
├── buildDebug
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── Makefile
│ ├── cmake_install.cmake
│ ├── install_manifest.txt
│ ├── src
│ └── utils
├── include
│ ├── version.h
│ └── version.h.txt
├── lib
│ └── libmyprogram.dylib
├─── src
│ ├── some other myprogram
│ │ ├── CMakeLists.txt
│ │ ├── othermyprogram.h
│ │ ├── othermyprogram.c
│ ├── myprogram
│ │ ├── CMakeLists.txt
│ │ ├── myprogram.h
│ │ ├── myprogram.c
│ │ ├── myprogram.pyx
│ │ ├── setup.py.in
│ └── versioning.cmake
The top level CMakeLists.txt contains add_subdirectory(src/myprogram) and the content of the CMakeLists.txt in src/myprograms is:
cmake_minimum_required(VERSION 2.8.8...3.20.5 FATAL_ERROR)
project (myprogram)
message ("-- Configuring: *** myprogram **")
if(APPLE)
set(CMAKE_MACOSX_RPATH 1)
endif()
set(CMAKE_C_FLAGS "${CFLAGS} -O0 -ggdb -fPIC")
set(CMAKE_C_FLAGS_DEBUG "${CFLAGS} -O0 -ggdb -fPIC")
set(CMAKE_C_FLAGS_RELEASE "${CFLAGS} -O3 -fPIC")
set(CMAKE_CXX_FLAGS "${CFLAGS} -O0 -ggdb")
set(CMAKE_CXX_FLAGS_DEBUG "${CFLAGS} -O0 -ggdb")
set(CMAKE_CXX_FLAGS_RELEASE "${CFLAGS} -O3")
# *** myprogram.so ***
SET(libmyprogram_SRCS
myprogram.c
)
ADD_LIBRARY(myprogram SHARED
${libmyprogram_SRCS}
)
ADD_DEPENDENCIES(myprogram versioning)
TARGET_LINK_LIBRARIES(myprogram
m
)
install(TARGETS myprogram
DESTINATION "lib")
if (APPLE)
install(CODE "execute_process(COMMAND ln -sf ${PROJECT_HOME}/lib/libmyprogram.dylib /usr/local/lib/libmyprogram.dylib)")
endif()
# *** myprogram.x ***
SET(myprogram_SRCS
myprogram.c
)
ADD_EXECUTABLE(myprogram.x
${myprogram_SRCS}
)
ADD_DEPENDENCIES(myprogram.x myprogram versioning)
TARGET_LINK_LIBRARIES(myprogram.x
m
)
set (EXECUTABLES "${EXECUTABLES}" myprogram.x)
# install executables and scripts
install (TARGETS ${EXECUTABLES}
RUNTIME DESTINATION "bin")
# *** pymyprogram.pyx ***
find_package(PythonInterp 3 REQUIRED)
if (CMAKE_BUILD_TYPE MATCHES "Debug")
message(STATUS "Python: version=${PYTHON_VERSION_STRING} interpreter=${PYTHON_EXECUTABLE}")
set(PYTHON_BUILD_FLAGS "--debug")
endif()
# Get location of user site-packages to install libs to
execute_process(COMMAND python3 -m site --user-site OUTPUT_VARIABLE PYTHON_INSTALL_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
if (PYTHONINTERP_FOUND)
set(SETUP_PY_IN "${CMAKE_CURRENT_SOURCE_DIR}/setup.py.in")
set(SETUP_PY "${CMAKE_CURRENT_BINARY_DIR}/setup.py")
set(DEPS "${CMAKE_CURRENT_SOURCE_DIR}/pymyprogram.pyx")
set(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/timestamp")
message ("-- Building Python Extension using: " ${PYTHON_EXECUTABLE})
configure_file(${SETUP_PY_IN} ${SETUP_PY})
add_custom_command(OUTPUT ${OUTPUT}
COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} build ${PYTHON_BUILD_FLAGS} --build-lib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}
COMMAND ${CMAKE_COMMAND} -E touch ${OUTPUT}
DEPENDS ${DEPS})
add_custom_target(pymyprogram ALL DEPENDS ${OUTPUT})
add_dependencies(pymyprogram myprogram versioning)
install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} install_lib --skip-build
--build-dir ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}
--install-dir=${PYTHON_INSTALL_DIR} --force
COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} install_egg_info
--install-dir=${PYTHON_INSTALL_DIR})" DEPENDS ${DEPS})
else()
message (WARNING "-- Could not build *** pymyprogram **, could not locate PYTHON: ${PYTHON_EXECUTABLE} or improper version")
endif()
And the setup.py.in that is used:
import os, sys
from distutils.core import setup, Extension
from Cython.Build import cythonize
link_arguments = []
if (sys.platform == 'darwin'):
link_arguments.append("-Wl,-rpath")
link_arguments.append("-Wl,#loader_path/")
os.environ["CC"] = "gcc"
else:
link_arguments.append("-Wl,-rpath=${CMAKE_SOURCE_DIR}/lib/")
myprogram_extension = Extension(
name="pymyprogram",
sources=["${CMAKE_CURRENT_SOURCE_DIR}/pymyprogram.pyx"],
libraries=["myprogram"],
extra_link_args = link_arguments,
library_dirs=["${PROJECT_BINARY_DIR}"],
include_dirs=["${CMAKE_SOURCE_DIR}/include", "${CMAKE_SOURCE_DIR}/build${CMAKE_BUILD_TYPE}"],
)
setup(name="pymyprogram",
author="My Name",
author_email="my-email",
version="1.1A",
description="Python wrapper for myprogram",
package_dir={ "": "${CMAKE_SOURCE_DIR}/lib/" },
license="MIT License",
ext_modules=cythonize([myprogram_extension], compiler_directives={'language_level' : "3"})
)
The code runs on different machines (Linux or macOS) and my module was previously build and installed using this method and either the --user or --prefix of the install command based on whether the code ran on Linux or macOS.
To avoid the double build step of the python module, I implemented a new method from PJ_Finnegan as mentioned above and shown in the code sample of my CMakeLists.txt. This method uses install_lib, to avoid the second build which allows the use of --build-dir which is great but no longer works with --user or --prefix which is unwanted as it will require me to define the path manually and that the path no longer depends on the python version automatically.
I also wonder what the difference between using install-lib vs install entails. I noticed no egg-info file being created, is this a problem? I therefore added the install_egg_info step as well.
Also, the the mypogram code is build twice, (the executable and library), and a third time for the python package. Is there some optimisation possible to reduce compile time?
Any other ways to build and install a python/Cython extension and separate standalone executable and help the install step find the build code? Perhaps using sdist and pip install?
EDIT
I've changed the INSTALL command in my CMAKE files to:
install(CODE "execute_process(COMMAND ${PYTHON_EXECUTABLE} ${SETUP_PY} install ${PYTHON_INSTALL_PREFIX} --skip-build --force WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})")
This reduces the install step to only installation and no more build as the build directory from the previous build step is now found.
Now the question remains, how to make the CMAKE install command not run every time and only upon changes in the *.pyx file. I know add_custom_target is always considered out-of-date so is there perhaps a workaround?
Here i am creating a project . i am using cmake . i am not able to link cmake created shared library with my main application ??? My CMakeLists.txt file are as follows :
//tree -stucture of my project
├── CMakeLists.txt
├── include
│ ├── Account.h
│ ├── bankingSystem.h
│ ├── bankStruct.h
│ └── stdheader.h
├── main.cpp
└── src
├── Account.cpp
├── bankingSystem.cpp
└── main.cpp
//CMakeLists.txt
cmake_minimum_required(VERSION 3.17.1)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++11 -DPC_BUILD")
include_directories(
./include
)
link_directories(
/usr/local/lib)
#create a shared library to be linked with test application
add_library(
BANK SHARED
src/bankingSystem.cpp
src/Account.cpp
)
add_executable(
main main.cpp
)
message("BANK")
But i am getting Undefined Reference :
[ 60%] Built target BANK
[ 80%] Linking CXX executable main
CMakeFiles/main.dir/main.cpp.o: In function `main':
/home/pankaj/BANK/main.cpp:8: undefined reference to `BankingSystem::BankingSystem()'
/home/pankaj/BANK/main.cpp:19: undefined reference to `BankingSystem::Create_new_Account()'
...
collect2: error: ld returned 1 exit status
CMakeFiles/main.dir/build.make:103: recipe for target 'main' failed
make[2]: *** [main] Error 1
CMakeFiles/Makefile2:124: recipe for target 'CMakeFiles/main.dir/all' failed
make[1]: *** [CMakeFiles/main.dir/all] Error 2
Makefile:103: recipe for target 'all' failed
make: *** [all] Error 2
in my project I am using the header only library rapidjson v1.1.0.
└── my_project
├── CMakeLists.txt
├── src
│
├── 3rdParty/tiny_dnn (header only)
│ ├── CMakeLists.txt
│ ├── src
│ └── rapidjson_v0.2
│
└── rapidjson_v1.1.0
The problem is now that tiny-dnn has also included rapidjson (but an older version), so while i try to include tiny_dnn in the main CMakeLists.txt like include_directories(${PROJECT_SOURCE_DIR}/3rdParty/tiny_dnn) some conflicts arise from either tiny-dnn searches mine rapidjson or my project searches in tiny-dnn's rapidjson.
my_project CMakeLists.txt
cmake_minimum_required(VERSION 3.9)
project(my_project)
# check the build type and set compiler and linker flags
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE)
IF(CMAKE_BUILD_TYPE MATCHES DEBUG)
message("Debug build")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unknown-pragmas -g -O0 -std=c++17 -Ddeveloper_build")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIC -g -O0")
ELSEIF(CMAKE_BUILD_TYPE MATCHES RELEASE)
message("Release build")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unknown-pragmas -O3 -std=c++17")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -O3")
ELSE()
message(FATAL_ERROR "No build type specified")
ENDIF()
find_package(Boost COMPONENTS system filesystem REQUIRED)
include_directories(${Boost_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/3rdParty/tiny-dnn)
file(GLOB_RECURSE SOURCE_FILES src/*.cpp src/*.c)
set(SOURCE_FILES
${SOURCE_FILES})
add_executable(my_project ${SOURCE_FILES})
target_link_libraries(my_project ${Boost_LIBRARIES} pthread)
set_target_properties(my_project PROPERTIES SUFFIX ${CMAKE_BUILD_TYPE})
my_project.cpp
#include <tiny_dnn/tiny_dnn.h>
#include <rapidjson/rapidjson.h> // <- usr/local/include/rapidjson
int main(int argc, char **argv)
{
rapidjson::Document d; // <- uses rapidjson (v0.2) of tiny_dnn/cereal/external/rapidjson but in my project i would use /usr/local/include/rapidjson (v1.0.1)
return 0;
}
In general - don't. Force one client to use higher / better. Even if you walk around those problems, you are likely to violate one definition rule and get segfault later.
I have a simple shared library libfool2.so with installed header fool2.h which are not from a CMake project. My project my_temp1 depends on fool2 so I write a FindFool2.cmake to make an imported target:
find_path(Fool2_INCLUDE_DIR fool2.h PATH_SUFFIXES fool2)
find_library(Fool2_LIB fool2)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Fool2
REQUIRED_VARS Fool2_INCLUDE_DIR Fool2_LIB
)
if(Fool2_FOUND AND NOT TARGET Fool2::Fool2)
add_library(Fool2::Fool2 SHARED IMPORTED)
set_target_properties(Fool2::Fool2 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Fool2_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${Fool2_LIB}"
)
endif()
The CMakeLists.txt for my_temp1 project is:
cmake_minimum_required(VERSION 3.3)
project(my_temp1)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake/cmake_modules)
# FindFool2.cmake is in ${CMAKE_CURRENT_LIST_DIR}/cmake/cmake_modules
find_package(Fool2 REQUIRED)
if (TARGET Fool2::Fool2)
message(STATUS "target found")
endif()
add_executable(my_temp1 main.cpp)
target_link_libraries(my_temp1 Fool2::Fool2)
Now
$ tree ../__install
../__install/
├── include
│ └── fool2
│ ├── fool2.h
│ └── version.h
└── lib
└── libfool2.so
$ tree .
.
├── cmake
│ └── cmake_modules
│ └── FindFool2.cmake
├── CMakeLists.txt
└── main.cpp
$ cmake -H. -B_builds -DCMAKE_INSTALL_PREFIX=../__install
# some output omitted
-- target found
-- Configuring done
-- Generating done
-- Build files have been written to: /OMITTED/my_temp1/_builds
$ cmake --build _builds
CMakeFiles/my_temp1.dir/build.make:82: *** target pattern contains no '%'. Stop.
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/my_temp1.dir/all' failed
make[1]: *** [CMakeFiles/my_temp1.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
$ head -n 85 _builds/CMakeFiles/my_temp1.dir/build.make | tail -n 10
# External object files for target my_temp1
my_temp1_EXTERNAL_OBJECTS =
my_temp1: CMakeFiles/my_temp1.dir/main.cpp.o
my_temp1: CMakeFiles/my_temp1.dir/build.make
my_temp1: Fool2::Fool2-NOTFOUND
my_temp1: CMakeFiles/my_temp1.dir/link.txt
#$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=/OMITTED/my_temp1/_builds/CMakeFiles --progress-num=$(CMAKE_PROGRESS_2) "Linking CXX executable my_temp1"
$(CMAKE_COMMAND) -E cmake_link_script CMakeFiles/my_temp1.dir/link.txt --verbose=$(VERBOSE)
The command $ cmake -H. -B_builds -DCMAKE_INSTALL_PREFIX=../__install finds fool2 because find_* commands searches in the CMAKE_INSTALL_PREFIX as well.
But why is there weird output my_temp1: Fool2::Fool2-NOTFOUND in build.make?
CMake version is 3.11.3
For IMPORTED library target value -NOTFOUND corresponds to absent IMPORTED_LOCATION property, corresponded to the library's path. You need to set that property for correctly work with IMPORTED target.
If you want CMake target to be a placeholder just for link with other libraries, use INTERFACE library target instead: such library target doesn't have library location.