Compare commits

...

10 Commits

11 changed files with 204 additions and 244 deletions

View File

@ -1,13 +0,0 @@
### 该问题是怎么引起的?
### 重现步骤
### 报错信息

View File

@ -1,11 +0,0 @@
### 相关的Issue
### 原因(目的、解决的问题等)
### 描述(做了什么,变更了什么)
### 测试用例(新增、改动、可能影响的功能)

21
LICENSE
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 xfygogo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,16 +0,0 @@
# of_cmake_config
#### Description
This project is used to generate CMakeLists.txt for OpenFOAM project.
#### Installation
0. Activate OpenFOAM environment:
- Using alias `of2012clang` or `of2012clangdebug`
- source directly: `source $HOME/OpenFOAM/OpenFOAM-v2012/etc/bashrc WM_COMPILER=Clang ...`
1. Get this project: `git clone https://gitee.com/xfygogo/of_cmake_config.git of_cmake_config`
2. Install: `cd of_cmake_config && ./install`
#### Instructions
1. Activate OpenFOAM environment
2. In project root path, run `ofCmakeConfig`

View File

@ -1,16 +1,24 @@
# of_cmake_config
[中文](./README.zh_CN.md) | [English](./README.md)
#### 介绍
本项目用于生成OpenFOAM项目的CMakeLists.txt
#### Introduction
This project is used to generate `CMakeLists.txt` for OpenFOAM projects.
#### 安装教程
0. 激活OpenFOAM环境:
- 使用别名 `of2012clang` or `of2012clangdebug`
- 直接source: `source $HOME/OpenFOAM/OpenFOAM-v2012/etc/bashrc WM_COMPILER=Clang ...`
1. 获取该项目源码:`git clone https://gitee.com/xfygogo/of_cmake_config.git of_cmake_config`
2. 安装:`cd of_cmake_config && ./install`
#### Installation Guide
0. Activate the required OpenFOAM environment (otherwise the installation will fail).
1. Obtain the project source code: `git clone https://github.com/zhyang-dev/of_cmake_config.git`
2. Install: `cd of_cmake_config && ./install`
#### 使用说明
#### Usage Instructions
0. 激活OpenFOAM环境
1. 在项目根目录下, 运行 `ofCmakeConfig`
0. Activate the OpenFOAM environment.
1. In the project's root directory:
- Run `ofCmakeConfig` to generate `CMakeLists.txt`.
- Or run `occ`, which will execute `ofCmakeConfig` and call `cmake -B build`, eventually generating `compile_commands.json` in the build directory.
#### Testing Environment
- `vscode` + `clangd`
- `vim` + `coc-clangd`
The following demonstrates the second scenario based on the icoFoam case.
![Video Demo](demo/occ_demo.gif)

24
README.zh_CN.md Normal file
View File

@ -0,0 +1,24 @@
# of_cmake_config
[中文](./README.zh_CN.md) | [English](./README.md)
#### 介绍
本项目用于生成OpenFOAM项目的CMakeLists.txt
#### 安装教程
0. 激活需要的OpenFOAM环境否则会安装失败
1. 获取该项目源码:`git clone https://github.com/zhyang-dev/of_cmake_config.git`
2. 安装:`cd of_cmake_config && ./install`
#### 使用说明
0. 激活OpenFOAM环境
1. 在项目根目录下,
- 运行 `ofCmakeConfig`,可以生成`CMakeLists.txt`
- 或运行`occ`,它会执行`ofCmakeConfig`,并调用`cmake -B build`最终在build中会生成`compile_commands.json`。
#### 测试环境
- `vscode` + `clangd`
- `vim` + `coc-clangd`
以下基于icoFoam算例演示第二种情况。
![视频演示](demo/occ_demo.gif)

BIN
demo/occ_demo.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

View File

