I am using CMake to build a project with external libraries by using "Eclipse CDT4 - Unix Makefiles".
Importing in Eclipse leads to a working project, but only all header files and my implemented source files are recognized correctly by the index of Eclipse.
I would also like to navigate through the source files for one external library by using "ctrl+click". I don't know how to add the *.cpp files of that external library in my CMakeList.txt to get them recognized by the indexer without building the library.
You can mark the .cpp files as "header file only" like this:
# find all filenames in the lib path and gather them in $YOUR_LIB
FILE(GLOB YOUR_LIB path_to_library/*.?pp)
# create a seperate sourcegroup so it doesn't clutter up the rest of your code
SOURCE_GROUP(\\lib FILES ${YOUR_LIB})
# mark them as header-file only
SET_SOURCE_FILES_PROPERTIES(${YOUR_LIB} PROPERTIES HEADER_FILE_ONLY TRUE)
# add both your code and the lib-code to the project
ADD_EXECUTABLE(program ${YOUR_CODE} ${YOUR_LIB})
I found a way to attach external library source files to the Eclipse project that is compatible with CMake project generator.
It turns out that to indexing and "ctrl+click" navigation works correctly only when external library sources are direct descendants of the project source folder. Therefore the solution is following:
Scan external library folder for source files.
Create a child folder under project's source folder.
Symlink discovered sources inside the created folder.
I created a CMake function attachExternalSources that performs above steps:
function(attachExternalSources librarySourceLocation folderName)
# Create folder for Geant4 sources
file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/${folderName})
message(STATUS "Searching for C++ sources in \"${librarySourceLocation}\"...")
FILE(GLOB_RECURSE libSources
${librarySourceLocation}/*.c
${librarySourceLocation}/*.cpp
${librarySourceLocation}/*.cxx
${librarySourceLocation}/*.cc
)
message(STATUS "Symlinking sources into\n \"${CMAKE_SOURCE_DIR}/${folderName}\"\n Please wait...")
foreach(source ${libSources})
# Obtain source filename
get_filename_component(source_filename ${source} NAME)
# Create symlink unless it already exists
set(symlink "${CMAKE_SOURCE_DIR}/${folderName}/${source_filename}")
if(NOT EXISTS ${symlink})
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${source} ${symlink})
endif()
endforeach()
# Scan all the symlinks created under the project folder and disable their compilation
FILE(GLOB sources_symlinks ${CMAKE_SOURCE_DIR}/${folderName}/*)
SET_SOURCE_FILES_PROPERTIES(${sources_symlinks} PROPERTIES HEADER_FILE_ONLY TRUE)
endfunction()
The use of the function is following. Paste above function code in your CMakeLists.txt. Next, use it as follows:
attachExternalSources("path/to/external/library/sources" "library-sources")
First parameter is location of the external library source code. Second argument is the name of a folder inside your project that that will contain source symlinks.
P.S. I tested function with Eclipse 4.19 and CMake 3.20.5.
Related
I am building a flutter plugin which calls native functions from lib.dll file and everything works as expected in my computer.
But I use relative path to link that lib such as
E:/_Projects/mahesabu/client/packages/server/windows/lib.dll
Now I want to move the build process in CI/CD which I believe using relative path such as
./lib.dll would be very easy.
Of cource I am new to cmake configuration. And in one comment it is written
List of absolute paths to libraries that should be bundled with the plugin
I wonder how can I use relative path there, because if I try build fails. The following is CMakeLists.txt
cmake_minimum_required(VERSION 3.14)
set(PROJECT_NAME "server")
project(${PROJECT_NAME} LANGUAGES CXX)
# This value is used when generating builds using this plugin, so it must
# not be changed
set(PLUGIN_NAME "server_plugin")
add_library(${PLUGIN_NAME} SHARED
"server_plugin.cpp"
)
apply_standard_settings(${PLUGIN_NAME})
set_target_properties(${PLUGIN_NAME} PROPERTIES
CXX_VISIBILITY_PRESET hidden)
target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
target_include_directories(${PLUGIN_NAME} INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin)
# List of absolute paths to libraries that should be bundled with the plugin
set(server_bundled_libraries
""
"E:/_Projects/mahesabu/client/packages/server/windows/lib.dll" #USE RELATIVE PATH HERE
PARENT_SCOPE
)
Any help will be appreciated.
Just use:
set(server_bundled_libraries "${CMAKE_CURRENT_SOURCE_DIR}/lib.dll" PARENT_SCOPE)
The CMAKE_CURRENT_SOURCE_DIR variable will expand to current source directory as tracked by add_subdirectory. This is usually, but not always, the directory in which the present CMakeLists.txt resides. Presumably, this is E:/_Projects/mahesabu/client/packages/server/windows on your computer (given your remark that you expect ./lib.dll to work), but will be somewhere else on CI or elsewhere.
I'm currently working on an embedded C project in Eclipse, cross-compiling to an M4 Cortex target. This project will create 3 separate executable files: apple.hex, orange.hex, and pear.hex. The "apple" source directory compiles, builds, and links without any dependencies on "orange" or "pear". The "orange" source directory also compiles, builds, and links without any dependencies.
However, "pear" needs to access numerous .h and .c assets from "orange". I've had many attempts at getting my CMakeLists.txt to "find" and "link" the code from "orange" to "pear", but to no avail.
Here is my current CMakeLists.txt file:
cmake_minimum_required(VERSION 3.0)
file(GLOB LD_FILE *gcc_nrf52.ld)
set(MY_APP_DIR ${CMAKE_SOURCE_DIR}/apps/orange)
create_application(
NAME
"pear"
PLATFORM
target
INCLUDE_DIRS
./
${MY_APP_DIR}
LINKER_SCRIPT
${LD_FILE}
SOURCES
${MY_APP_DIR}/foo.c
${MY_APP_DIR}/foo_bar.c
main.c
LIBRARIES
SomeLib_1
SomeLib_2
SomeLib_3
)
However, the compiler keeps complaining, saying that it cannot find "foo.h" and "foo_bar.h".
1) Do I need to separately create a static library in orange in order to access it in pear?
2) If I don't need to create a static library to access orange from pear, how do I link orange to pear?
3) I cannot find where CMake places the object files. Where are they?
This project is all under a single makefile.
Any help would be greatly appreciated, thanks!
I was able to fix my directory issues so that all of the include directories in ${MY_APP_DIR} are being linked into "Pear". However, a new issues has arisen. The linker cannot find the map file needed to create the executable image:
/usr/local/Caskroom/gcc-arm-embedded/5_4-2016q3,20160926/gcc-arm-none-eabi-5_4-2016q3/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld: cannot open map file /Users/admin/Github/target/apps/pear/pear.map: No such file or directory.
I'm not sure why a map find isn't being created. Is the linker (ld) still missing files?
I'll try to answer your questions
You are not linking your libraries to your target.
You need something like:
$target_link_libraries(yourtarget yourlibraries)
after your add_executable command.
3) I cannot find where CMake places the object files. Where are they?
CMake puts all of its outputs in the build tree by default, so unless you are liberally using ${CMAKE_SOURCE_DIR} or ${CMAKE_CURRENT_SOURCE_DIR} in your cmake files, you should find the output files in the folder where your CMakeLists.txt file is.
I have some ast parser code in eclipse but I am unable to import the
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
packages.
could some body tell me which jar file to download and where to add same that jar file in eclipse folder.
You probably have those files downloaded already in eclipse\plugins folder i.e. in windows C:\Program Files\eclipse\plugins\org.eclipse.jdt.core_3.9.1.v20130905-0837.jar
Of course you can download from internet as well
http://central.maven.org/maven2/org/eclipse/tycho/org.eclipse.jdt.core/
Note that in order to run it as a stand alone application you will have to import such librariers (where xx stands for version and again they can be found in eclipse\plugins folder):
org.eclipse.core.contenttype_xx.jar
org.eclipse.core.jobs_xx.jar
org.eclipse.core.resources_xx.jar
org.eclipse.core.runtime_xx.jar
org.eclipse.equinox.common_xx.jar
org.eclipse.equinox.preferences_xx.jar
org.eclipse.jdt.core_xx.jar
org.eclipse.osgi_xx.jar
Usually people add other libraries in folder called lib but still you will have to set it in eclipse. In order to do that right click on your project then build path -> configure build path -> libraries and select add JAR.
I recently decided to use SBT to build an existing project.
In this project I have some .glsl files within the scala packages which I need to copy during the compilation phase.
The project is structured like this :
- myapp.opengl
- Shader.scala
- myapp.opengl.shaders
- vertex_shader.glsl
- fragment_shader.glsl
Is this file structure correct for SBT or do I need to put the .glsl files into an other directory. And do you know a clean way to copy these files into the target folder ?
I would prefer not putting these files into the resources directory since they are (non-compiled) sources files
Thanks
I would not recommend putting those files into src/main/scala as they do not belong there. If you want to keep them separate from your resource files, you can put them in a custom path, e.g. src/main/glsl and add the following lines to your project definition to have them copied into output directory:
val shaderSourcePath = "src"/"main"/"glsl"
// use shaderSourcePath as root path, so directory structure is
// correctly preserved (relative to the source path)
def shaderSources = (shaderSourcePath ##) ** "*.glsl"
override def mainResources = super.mainResources +++ shaderSources
I have different behaviour of compiler, when building project from IDE and from command-line, which I can not explain.
The detailed issue's description is rather big, but it's really simple.
I have a C++ Builder project, which has a PAS-file included (IncludeUnits.pas). This pas-file has several units and inc-files listed. These files are located in separate folders and these folders are listed in library&include paths in project's options.
Folders layout:
C:\Demo\Bin
C:\Demo\Project
C:\Demo\Project\CBuilder5
C:\Demo\Project\Common
C:\Demo\Source
C:\Demo\Source\Common
Bin is output folder, Project/CBuilder5 holds project (bpr-file), Project/Common holds included pas-file (IncludeUnits.pas), Source and Source/Common hold other files (pas&inc). I think that it's pretty usual layout.
C:\Demo\Project\Common\ IncludeUnits.pas :
unit IncludeUnits;
interface
uses
Test;
implementation
end.
C:\Demo\Source\ Test.pas :
unit Test;
interface
{$I Test.inc}
implementation
end.
C:\Demo\Source\Common\ Test.inc :
// this file is empty
If I compile this project from C++ Builder IDE - it will compile fine. C++ Builder IDE doesn't have any additional paths in IDE settings set.
Now, I want to compile it from command-line. First, I issue
bpr2mak.exe MyProject.bpr
command.
This command creates MyProject.mak file, where I can see all paths ("....\Source" and "....\Source\Common" are the paths in question):
...
INCLUDEPATH = $(BCB)\include;$(BCB)\include\vcl;..\Common;..\..\Source;..\..\Source\Common
LIBPATH = $(BCB)\lib\obj;$(BCB)\lib;..\Common;..\..\Source;..\..\Source\Common
...
Now, I run make command:
make.exe -B -f"MyProject.mak"
It gives me the following output:
C:\PROGRA~1\Borland\CBUILD~2\BIN\dcc32 -N2....\Bin -N0....\Bin -$Y+ -$W -$R -v -JPHNE -M -UC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common -D_DEBUG;_RTLDLL;NO_STRICT -OC:\PROGRA~1\Borland\CBUILD~2\bin..\include;C:\PROGRA~1\Borland\CBUILD~2\bin..\include\vcl;..\Common;..\..\Source;..\..\Source\Common --BCB ..\Common\IncludeUnits.PAS
Borland Delphi Version 13.0 Copyright (c) 1983,99 Inprise Corporation
C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(1) C:\Demo\Project\Common\IncludeUnits.pas(6) C:\Demo\Source\Test.pas(1) C:\Demo\Source\Test.pas(5) Fatal: File not found: 'Test.inc'
As you can see - all search path is passed to compiler and the file (Test.inc) is all here - in that Source\Common folder. But still compiler can't find it?
Of course, I run both commands from folder with bpr-file. And changing paths to absolute doesn't help.
Copying Test.inc from Source\Common to Source will help. Changing {$I Test.inc} to {$I Common\Test.inc} will also help.
Why? It seems that I'm missing something. Remember: project have no problems with compiling from IDE, Test.inc is found without copying or changing declaration. Did I miss some switch to make or dcc32?
I found the reason: command line for dcc32 misses -I switch, which specifies paths for include files.
For some reason, bpr2mak doesn't respect this option. Fortunately, it allows you to specify alternate template for conversion bpr -> mak. I edited default template and added "-I" option to it, pass new template to bpr2mak - and it worked.