@ -3,10 +3,10 @@
objDir=$WM_PROJECT_DIR/wmake
if [ -d $objDir ]
then
cwd=`pwd`
chmod +x ./ofCmakeConfig
rm -f $objDir/ofCmakeConfig
ln -s $cwd/ofCmakeConfig $objDir/
chmod +x ./occ
rm -f $objDir/ofCmakeConfig $objDir/occ
cp ofCmakeConfig occ wmakelog2cmakelists.py $objDir/
echo "installed ofCmakeConfig"
else
echo "please active OpenFOAM environment"

4
occ Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
ofCmakeConfig
rm -r build && mkdir build
cmake -Bbuild -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .

View File

@ -1,177 +1,31 @@
#!/bin/bash
Script="${0##*/}" # Need 'Script' for wmakeFunctions messages
scriptsDir="${0%/*}"/scripts # wmake/scripts directory
. "$scriptsDir"/wmakeFunctions # Source wmake functions
# TODO: 检查当前路径是否是CMAKE_SOURCE_DIR
# 其中包含.vscode, CMakeLists.txt
# ...
# TODO: 根据OF环境变量设置安装目录
printInfo() {
if [ -f "$WM_DIR"/makefiles/info ]
if [ ! -f "log.wmake" ]
then
make --no-print-directory -f "$WM_DIR"/makefiles/info "$@"
echo "wmake > log.wmake"
wmake $@ >log.wmake 2>&1
fi
# Find the Python executable in the system
PYTHON_EXEC=$(which python3)
# Check if python3 is found
if [ -z "$PYTHON_EXEC" ]; then
echo "python3 not found"
exit 1
fi
# Get the Python version
PYTHON_VERSION=$($PYTHON_EXEC -c 'import sys; print(".".join(map(str, sys.version_info[:3])))')
# Split the version number
IFS='.' read -r -a version_parts <<< "$PYTHON_VERSION"
# Compare major and minor versions
if [ "${version_parts[0]}" -gt 3 ] || { [ "${version_parts[0]}" -eq 3 ] && [ "${version_parts[1]}" -ge 6 ]; }; then
script_dir=$(cd "$(dirname "$0")" && pwd)
$PYTHON_EXEC $script_dir/wmakelog2cmakelists.py
else
echo "OpenFOAM environment not set?" 1>&2
return 1
echo "Python version must be greater than 3.6, current version is: $PYTHON_VERSION"
exit 1
fi
}
if [ -z "$objectsDir" ]
then
objectsDir="$MakeDir/$WM_OPTIONS"
fi
mkdir -p "$objectsDir"
make -s -f "$WM_DIR"/makefiles/files MAKE_DIR="$MakeDir" OBJECTS_DIR="$objectsDir" "$objectsDir"/options
make -s -f "$WM_DIR"/makefiles/files MAKE_DIR="$MakeDir" OBJECTS_DIR="$objectsDir"
s=`make --dry-run -f "$WM_DIR"/makefiles/general MAKE_DIR="$MakeDir" OBJECTS_DIR="$objectsDir" $targetType`
if [ $WM_COMPILE_OPTION = "Debug" ]; then
echo $s
fi
link_flags_extra=`echo $s | grep -oP '(?<=Xlinker)(.*?)(?=Make)'`
link_flags_extra="-Xlinker $link_flags_extra"
OF_compile_flags=`printInfo "cxxflags"`
OF_compile_flags="$OF_compile_flags -iquote."
OF_link_flags="$OF_compile_flags $link_flags_extra"
# echo OF_compile_flags: $OF_compile_flags
# echo OF_link_flags: $OF_link_flags
OF_project_name=`cat Make/files | grep EXE | grep -oP '(?<=/).*$'`
# echo OF_testCaseDir: '${CMAKE_SORCE_DIR}/testCase'
OF_sources=`cat Make/files | grep -oP '.*.C'`
# echo OF_sources: $OF_sources
str_inc=`echo $s | sed 's/ /\n/g' | grep -E '^-I' | sort | uniq |grep -oP '(?<=-I).*'`
OF_includeDir_tmp=${str_inc/%lnInclude/}
OF_includeDir=""
for inc in $OF_includeDir_tmp
do
if [ "${inc:0:1}" != "/" ]
then
inc="\${CMAKE_SOURCE_DIR}/$inc"
fi
OF_includeDir="$OF_includeDir $inc"
done
OF_includeDir="$OF_includeDir \${CMAKE_SOURCE_DIR}/lnInclude"
OF_includeDir=`echo $OF_includeDir | sed 's/ /\n/g'`
OF_linkLib=`echo $s | sed 's/ /\n/g' | grep -E '^-l' | sort | uniq |grep -oP '(?<=-l).*'`
OF_linkDir=$WM_PROJECT_DIR/platforms/$WM_OPTIONS/lib
# echo OF_linkLib: $OF_linkLib
# echo OF_linkDir: $OF_linkDir
# 写入文件 .vscode/of-gdb.sh
mkdir -p .vscode
cat > .vscode/of-gdb.sh <<EOF
#!/bin/bash
source $FOAM_ETC/bashrc WM_MPLIB=$WM_MPLIB WM_COMPILE_OPTION=$WM_COMPILE_OPTION WM_COMPILER=$WM_COMPILER
/usr/bin/gdb "\$@"
EOF
# 写入文件 .vscode/launch.json
cat > .vscode/launch.json << EOF
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
// Resolved by CMake Tools:
"program": "\${command:cmake.launchTargetPath}",
"args": [],
"stopAtEntry": true,
"cwd": "\${workspaceFolder}/testCase",
"environment": [
{
// add the directory where our target was built to the PATHs
// it gets resolved by CMake Tools:
"name": "PATH",
"value": "\${env:PATH}:\${command:cmake.getLaunchTargetDirectory}"
},
{
"name": "OTHER_VALUE",
"value": "Something something"
}
],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "\${workspaceFolder}/.vscode/of-gdb.sh",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}
EOF
chmod +x .vscode/of-gdb.sh
# 写入文件 CMakeLists.txt
cat > CMakeLists.txt <<EOF
cmake_minimum_required(VERSION 3.12)
#=== OF related variables ===
set(project_name $OF_project_name)
set(WM_COMPILE_OPTION $WM_COMPILE_OPTION)
set(OF_compile_flags "$OF_compile_flags")
set(OF_link_flags "$OF_link_flags")
set(OF_testCaseDir \${CMAKE_SOURCE_DIR}/testCase)
set(OF_sources
$OF_sources
)
set(OF_includeDir
$OF_includeDir
)
set(OF_linkLib
$OF_linkLib
)
set(OF_linkDir
$OF_linkDir
)
#=== End ===
project(\${project_name} LANGUAGES CXX C)
set(ENV{LD_LIBRARY_PATH} "\$ENV{LD_LIBRARY_PATH}:\${OF_linkDir}")
if(\${WM_COMPILE_OPTION} STREQUAL "Opt")
set(CMAKE_BUILD_TYPE Release CACHE STRING "Release mode" FORCE)
endif()
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED)
link_directories(
\${OF_linkDir}
)
include_directories(
\${OF_includeDir}
\${CMAKE_SOURCE_DIR}/lnInclude
\${CMAKE_SOURCE_DIR}
)
add_executable(\${project_name}
\${OF_sources}
)
target_link_libraries(
\${project_name}
PRIVATE
\${OF_linkLib}
)
set_target_properties( \${project_name} PROPERTIES
COMPILE_FLAGS \${OF_compile_flags}
LINK_FLAGS \${OF_link_flags}
WORKING_DIRECTORY \${OF_testCaseDir})
EOF

131
wmakelog2cmakelists.py Normal file
View File

@ -0,0 +1,131 @@
import re
def remove_duplicates(seq):
"""
Remove duplicates from the seq list and maintain the original order
"""
seen = set()
return [x for x in seq if not (x in seen or seen.add(x))]
def preprocess_lines(lines):
"""
Merge multiple lines with newline characters
"""
merged_lines = []
current_line = ""
for line in lines:
stripped_line = line.strip()
if stripped_line.endswith('\\'):
current_line += stripped_line[:-1].strip() + ' '
else:
current_line += stripped_line
merged_lines.append(current_line)
current_line = ""
return merged_lines
def parse_wmake_log(log_file):
"""
There may be multiple compilation targets; distinguish between compilation and linking.
"""
with open(log_file, 'r') as file:
lines = file.readlines()
# Preprocess line merging
lines = preprocess_lines(lines)
# Initialize data storage
source_files = set()
compile_options = []
link_options = []
link_libraries = []
link_directories = set()
include_directories = set()
compile_definitions = set()
output_file = ""
cxx_standard = ""
for line in lines:
if 'g++' in line:
# Check for C++ standard settings
cxx_match = re.search(r'-std=c\+\+(\d+)', line)
if cxx_match:
cxx_standard = cxx_match.group(1)
# Determine if it's a compile or link statement
if '-Xlinker' in line or '-Wl,' in line:
# Link statement
# Handle -fuse-ld
useld = re.search(r'(-fuse-ld=\S+)', line)
if useld:
link_options.append(f'{useld.group(1)}')
# Handle output file
output_file = re.search(r'-o\s+(\S+)', line).group(1)
# Handle libraries
lib_matches = re.findall(r'-l(\S+)', line)
for lib in lib_matches:
if lib not in link_libraries:
link_libraries.append(lib)
link_directories.update(re.findall(r'-L(\S+)', line))
options = re.findall(r'( -\S+)', line)
# Handle -Xlinker options
xlinker_options = re.findall(r'-Xlinker\s+(\S+)', line)
link_options.append(f'-Wl,{",".join(xlinker_options)}')
else:
# Compile statement
source_files.update(re.findall(r'-c\s+(\S+)\s+-o', line))
include_directories.update(re.findall(r'-I(\S+)', line))
compile_definitions.update(re.findall(r'-D(\S+)', line))
options = re.findall(r'(-\S+)', line)
exclude_prefixes = ('-I', '-D', '-o', '-c', '-std=c++')
compile_options.extend(opt for opt in options if not any(
opt.startswith(prefix) for prefix in exclude_prefixes))
# Handle specific include directories
include_directories = {f"${{CMAKE_SOURCE_DIR}}/{dir}" if dir ==
'lnInclude' else dir for dir in include_directories}
include_directories.add("${CMAKE_SOURCE_DIR}")
objfile_split = output_file.split('/')[-1].split('.')
objname = objfile_split[0]
objstr = ''
if len(objfile_split) == 1:
objstr = f'add_executable({objname} {" ".join(source_files)})'
elif objfile_split[1] == 'so':
objstr = f'add_library({objname} SHARED {" ".join(source_files)})'
elif objfile_split[1] == 'a':
objstr = f'add_library({objname} STATIC {" ".join(source_files)})'
# Handle the issue of link and target having the same name
link_libraries = [lib if lib != objname else f'lib{lib}.so'
for lib in link_libraries]
# Create CMakeLists.txt content
cmake_content = f"""cmake_minimum_required(VERSION 3.10)
project({output_file.split('/')[-1].split('.')[0]})
set(CMAKE_CXX_COMPILER g++)
set(CMAKE_CXX_STANDARD {cxx_standard})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
{objstr}
target_include_directories({objname} PRIVATE {" ".join(include_directories)})
target_compile_definitions({objname} PRIVATE {" ".join(compile_definitions)})
target_compile_options({objname} PRIVATE {" ".join(remove_duplicates(compile_options))})
target_link_directories({objname} PRIVATE {" ".join(remove_duplicates(link_directories))})
target_link_libraries({objname} {" ".join(remove_duplicates(link_libraries))})
target_link_options({objname} PRIVATE {" ".join(link_options)})
"""
return cmake_content
def write_cmake_file(content, output_filename="CMakeLists.txt"):
with open(output_filename, 'w') as file:
file.write(content)
if __name__=="__main__":
# Use functions to parse the log and write CMakeLists.txt
cmake_content = parse_wmake_log("log.wmake")
write_cmake_file(cmake_content)
print("CMakeLists.txt has been generated successfully.")